Documentation Conventions & Canonical Decisions
This file is the single source of truth for names, codes, IDs and baseline decisions used across every Spyrl document: summary.md, brd.md, prd.md, project-plan.md, architecture.md, review.md, the research and the Docusaurus site in website/. If a document disagrees with this file, this file wins. Fix the document, or change this file through a decision-log entry.
1. Naming
| Term | Meaning |
|---|---|
| Spyrl | Working name of our product: a multi-tenant HCM + Field-Force CRM SaaS for Indian SMEs. Rename later with a global find/replace. |
| Spryple | The reference product we researched (help.spryple.com). We never copy its UI, text or assets. We only learn from its documented behaviour. |
| Tenant / Client | A customer organisation subscribed to Spyrl. "Client" in the business documents; tenant in technical documents. |
| Platform | Spyrl as operated by us: the control plane, shared infrastructure and our internal staff. |
| Cell | A deployable unit of the application plane (app containers + database + cache + storage prefix). It is either pooled (many tenants) or dedicated (one tenant). |
spyrl.app | Placeholder domain used in examples. It is not registered. |
2. Evidence labels (mandatory in research, BRD, PRD)
| Label | Use when |
|---|---|
| [Observed] | The Spryple Help Center explicitly documents it. Cite the page with a role code, e.g. (A: Leave Management). |
| [Inferred] | It is not stated, but it follows logically from documented workflows or screens. Give the reasoning. |
| [Proposed] | It is our own enhancement, redesign or new feature. |
Role codes for citations: SA Super Admin, A Admin, M Managers, E Employee, MOB Mobile App, I LMS Instructor (see research/source-inventory.md).
3. Module codes
Every requirement, epic, API path and table prefix uses these codes.
| Code | Module | Spryple equivalent | Release |
|---|---|---|---|
| PLT | Platform & Tenant Administration (control plane) | — (not exposed; Spryple "Super Admin" is a tenant role) | R1 (core) |
| ORG | Organisation Setup & Masters | Employee Mgmt → company, department, designation, location, logo, holidays | R1 |
| IAM | Identity, Access & Security | Users Login, Roles & Permissions, HR Policies (password rules), Password Reset, Device Approvals | R1 |
| EMP | Core HR & Onboarding | Employee Mgmt → new hires, directory, documents, checklists, induction, Excel upload | R1 |
| ATT | Attendance, Shifts & Time | Attendance Mgmt (all roles), Spryple Lite, HCM attendance | R1 |
| LVE | Leave & Holidays | Leave Mgmt (all roles) | R1 |
| PAY | Payroll & Statutory Compliance (India) | Payroll Mgmt (Finance Admin / Finance Manager / Employee) | R1 |
| NTF | Notifications & Workflow (approvals engine) | Implicit everywhere (emails, reminders, alerts, Messages Master) | R1 |
| RPT | Reporting, Dashboards & Exports | Super Admin dashboard + per-module reports | R1 (standard) → R4 (advanced) |
| MOB | Mobile app (single app, role-based) + Kiosk mode | Spryple HCM, Spryple Lite, Spryple CRM, Claims app | R1 (ESS/MSS) → R2 (kiosk/face) |
| CLM | Claims & Expense Reimbursement | Claims Mgmt (web + mobile) | R2 |
| EXT | Exit & Full-and-Final Settlement | Exit Mgmt | R2 |
| ENG | Engagement: Announcements, Recognition | Announcements, Rewards & Recognition | R2 |
| FFM | Field Force & Sales CRM | CRM Field Force Mgmt, Sales CRM web/mobile | R3 |
| TSM | Timesheets & Projects | Time Sheet Mgmt | R3 |
| LMS | Learning Management | LMS (Admin, Manager, Employee, Instructor) | R4 |
4. Roles
Roles are bundles of permissions plus a data scope. Tenants can clone them and create custom roles ([Proposed]). The reporting-manager relationship comes from the org hierarchy and is not a manually assigned role.
Tenant roles
| Role key | Name | Spryple equivalent | Default data scope |
|---|---|---|---|
org_owner | Organisation Owner | Super Admin | ORG |
hr_admin | HR Administrator (configuration) | Admin | ORG |
hr_manager | HR Manager (operations) | HR Manager | ORG or LOCATION |
finance_admin | Finance Administrator (payroll configuration) | Finance Admin | ORG |
payroll_manager | Payroll / Finance Manager (runs payroll, finance approvals) | Finance Manager | ORG or LOCATION |
line_manager | Reporting Manager (derived from reports_to) | Manager / Reporting Manager | TEAM |
sales_admin | Sales Administrator (CRM masters) | Sales Admin | ORG |
sales_manager | Sales Manager | Sales Manager | TEAM or LOCATION |
employee | Employee (everyone has it) | Employee | SELF |
field_executive | Field Executive (employee + tracking/CRM) | Sales Executive / Field Executive | SELF |
kiosk_operator | Front-desk / Kiosk Operator | Receptionist | LOCATION (punch-only) |
instructor | LMS Instructor | LMS Instructor | Own courses |
auditor | Read-only Auditor [Proposed] | — | ORG (read) |
Platform roles [Proposed]
platform_admin (full control plane), support_engineer (time-boxed, consented, audited tenant access), billing_admin (plans, invoices), release_manager (cell versions and rollouts).
Data scopes
SELF → TEAM (direct + indirect reports) → DEPARTMENT → LOCATION → ORG. A permission check is always the pair (permission, scope), e.g. att.request.approve@TEAM.
5. Identifier schemes
| Artifact | Format | Example |
|---|---|---|
| Business objective | BO-NN | BO-03 |
| Business requirement | BR-<MOD>-NN | BR-PAY-04 |
| Business rule | RULE-<MOD>-NN | RULE-LVE-07 |
| Functional requirement | FR-<MOD>-NNN | FR-ATT-012 |
| Non-functional requirement | NFR-<CAT>-NN (CAT = PERF, SEC, AVL, SCL, OBS, PRV, ACC, I18N, MNT, CMP) | NFR-SEC-04 |
| User story | US-<MOD>-NN with acceptance criteria AC1..n (Given/When/Then) | US-LVE-03 |
| Epic (plan) | E-<MOD>-NN | E-PAY-02 |
| Milestone | M<N> | M3 |
| Risk | RSK-NN | RSK-05 |
| Architecture decision | ADR-NNN | ADR-002 |
| Research finding (Spryple) | SP-<MOD>-NN | SP-ATT-04 |
Priorities use MoSCoW: Must / Should / Could / Won't (this release).
6. Canonical baseline decisions
Each one is detailed in architecture.md. The rationale lives in the Docusaurus decision log.
- Architecture style: a modular monolith in TypeScript (NestJS 11), with strict module boundaries and an in-process domain-event bus. Services are extracted only on evidence: GPS ingest and payroll compute are the first candidates.
- Tenancy: hybrid, "pooled by default, dedicated on demand". Pooled cells use a shared PostgreSQL database with a shared schema,
tenant_idon every tenant-owned row, and PostgreSQL Row-Level Security as defence-in-depth. Dedicated cells (Enterprise plan) run the same images and migrations with their own database, and optionally their own full stack. A single release train serves both. - Control plane vs application plane: tenant registry, provisioning, plans and billing, feature flags/entitlements, the cell map, version rollout and support access all live in a separate control-plane service and database.
- Data: PostgreSQL 16+, accessed through Prisma ORM (team familiarity) using a tenant-scoped client extension that sets the tenant ID transaction-locally (
set_config('app.tenant_id', …, true)). Redis is used for cache, rate limits and BullMQ queues. Files go to S3-compatible object storage with tenant-prefixed keys and presigned URLs. GPS points go to monthly-partitioned tables. - Configuration model: effective-dated, versioned, typed policies (JSON-schema-validated) assigned by applicability rules (location / department / designation / employment type / grade). This replaces numbered free-text "rules" and fixes "changes apply only to new employees" (Spryple).
- Frontend: a single web SPA built with Vite + React 19 + TypeScript + Tailwind 4 + shadcn/ui + TanStack Query, with role-aware navigation (matching
lookin-hr). The mobile app is a single Expo (Expo Router) app with role-based navigation, an offline punch queue and a kiosk mode. - Tenant addressing:
https://{tenant}.spyrl.appfor web, a company code for mobile login, and custom domains (CNAME + automatic TLS) on the Enterprise plan. - Auth: built-in auth (argon2id passwords, short-lived JWT access + rotating refresh tokens, mobile device binding), TOTP MFA (mandatory for admin roles), and OIDC SSO (Google Workspace, Microsoft Entra ID) on paid plans. There are no default shared passwords: users activate through one-time invite links.
- Hosting: data stays in India (AWS
ap-south-1Mumbai primary,ap-south-2Hyderabad for DR copies). Docker images are used everywhere. Dev/UAT run on Dokploy (existing team practice). Production starts as Stage A: Dokploy-managed containers on EC2, with managed RDS PostgreSQL (PITR) + ElastiCache + S3. It graduates to Stage B (ECS Fargate, Terraform) when the scale or SLA triggers in architecture.md are met. - CI/CD: GitHub Actions → container registry → migrate (expand/contract) → canary cell → progressive rollout across cells.
- Observability: OpenTelemetry traces, metrics and logs with a
tenant_idattribute; Sentry for errors; Grafana dashboards and alerting. - Billing: a per-active-employee-per-month (PEPM) price with plan tiers Lite / Standard / Professional / Enterprise, add-ons (Field Force, LMS) and metered usage (SMS/WhatsApp, GPS-tracked users, storage). Razorpay Subscriptions is used for India.
- Compliance posture: DPDP Act 2023 (and its Rules) for personal data, explicit consent for biometric and location data, India labour/payroll statutes (EPF, ESI, PT, LWF, TDS, Gratuity), and the Labour Codes. Statutory rates are configurable reference data, never hard-coded.
7. MVP & release scope (canonical)
| Release | Theme | Modules |
|---|---|---|
| R0 | Foundations | PLT (provisioning, plans, flags), IAM, ORG, NTF core, audit, CI/CD, observability |
| R1 — MVP | Attend-to-Pay core | EMP, ATT (web/mobile punch with selfie + geo-fence, shifts, rotations, week-offs, regularization, permissions, OT, biometric CSV/API import), LVE, PAY (India statutory: EPF, ESI, PT, LWF, TDS with IT declarations, ECR/ESI/PT files, bank files), RPT (standard), MOB (ESS + MSS) |
| R2 | Complete HR lifecycle | CLM, EXT (+ F&F), ENG, MOB kiosk + face verification, biometric device gateway, Form 16 / 24Q outputs, public API & webhooks |
| R3 | Field & projects | FFM (tracking, CRM pipeline, travel), TSM |
| R4 | Learning & scale | LMS, advanced analytics, dedicated-cell automation, accounting/ERP API integrations (Zoho Books, ERPs). Tally XML/CSV journal export ships in R2 |
8. Writing style
- Write in plain English and keep it practical. Use tables for structured facts and Mermaid for diagrams.
- Use
.mdfiles (CommonMark). Docusaurus is configured withmarkdown.format: 'detect', so.mdfiles are not parsed as MDX. Do not use JSX in.mdfiles. - Root canonical documents link only to each other, to
research/, and toCONVENTIONS.mdusing relative links. The sync script mirrors them intowebsite/docs/reference/, so those links keep working. - Never state a Spryple capability without an
[Observed]/[Inferred]label and a citation. - Treat statutory rates and thresholds as examples to verify, and label them that way.
9. Documentation site layout (Docusaurus, website/docs/)
| Folder | Content | Owner |
|---|---|---|
intro.md, product/ | Welcome, product overview, personas & roles, glossary | Product |
reference/ | Generated. It is synced from the root canonical files by website/scripts/sync-docs.mjs. Never edit it by hand. | — |
modules/ | One design spec per module (PLT, ORG, IAM, EMP, ATT, LVE, PAY, NTF, RPT, MOB, CLM, EXT, ENG, FFM, TSM, LMS) | Product + Eng |
features/ | Feature catalogue (every feature with label, release, MoSCoW) | Product |
workflows/ | End-to-end cross-module journeys | Product |
architecture/ | System design, tech stack, decision log | Eng |
data/ | Data-model conventions, ERDs, data dictionary | Eng |
api/ | API conventions, endpoint catalogue, events & webhooks | Eng |
integrations/ | External integrations | Eng |
operations/ | Deployment, client onboarding, administration, backup/DR, observability, upgrades | Ops |
security/ | Security overview, RBAC permission matrix, privacy (DPDP) | Security |
quality/ | Testing strategy, maintenance & support | QA |
roadmap/ | Roadmap and MVP | Product |
Docs pages link to canonical documents with relative paths such as ../reference/prd.md. Every page starts with front matter that contains title, sidebar_position and a one-line description.
Synced from
/CONVENTIONS.mdin the repository root. Edit the root file, not this page.