Money — integer paise
All monetary values are stored and computed as integer paise (₹1 = 100 paise). Never use floating point for money.Dates & time
- Stored as
timestamptz(UTC); displayed in IST (UTC+5:30). - Display format is DD/MM/YYYY via
formatDateIN. - API payloads use ISO-8601 strings.
Layer rules (strict)
API routes are thin orchestrators: parse → ZodsafeParse → call business
logic / queries → return JSON. No DB queries live in route handlers’ own logic
beyond calling the query layer.
API response envelope
Every JSON API responds with one of two shapes.- Success
- Error
meta is present only on paginated list endpoints.Background-job routes (
/api/jobs/*) are the exception: they return a minimal
{ processed } body and a non-2xx status on failure so QStash can retry. They
do not use the success/error envelope.Error codes
Codes come from a central registry (@rgss/errors). Expand for the common ones — domain-specific codes for booking, membership, invoice, gems, offer, and branch rules are documented on each API page.
VALIDATION_ERROR — 400
VALIDATION_ERROR — 400
Zod validation failed. The
details field carries the field → message map.UNAUTHENTICATED — 401
UNAUTHENTICATED — 401
No valid session.
FORBIDDEN — 403
FORBIDDEN — 403
Authenticated but insufficient role.
NOT_FOUND — 404
NOT_FOUND — 404
Resource does not exist.
CONFLICT — 409
CONFLICT — 409
State conflict (e.g. double-book).
BUSINESS_RULE_VIOLATION — 409/422
BUSINESS_RULE_VIOLATION — 409/422
A domain rule was violated.
RATE_LIMITED — 429
RATE_LIMITED — 429
Too many requests.
INTERNAL_ERROR — 500
INTERNAL_ERROR — 500
Unexpected error (retryable).
Related Pages
Data Model
Schema conventions, enums, and ID formats
Error Handling
The AppError class and handler pattern
API Reference
Per-endpoint codes and contracts