Skip to main content

Reporting, Dashboards & Exports (RPT)

Module code RPT · Release R1 (standard reports, dashboards, export), R2 (schedules, saved views), R4 (custom report builder, analytics warehouse) · Packaging Core (advanced analytics on Professional+) · Requirements FR-RPT-*, BR-RPT-* in the PRD and BRD

1. Overview and scope​

RPT is a framework, not a pile of reports. A report is a dataset definition (columns, joins through module read models, filters, default sort) evaluated under the viewer's permission scope. "The manager's attendance report" and "the HR attendance report" are the same dataset with a different scope. The framework also renders dashboards (KPI tiles and charts) and runs exports and schedules asynchronously.

In scope: dataset registry (code-defined per module); standard filter idiom (location, department, manager, employee, period); column chooser; saved views; Excel, CSV and PDF export through background jobs; scheduled email delivery; persona dashboards (owner, HR, manager, employee, finance, sales); drill-down from tile to rows; masking of sensitive columns; export audit.

R4: custom report builder over a semantic layer, trend analytics (attrition, absenteeism, OT cost, payroll cost), a columnar replica for heavy queries.

Out of scope: statutory files (PAY generates them), operational lists inside module screens (they use the same datasets but are not "reports").

2. Learned from the reference product​

Source: Spryple analysis, §3.3, §14 and §21.

  • [Observed] Almost every report offers Excel and PDF export (SP-X-05).
  • [Observed] A shared filter idiom: City-Branch → Manager → Employee → Period, with Search and Clear (SP-X-06).
  • [Observed] The Super Admin dashboard shows employees by location and department, headcount (active, new, exit), attendance by work type, employees on leave, shift-based headcount and payroll amount by department by month (SA: Dashboard).
  • [Observed] The employee report has a column chooser (SP-RPT-01).
  • [Inferred] Reports are re-implemented per role and module, with no saved filters, schedules, drill-down or trends (§14).

3. Our design decisions​

IDDecision [Proposed]Reason
D-RPT-01A dataset is defined once in code (packages/contracts plus a module read query) and registered with RPT; scope is applied by the framework using the IAM guard.One implementation per report; consistent security.
D-RPT-02Exports always run as jobs, with a row-limited synchronous preview; files are stored behind a short-lived presigned URL.Month-end export spikes must not hurt the API.
D-RPT-03Sensitive columns (salary, bank, PAN, Aadhaar) are excluded unless the viewer has the field permission; every export is audited.DPDP and insider-risk controls.
D-RPT-04Dashboards are composed from widget definitions bound to datasets with an aggregation; per-persona defaults that the tenant can rearrange.Persona KPIs without bespoke screens.
D-RPT-05Reports read from module read models or a read replica, never from module tables directly.Respects module boundaries; protects the primary.

4. Domain model​

rpt_dataset is code-defined reference data (no tenant_id).

5. State machines​

5.1 Export job​

6. Key business logic​

runReport(viewer, dataset, params):
require can(viewer, dataset.required_permission, any scope)
scope = widest scope the viewer holds for that permission
rows = dataset.query(params, scopeFilter(viewer, scope)) # employee ids in scope
cols = dataset.columns minus sensitive columns the viewer lacks permission for
if params.preview: return first 500 rows
enqueue export job ; audit (viewer, dataset, filters, row_count)

Period semantics: every dataset declares whether "period" means the pay period (from PAY schedules), the attendance window or the calendar month, so the same filter means the same thing across reports.

KPI definitions are fixed in code so every dashboard agrees:

KPIDefinition
HeadcountEmployees with a job assignment valid on the date and status not Separated
Attrition rate (monthly)Separations in month / average of opening and closing headcount
Absenteeism rateUnplanned absent and LOP days / scheduled working days
Late rateDays with is_late / present days
OT costSum of OT component amounts in locked runs
Payroll costGross plus employer contributions in locked runs
Approval turnaroundMedian hours from submission to final decision

7. Configuration​

SettingTypeDefaultDescription
export.max_rowsinteger200000Hard limit per export
export.link_ttl_hoursinteger24Presigned URL lifetime
export.pdf_max_rowsinteger5000Larger exports must use Excel or CSV
schedule.max_per_tenantinteger50Plan-dependent
dashboard.refresh_minutesinteger15Widget cache
masking.defaultbooleantrueMask sensitive columns unless permitted

8. Screens by persona​

PersonaDashboard tiles (defaults)Report access
org_ownerHeadcount by location and department, joiners and exits, attendance by work type, on leave today, payroll cost by department by monthAll datasets at ORG
hr_managerToday's attendance, pending approvals, probation due, overdue onboarding tasks, leave trendHR datasets at scope
line_managerTeam present, absent and late today, pending approvals, team leave calendarTeam datasets
employeeThis month's attendance, leave balances, last payslipOwn data
payroll_managerRun status, variance, statutory totals, advance balancesPayroll datasets
sales_managerTeam on field, visits, km, pipeline by stage (R3)FFM datasets

Mobile shows the same tiles for the employee and manager personas (see Mobile).

9. Events​

EventConsumers
rpt.export.readyNTF (in-app link)
rpt.export.failedNTF
rpt.schedule.deliveredAudit

Consumed: none for computation (reads are pull-based). Cache invalidation listens to att.period.locked and pay.run.locked.

10. API surface​

ResourceMain operations
/v1/rpt/datasetsGET catalogue visible to the viewer
/v1/rpt/datasets/:key/queryPOST preview with filters
/v1/rpt/exportsPOST, GET /:id
/v1/rpt/viewsCRUD saved views
/v1/rpt/schedulesCRUD
/v1/rpt/dashboardsGET by persona, PUT layout

Detailed in API endpoints.

11. Permissions​

Module report permissions (att.report.export, pay.report.export and so on) gate datasets. RPT adds:

PermissionScopesDefault roles
rpt.view.shareORGhr_manager, org_owner
rpt.schedule.manageSELF, ORGmanagers and admins
rpt.dashboard.manageORGorg_owner, hr_admin
rpt.builder.use (R4)ORGhr_admin, finance_admin

12. Reports​

The catalogue of standard datasets lives with each module (see the Reports section of each spec). RPT itself provides the export audit log and the schedule delivery log.

13. Release and priority​

CapabilityReleaseMoSCoW
Dataset framework, scope filters, column chooser, Excel/CSV/PDF exportR1Must
Persona dashboards with drill-downR1Must
Saved views and schedulesR2Should
Read replica for reportsR2Should
Custom report builder and semantic layerR4Could
Trend analytics (attrition, absenteeism, OT cost)R4Should

14. Open questions​

  1. Should employees export their own data in machine-readable form through RPT as part of DPDP access requests? The default is a separate IAM/EMP data-access flow.
  2. Which charting library meets accessibility requirements in light and dark themes? To be decided with design.
  3. When do we add the columnar warehouse (CDC to ClickHouse or Redshift)? The architecture trigger is the 300-tenant scale stage.