Skip to content

Architecture

Syed Ahmer Shah edited this page Oct 25, 2026 · 1 revision

A short tour. Details, the data model and caching: docs/architecture.md.

Layers

browser / API client
   |
Django (gunicorn)
   |-- apps/public      server-rendered site (works without JavaScript)
   |-- apps/api         DRF views and serializers, API keys, throttles, usage
   |-- apps/accounts    users, sign-up codes, 2FA, Google and Microsoft sign-in, sessions
   |-- apps/orgs        organizations, roles, invites, audit log
   |-- apps/calendars   company calendars and custom days
   |-- apps/feeds       private iCal feeds
   |-- apps/notifications, apps/webhooks   digests and signed webhooks (Celery)
   |
   `-- apps/core        pure Python date logic on the holidays library
   |
MySQL 8 (data)   Redis (cache, Celery queue)   Celery worker + Beat

The React web app (Vite, TypeScript strict) is built into the same image and served by Django.

Rules that shape the code

  • apps/core has no Django imports and 100% branch test coverage. It uses the library's own working-day logic and never copies holiday data.
  • Dates are plain datetime.date; there is no time-zone maths in the domain.
  • Every organization query is filtered by the current organization. Another organization's data answers 404, and a test checks this for every endpoint.
  • Countries, regions, languages and categories are validated against the library; years and days are capped.
  • Secrets come only from environment variables. Secrets the app must read back are encrypted; anything it only compares (passwords, API keys, tokens, codes) is hashed.

More

Clone this wiki locally