How khairul-anik-qp/qpbd-office works
1. This is a pnpm workspace monorepo with three meaningful boundaries: apps/web for the PWA frontend, apps/api for the NestJS backend, and packages/shared for domain logic and shared constants/types used by both sides.
2. packages/shared is the domain contract layer. It contains request/status enums, user types, location/type constants, assignment helpers, operating-window logic, staff-count logic, and shared icon mappings. Both web and API import from here, so architecture diagrams should show it as the source of truth for cross-cutting business rules.
3. The backend is a NestJS 10 application in apps/api. It is organized by feature modules: auth, users, admin, staff, requests, assignment, SSE, push, reminders, email, and Prisma access. The backend owns all persistence, authorization, routing decisions, notifications, and background maintenance.
4. PostgreSQL is the primary system of record. Prisma sits between the API and the database, with migrations defining schema evolution for users, requests, push subscriptions, availability timestamps, favorites, cancellation/discard state, and related request lifecycle fields.
5. Authentication is Google OAuth plus JWT. The frontend sends Google sign-in credentials to /api/auth/google, receives a session token for active users, and routes based on role. New users are created as pending and must be approved or registered before accessing employee/staff areas.
6. The frontend is a React 19/Vite PWA in apps/web, split into role-specific shells: employee, staff, and admin. These shells are lazy-loaded UI boundaries that map directly to the three user roles and their workflows, rather than a single generic app screen.
7. Real-time updates use two channels: REST for commands and SSE for live state changes. The backend exposes /sse/events, and the web app has hooks and stores for SSE connection state, request synchronization, pending counts, and tab badges. Architecture diagrams should show SSE as a push-only event stream from API to clients, not a bidirectional socket.
8. Push notifications are a separate delivery path from SSE. The API stores push subscriptions and can send Web Push / FCM notifications, while the staff UI has setup and prompt components for enabling notifications. This matters because staff updates arrive both in-browser and out-of-browser.
9. The request lifecycle is the core business flow. Employees create requests through the web UI; the assignment service picks a staff target; staff accept, forward, and complete requests; the employee view reflects status changes live. The request states include new, progress, done, and discarded, with midnight auto-discard for stale open requests within the configured operating window.
10. Staff availability is its own subsystem because it affects routing and visibility. The API exposes staff roster and availability updates, and includes auto-reset/reminder services for busy status and stale “new” items. The frontend staff shell is organized around tabs for New, In progress, and Done.
11. There is an admin approval workflow for onboarding. Admin endpoints expose a pending queue and approval/rejection actions, while the admin UI shows the queue and staff/profile setup. Bootstrap admins are created from BOOTSTRAP_ADMIN_EMAILS on first login, which is an operational backdoor for initial setup.
12. Deployment is designed for single-origin production. The built web app is served alongside the API container, with Caddy and Docker Compose used for production orchestration. In development, Vite proxies /api and /sse to the API, so the browser still experiences one logical application surface.
13. Background jobs are part of the backend, not the frontend. The reminders service, request expiry service, and availability reset service run server-side to enforce time-based workflow rules independent of active clients.
14. The main diagram should therefore show four layers: browser/PWA shells, NestJS feature modules, Prisma/PostgreSQL, and external services such as Google OAuth, push providers, and optional email delivery. The key data flows are sign-in, request creation and status changes, live event broadcast, and notification delivery.
Main entry points: prisma.module.ts Prisma Access · router.tsx Router · requests.module.ts Requests Module · index.ts Domain Contract
Components 26
Browser / PWA
React/Vite client surfaces and client-side state.
- Router · Routes users into role-specific shells and auth screens.
apps/web/src/router.tsx - Employee Shell · Employee-facing workflow for creating and tracking requests.
apps/web/src/shells/employee/EmployeeShell.tsx - Staff Shell · Staff-facing queue, availability, and request handling UI.
apps/web/src/shells/staff/StaffShell.tsx - Admin Shell · Admin approval and onboarding workflow.
apps/web/src/shells/admin/AdminShell.tsx - Realtime Sync · SSE connection state, request sync, and tab badge updates.
apps/web/src/components/RealtimeSync.tsx - Push Setup · Staff notification setup and permission prompts.
apps/web/src/context/PushSetupContext.tsx
NestJS API
Backend feature modules, routing, background jobs, and delivery services.
- Auth Module · Google sign-in, JWT sessions, guards, and role checks.
apps/api/src/auth/auth.module.ts - Requests Module · Request creation, lifecycle transitions, and list/query APIs.
apps/api/src/requests/requests.module.ts - Staff Module · Availability, roster, and auto-reset/reminder flows.
apps/api/src/staff/staff.module.ts - Assignment Service · Chooses staff targets for new requests.
apps/api/src/assignment/assignment.service.ts - Admin Module · Pending-user queue and onboarding approval actions.
apps/api/src/admin/admin.module.ts - SSE Module · Push-only event stream for live client updates.
apps/api/src/sse/sse.module.ts - Push Module · Stores subscriptions and sends Web Push/FCM notifications.
apps/api/src/push/push.module.ts - Reminders · Server-side reminder and maintenance jobs.
apps/api/src/reminders/reminders.module.ts - Email Service · Optional email delivery path for backend notifications.
apps/api/src/email/email.module.ts - Prisma Access · Typed persistence boundary between NestJS and the database.
apps/api/src/prisma/prisma.module.ts
Shared Contract
Domain rules and cross-cutting types used by both web and API.
- Domain Contract · Source of truth for request states, users, staff rules, assignments, and operating windows.
packages/shared/src/index.ts - Request Rules · Request lifecycle constants and helpers.
packages/shared/src/requests.ts - Staff Rules · Availability, staffing, and roster helpers.
packages/shared/src/staff-count.ts - Assignment Logic · Target selection and assignment helpers.
packages/shared/src/assignment.ts - Operating Window · Time-window logic for stale-item expiry and auto-discard behavior.
packages/shared/src/operating-window.ts
Persistence
Prisma schema and PostgreSQL system of record.
- Schema · Database schema and migration history for users, requests, push subscriptions, availability, and lifecycle fields.
apps/api/prisma/schema.prisma - PostgreSQL · Primary persistent store for users, requests, and staff state.
External Services
Identity, push delivery, and optional email providers.
- Google OAuth · External sign-in provider for authentication.
- Push Provider · Out-of-browser notification delivery destination.
- Email Provider · Optional email transport for backend notifications.
Connections 30
- Router → Employee Shell: role routes · Routes employees into the employee shell.
- Router → Staff Shell: role routes · Routes staff into the staff shell.
- Router → Admin Shell: role routes · Routes admins into the admin shell.
- Router → Auth Module: login · Submits Google credentials and receives session state.
- Employee Shell → Domain Contract: uses rules · Renders and validates request states and helpers.
- Staff Shell → Domain Contract: uses rules · Uses shared staff and request semantics.
- Admin Shell → Domain Contract: uses rules · Uses shared user and approval semantics.
- Realtime Sync → SSE Module: SSE · Consumes push-only live events from the backend.
- Push Setup → Push Module: setup · Registers notification permissions and subscriptions.
- Auth Module → Google OAuth: OAuth · Authenticates users through Google.
- Auth Module → Prisma Access: session users · Creates or updates authenticated user records.
- Admin Module → Prisma Access: approve users · Reads pending users and applies approval decisions.
- Requests Module → Assignment Service: assign · Delegates staff selection for new requests.
- Requests Module → Prisma Access: persist · Stores request lifecycle changes.
- Staff Module → Prisma Access: availability · Reads and updates staff availability state.
- Staff Module → Reminders: reset jobs · Supports busy-status resets and stale-item maintenance.
- Requests Module → Reminders: expiry jobs · Enforces midnight auto-discard for stale requests.
- SSE Module → Requests Module: live state · Broadcasts request changes to connected clients.
- SSE Module → Staff Module: live state · Broadcasts staff availability changes to connected clients.
- Push Module → Push Provider: deliver · Sends Web Push or FCM notifications.
- Push Module → Prisma Access: subscriptions · Stores push subscriptions.
- Email Service → Email Provider: deliver · Sends outbound email notifications when used.
- Prisma Access → Schema: schema · Uses Prisma schema and migrations as persistence contract.
- Schema → PostgreSQL: storage · Defines the PostgreSQL data model.
- Request Rules → Requests Module: consumed by · Backend request logic is based on shared lifecycle rules.
- Staff Rules → Staff Module: consumed by · Backend staffing logic uses shared availability helpers.
- Assignment Logic → Assignment Service: consumed by · Assignment service uses shared target-selection rules.
- Operating Window → Reminders: consumed by · Background jobs use operating-window logic.
- Domain Contract → Router: types · Frontend imports shared domain types and constants.
- Domain Contract → Auth Module: types · Backend imports shared domain types and constants.