PRD 14 — Reports & Insights
Status: draft · Priority tier: P1 · Size: L · Depends on: PRD 01, sales/transactions, bookings/attendance, customers, pricing plans, staff (PRD 13 for marketing/referral data)
1. Summary
A report hub with 31 reports in 9 groups (filters, columns, CSV export, per-user favourites), dashboard KPIs, customer-feedback tools (service/staff ratings, contact form inbox and subjects) and payroll settings with commission rules. Gives owners the numbers to run the studio and pay staff.
2. Problem & goals
- Owners need sales, attendance, customer and staff numbers without spreadsheets.
- Goals: any report reachable in <=3 clicks (rail/search -> report -> export); default view loads <3 s for 12 months of data; every report exports CSV matching on-screen filters; payroll run reproducible from commission rules.
- Non-goals: AI Business Insights (not opened in recon; Out), custom report builder, scheduled report emails (Later), BI integrations.
3. Users & roles
Owner (all), manager (all except payroll: assumption), front desk (dashboard KPIs, own-location attendance), staff (own payroll/ratings only: assumption), customer (submits ratings and contact form).
4. Scope
In (v1): hub, favourites, search (must); sales over time, finance, booking/class/attendance reports (must/should); CSV export on all (must); dashboard KPIs (should); ratings and contact form (should); pricing plan and customer reports (should); payroll settings + payroll report (could). Later: scheduled emailed reports, XLSX/PDF, saved filter presets, customer-facing review moderation. Out: AI insights (not observed); ClassPass revenue column (third-party partner; revisit).
5. User stories
- US-14-01 As an owner, I want a catalogue of reports grouped by topic so that I find the right one fast.
- US-14-02 As an owner, I want to star favourites so that my common reports are one click away.
- US-14-03 As an owner, I want to filter by period/location and export CSV so that I can share with my accountant.
- US-14-04 As an owner, I want sales over time by type so that I see what earns money.
- US-14-05 As an owner, I want dashboard KPIs so that I see health at a glance.
- US-14-06 As an owner, I want service and staff ratings so that I improve quality.
- US-14-07 As an owner, I want to read contact form submissions and manage subjects so that no enquiry is lost.
- US-14-08 As an owner, I want commission rules and a payroll report so that I pay instructors correctly.
- US-14-09 As a customer, I want to rate a class/instructor after attending so that feedback is heard.
6. Functional requirements
| ID | requirement | priority | evidence |
|---|---|---|---|
| FR-14-01 | Hub lists all reports as cards (name, description, favourite star); left rail by group with counts, plus Favourites and All; search by name | must | S75 |
| FR-14-02 | Favourite toggle stored per user; Favourites view | must | S75 |
| FR-14-03 | Generic report page: breadcrumb, title, filters, optional chart, sortable table, per-page (20/50/100), "showing x-y of z" pager, empty state "no data for filter" | must | S76 |
| FR-14-04 | Export CSV on every report, honours current filters and chosen columns, all rows (not only page) | must | S76, F32 |
| FR-14-05 | Date control: presets (today, yesterday, last 7/30/90 days, last month, last year, till date, exact date, custom range) | must | S71 |
| FR-14-06 | Column chooser on finance, booking and pricing-plan reports | should | S76 |
| FR-14-07 | Sales group (3): Sales over Time, Attendance with Revenue, Sales by Pricing Plan — see 9a | must | S75, S76 |
| FR-14-08 | Sales over Time: hourly/daily grain, location, recognised vs deferred, type filter; stacked chart by type; table gross, discount, net, tax, total | must | S76 |
| FR-14-09 | Finance group (6): Daily, Successful, Overdue, Voided, Refunded, Unpaid transactions/invoices | should | raw_rep03-08 |
| FR-14-10 | Class (1) and Appointment (4: paid, unpaid, cancellation, no show) reports | should | rep09-13 |
| FR-14-11 | Course group (4) if courses PRD ships; Outlet Access (1) with access PRD | could | rep14-18 |
| FR-14-12 | Customers group (5): Profile, Activities, Marketing consent, Booking Insights, Referral | should | rep19-23 |
| FR-14-13 | Booking Insights: tabs by customer / by service type; month range + quick ranges (3/6/12/15/18 m); KPI tiles sessions attended, cancellations, late cancellations, no shows | should | raw_rep22 |
| FR-14-14 | Staff group (4): Payroll (settings), Payroll Report, Attendance Insights, Pricing Plan Sales Insights | could | rep24-27 |
| FR-14-15 | Pricing Plan group (3): Packages, Memberships, Pricing Plan Expiration | should | rep28-30 |
| FR-14-16 | Report totals and tax follow the same rules as the sales ledger; reports read-only | must | rule |
| FR-14-17 | Dashboard KPIs (our design; original shows none): today bookings, revenue 7/30 days, new customers, active memberships, no-show rate, with period selector and link to the report | should | S01 gap, guess |
| FR-14-18 | Service Ratings and Staff Ratings lists: score, comment, customer, service/staff, date; filter and average score; staff rating also on staff profile | should | S91, S92, S146 |
| FR-14-19 | Customers submit a rating after attended session (1-5 + optional comment), once per booking | should | assumption |
| FR-14-20 | Contact form submissions inbox: subject, sender, message, date; read/unread | could | S93 |
| FR-14-21 | Contact subjects CRUD; defaults "General" and "Other" created automatically; delete keeps old submissions | could | S94 |
| FR-14-22 | Each submission also emails the staff recipients configured in notifications | could | S156 events |
| FR-14-23 | Payroll settings: payroll frequency (monthly default, Manage) | could | raw_rep24 |
| FR-14-24 | Commission rules per item kind (classes first; appointments, plan sales later) with Active/Inactive status; rule types: percentage of revenue or fixed per session/attendee (structure not observed) | could | rep24 |
| FR-14-25 | Recurring miscellaneous items (bonus, deduction types) assignable to staff, auto-included in payroll report | could | rep24 |
| FR-14-26 | Payroll report: choose period, run payroll to compute per staff sessions, commission, misc items, total; close/confirm locks the period; export | could | rep25 |
| FR-14-27 | Permissions applied per report (e.g. payroll owner only) | must | rule |
7. Screens
Reports hub (S75), report detail (S76, with variants), Booking Insights (tabs/KPIs), Payroll settings + Payroll report, Dashboard KPI strip (S01 extension), Customer feedback hub (S90), ratings (S91/S92), submissions (S93), subjects (S94). States: empty, loading skeleton, filled, error with retry.
8. Flows
- F32: hub -> report -> filter -> Export CSV (3 clicks).
- F38: hub -> ratings / submissions; subjects add/edit/delete.
- Payroll: set frequency + commission -> Payroll Report -> Run -> review -> confirm.
- Edge: >100k rows export runs async with download link (assumption).
9. Data model
Mostly derived from other modules' tables (transactions, bookings, attendance, plans, customers, access logs). New: ReportFavourite(user_id, report_key); Rating(id, kind service|staff, target_id, booking_id, customer_id, score, comment, created_at) (guess); ContactSubject(id, name, updated_at); ContactSubmission(id, subject_id, name, email, message, read, created_at) (guess); PayrollSettings(frequency, ...); CommissionRule(id, item_kind, type, value, active) (guess); MiscType(id, name, sign); StaffMiscItem(staff_id, type_id, amount, recurring); PayrollRun(id, period, status open|confirmed, lines json). Report catalogue is static code config: key, group, name, description, columns, filters.
9a. The 31 reports
| group | report | filters / notable columns |
|---|---|---|
| Sales | Sales over Time | period, hourly/daily, location, recognised/deferred, type; qty per type, gross, discount, net, tax, total |
| Sales | Attendance with Revenue | service, location, facility, staff, payment, sold at |
| Sales | Sales by Pricing Plan | pricing plan |
| Finance | Daily transactions | status, payment method, item type, location, sold by, channel; column chooser |
| Finance | Successful transactions | as above + issue date |
| Finance | Overdue invoices | due date, amount |
| Finance | Voided transactions | amount, item type, payment method, staff |
| Finance | Refunded transactions | amount, refunded by, refund method |
| Finance | Unpaid invoices | due date, net amount, type, channel |
| Class | Class Attendance | staff, location, class |
| Appointment | Paid Bookings | appointment, facility, equipment, staff, status, payment |
| Appointment | Unpaid Bookings | same family |
| Appointment | Cancellation | same family |
| Appointment | No Show | same family |
| Course | Sales by Courses | category, status |
| Course | Sales by Ticket Type | ticket type |
| Course | Attendee Summary | course attendees and attendance |
| Course | Attendance by Course | category, course status, ticket type, payment status |
| Outlet Access | Outlet Access Report | last 30 days, location, status |
| Customers | Profile | channel, group, lifecycle, status |
| Customers | Activities | last 90 days |
| Customers | Marketing consent | channels, consent updated at, email, mobile, name |
| Customers | Booking Insights | tabs, month range, service type, KPIs |
| Customers | Referral | completed, referee rewarded, manually added |
| Staff | Payroll | settings page |
| Staff | Payroll Report | per period, run payroll |
| Staff | Attendance Insights | date, staff; all attendances |
| Staff | Pricing Plan Sales Insights | date, staff; all plan sales |
| Pricing Plan | Packages | package, status, columns |
| Pricing Plan | Memberships | membership, status |
| Pricing Plan | Pricing Plan Expiration | weeks to expire, credits remaining, expired, plan, pricing group |
| Marketing group: original has none; marketing numbers live in campaign list (PRD 13) and Marketing consent/Referral reports. A "Campaign performance" report is a could-have. |
10. Business rules & edge cases
- Recognised vs deferred revenue: prepaid plan revenue recognised on use/expiry (rule to confirm with finance); gross - discount = net; tax separate.
- Times in business timezone; multi-location filter defaults to all.
- Reports for modules not shipped (courses, access) are hidden, not empty.
- Rating shown only for customers who attended; one per booking; hidden customer names option TBD.
- Payroll period locked once confirmed; later edits create adjustments.
- CSV: UTF-8, no formula injection (prefix =,+,-,@ cells).
11. Permissions
Owner: all. Manager: all except payroll and refunds detail (assumption). Front desk: dashboard, attendance. Staff: own ratings and payroll. Favourites per user.
12. Acceptance criteria
- Given 31 catalogue entries, when I search "refund", then only Refunded transactions shows.
- Given I star a report, when I reload, then it appears in Favourites for me only.
- Given filter last 30 days + location A, when I Export CSV, then file rows equal the table total and respect filters.
- Given Sales over Time hourly, then totals per row equal gross - discount + tax reconciliation to the ledger.
- Given no data, then an empty state explains and Export is disabled or yields header-only file.
- Given a customer already rated a booking, when they rate again, then it is rejected.
- Given contact subjects deleted, then old submissions still display their subject name.
- Given a confirmed payroll period, when I run it again, then I am blocked from altering it.
13. Dependencies & open questions
Depends on data from sales, bookings, plans, customers, access, courses PRDs and staff PRD. Open (not observed; every report was empty): real column lists for most reports; charts beyond Sales over Time; Favourites view; AI Business Insights (Out); commission rule form fields; payroll run output; rating record fields and moderation; whether dashboard KPIs exist in original (none seen); refund/void UI; ClassPass scope.
14. Evidence
See evidence/evidence.md.
