# serkanfidanci/rastamanlonge architecture

> Architecture diagram of the GitHub repository serkanfidanci/rastamanlonge, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/serkanfidanci/rastamanlonge
- Repository: https://github.com/serkanfidanci/rastamanlonge

## Overview

1. **Overall shape**
   - This is a two-tier business system: a React/Vite frontend in the browser and a Node.js/Express backend API, backed by a single PostgreSQL 16 database.
   - Deployment is containerized with Docker Compose: one app container and one Postgres container. There is no Supabase or external app server.

2. **Client layer**
   - The frontend is a TypeScript React SPA (`src/`) with PWA support (`sw.js`, `InstallPrompt.tsx`, `pwa.tsx`), so users can install it like an app.
   - The browser client handles customer booking flows, admin screens, and employee views, but all authoritative business actions are validated by the backend.

3. **API / application layer**
   - The backend lives under `server/` and is the main orchestration layer for all business rules.
   - Key modules are split by concern: `auth.js` for JWT/bcrypt auth, `db.js` for Postgres access, `whatsapp.js` for notification transport, `migrate.js` and `seed.js` for startup database setup, and `index.js` as the server entrypoint.
   - The backend is the boundary for booking validation, role checks, reporting, notification sending, and config management.

4. **Authentication and role boundaries**
   - Auth is JWT-based with password hashing via bcrypt.
   - The system distinguishes at least three access patterns:
     - public/customer flows for booking and phone verification,
     - admin flows for configuration, approvals, campaigns, and reporting,
     - employee flows for seeing their own appointments and financial entries.
   - The README makes clear that employees are restricted to their own records, while admins have system-wide visibility.

5. **Core booking workflow**
   - Customers create appointments by selecting service, employee, date, and time.
   - New appointments are stored as `pending` and later moved by admin to approved, rejected, cancelled, or completed states.
   - Completion is a business event: completed appointments automatically generate revenue records in the finance ledger.

6. **Finance and reporting**
   - Financial data is stored separately from appointments in `finance_entries`.
   - The admin side can report on income, expenses, net profit, and employee-based performance.
   - Employees can also add their own extra income/transaction records, so finance is not derived only from appointments.

7. **Notification subsystem**
   - WhatsApp messaging is a first-class subsystem, not just a side effect.
   - `server/whatsapp.js` abstracts provider delivery, supporting Meta WhatsApp Cloud API, a generic webhook provider, or a disabled mode.
   - Every send attempt and failure is written to `notification_logs`, which makes notifications observable and auditable.

8. **OTP and phone verification**
   - There is a dedicated public API for WhatsApp OTP request/verify and phone-verification checks.
   - Verified phone state is remembered client-side for 180 days, but the server keeps only a hash of the verification key.
   - This verification gate sits in front of the customer booking flow, so a booking cannot be created without a valid phone verification.

9. **Campaign / discount engine**
   - Campaigns are stored and validated server-side, with rules for date, service, usage limits, and discount amount.
   - Active campaigns are shown on the homepage, and booking can apply a campaign code.
   - The backend re-validates the campaign at appointment creation time, so the discount used for booking is authoritative and reflected in finance records.

10. **Employee scheduling and time off**
   - The schema includes `employee_schedules`, `employee_timeoff`, and `employee_services`, so availability is modeled explicitly rather than inferred.
   - Hourly appointment slot logic and time-off constraints are handled in later migrations, which means scheduling is a backend-owned availability problem.

11. **Persistence and schema evolution**
   - Database schema lives in `db/migrations/` as numbered SQL migrations, starting with core tables and then adding feature slices like WhatsApp OTP, phone verification, campaigns, reminders, and campaign engine logic.
   - Startup applies migrations automatically, and an initial admin account is seeded from environment variables.
   - This indicates the database is the single source of truth for both operational data and system configuration.

12. **Files, config, and deployment**
   - Employee profile photos are uploaded as files and persisted in a Docker volume, so they are separate from relational data.
   - Sensitive settings such as JWT secret, encrypted WhatsApp token storage key, and provider credentials come from `.env`.
   - The app is designed for local development and production Docker deployment, with the frontend and backend packaged together in the app container and PostgreSQL isolated in its own container.

Main entry points: [`db`](https://github.com/serkanfidanci/rastamanlonge/tree/main/db) (PostgreSQL), [`server/index.js`](https://github.com/serkanfidanci/rastamanlonge/blob/main/server/index.js) (API entry), [`src/App.tsx`](https://github.com/serkanfidanci/rastamanlonge/blob/main/src/App.tsx) (React SPA), [`Dockerfile`](https://github.com/serkanfidanci/rastamanlonge/tree/main/Dockerfile) (App container)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Client"]
  node_frontend_app["React SPA<br/>Vite React client<br/>[App.tsx]"]
  node_frontend_api["API client<br/>browser API layer<br/>[api.ts]"]
  node_frontend_pwa["PWA shell<br/>installable client<br/>[sw.js]"]
  node_frontend_bootstrap["Client entry<br/>app bootstrap<br/>[main.tsx]"]
end

subgraph group_server["Server"]
  node_server_entry["API entry<br/>Express server<br/>[index.js]"]
  node_server_auth["Auth<br/>[auth.js]"]
  node_server_db[("DB access<br/>Postgres layer<br/>[db.js]")]
  node_server_notifications["WhatsApp<br/>notification transport<br/>[whatsapp.js]"]
  node_server_migrate["Migrations<br/>startup schema<br/>[migrate.js]"]
  node_server_seed["Seed data<br/>initial setup<br/>[seed.js]"]
end

subgraph group_data["Data & Deploy"]
  node_schema_core["Core schema<br/>SQL migrations<br/>[001_initial.sql]"]
  node_schema_slots["Scheduling schema<br/>SQL migrations"]
  node_schema_verification["Verification schema<br/>SQL migrations"]
  node_schema_campaigns["Campaign schema<br/>SQL migrations<br/>[006_campaigns.sql]"]
  node_schema_reminders["Reminder schema<br/>SQL migrations"]
  node_db_files["Uploaded files<br/>volume-backed assets"]
  node_postgres[("PostgreSQL<br/>database container")]
  node_docker_app["App container<br/>Docker service"]
  node_docker_db["DB container<br/>Docker service<br/>[docker-compose.yml]"]
end

node_frontend_bootstrap -->|"render"| node_frontend_app
node_frontend_app -->|"calls"| node_frontend_api
node_frontend_app -.->|"installs"| node_frontend_pwa
node_frontend_api -->|"HTTP"| node_server_entry
node_server_entry -->|"guards"| node_server_auth
node_server_entry -->|"queries"| node_server_db
node_server_entry -->|"sends"| node_server_notifications
node_server_entry -->|"starts"| node_server_migrate
node_server_entry -->|"starts"| node_server_seed
node_server_migrate -->|"applies"| node_postgres
node_server_seed -->|"writes"| node_postgres
node_server_db -->|"uses"| node_postgres
node_server_auth -->|"reads"| node_postgres
node_server_notifications -->|"logs"| node_postgres
node_schema_core -->|"defines"| node_postgres
node_schema_slots -->|"extends"| node_postgres
node_schema_verification -->|"extends"| node_postgres
node_schema_campaigns -->|"extends"| node_postgres
node_schema_reminders -->|"extends"| node_postgres
node_docker_app -->|"runs"| node_server_entry
node_docker_app -->|"serves"| node_frontend_app
node_docker_db -->|"hosts"| node_postgres
node_db_files -.->|"mounted in"| node_docker_app

click node_frontend_app "https://github.com/serkanfidanci/rastamanlonge/blob/main/src/App.tsx"
click node_frontend_api "https://github.com/serkanfidanci/rastamanlonge/blob/main/src/api.ts"
click node_frontend_pwa "https://github.com/serkanfidanci/rastamanlonge/blob/main/public/sw.js"
click node_frontend_bootstrap "https://github.com/serkanfidanci/rastamanlonge/blob/main/src/main.tsx"
click node_server_entry "https://github.com/serkanfidanci/rastamanlonge/blob/main/server/index.js"
click node_server_auth "https://github.com/serkanfidanci/rastamanlonge/blob/main/server/auth.js"
click node_server_db "https://github.com/serkanfidanci/rastamanlonge/blob/main/server/db.js"
click node_server_notifications "https://github.com/serkanfidanci/rastamanlonge/blob/main/server/whatsapp.js"
click node_server_migrate "https://github.com/serkanfidanci/rastamanlonge/blob/main/server/migrate.js"
click node_server_seed "https://github.com/serkanfidanci/rastamanlonge/blob/main/server/seed.js"
click node_schema_core "https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/001_initial.sql"
click node_schema_slots "https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/002_service_vip.sql"
click node_schema_verification "https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/004_whatsapp_otp.sql"
click node_schema_campaigns "https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/006_campaigns.sql"
click node_schema_reminders "https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/008_appointment_reminders.sql"
click node_postgres "https://github.com/serkanfidanci/rastamanlonge/tree/main/db"
click node_docker_app "https://github.com/serkanfidanci/rastamanlonge/tree/main/Dockerfile"
click node_docker_db "https://github.com/serkanfidanci/rastamanlonge/blob/main/docker-compose.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_frontend_app,node_frontend_api,node_frontend_pwa,node_frontend_bootstrap toneBlue
class node_server_entry,node_server_auth,node_server_db,node_server_notifications,node_server_migrate,node_server_seed toneAmber
class node_schema_core,node_schema_slots,node_schema_verification,node_schema_campaigns,node_schema_reminders,node_db_files,node_postgres,node_docker_app,node_docker_db toneMint
```

## Components

### Client

Browser SPA and PWA entrypoints

- [React SPA](https://github.com/serkanfidanci/rastamanlonge/blob/main/src/App.tsx): Vite React client · TypeScript browser app for customer, admin, and employee screens · `src/App.tsx`
- [API client](https://github.com/serkanfidanci/rastamanlonge/blob/main/src/api.ts): browser API layer · Client-side calls into the backend · `src/api.ts`
- [PWA shell](https://github.com/serkanfidanci/rastamanlonge/blob/main/public/sw.js): installable client · Service worker, install prompt, and PWA bootstrapping · `public/sw.js`
- [Client entry](https://github.com/serkanfidanci/rastamanlonge/blob/main/src/main.tsx): app bootstrap · Main frontend startup and rendering path · `src/main.tsx`

### Server

Node.js API and business logic

- [API entry](https://github.com/serkanfidanci/rastamanlonge/blob/main/server/index.js): Express server · Main backend process and route orchestration · `server/index.js`
- [Auth](https://github.com/serkanfidanci/rastamanlonge/blob/main/server/auth.js): JWT/bcrypt auth · Login, token handling, and role checks · `server/auth.js`
- [DB access](https://github.com/serkanfidanci/rastamanlonge/blob/main/server/db.js): Postgres layer · Database connection and query access · `server/db.js`
- [WhatsApp](https://github.com/serkanfidanci/rastamanlonge/blob/main/server/whatsapp.js): notification transport · Provider abstraction for Cloud API, webhook, or disabled mode · `server/whatsapp.js`
- [Migrations](https://github.com/serkanfidanci/rastamanlonge/blob/main/server/migrate.js): startup schema · Applies database migrations on startup · `server/migrate.js`
- [Seed data](https://github.com/serkanfidanci/rastamanlonge/blob/main/server/seed.js): initial setup · Creates initial admin and bootstrap data · `server/seed.js`

### Data & Deploy

Database schema, files, and containerization

- [Core schema](https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/001_initial.sql): SQL migrations · Appointments, users, services, finance, and notification tables · `db/migrations/001_initial.sql`
- [Scheduling schema](https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/002_service_vip.sql): SQL migrations · Service VIP, hourly slots, time off, and employee service rules · `db/migrations/002_service_vip.sql`
- [Verification schema](https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/004_whatsapp_otp.sql): SQL migrations · WhatsApp OTP and phone verification persistence · `db/migrations/004_whatsapp_otp.sql`
- [Campaign schema](https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/006_campaigns.sql): SQL migrations · Campaign storage and campaign engine rules · `db/migrations/006_campaigns.sql`
- [Reminder schema](https://github.com/serkanfidanci/rastamanlonge/blob/main/db/migrations/008_appointment_reminders.sql): SQL migrations · Appointment reminder support · `db/migrations/008_appointment_reminders.sql`
- **Uploaded files**: volume-backed assets · Employee profile photos stored outside the relational database
- [PostgreSQL](https://github.com/serkanfidanci/rastamanlonge/tree/main/db): database container · Single source of truth for operational data and config · `db`
- [App container](https://github.com/serkanfidanci/rastamanlonge/tree/main/Dockerfile): Docker service · Builds and runs frontend plus backend in one container · `Dockerfile`
- [DB container](https://github.com/serkanfidanci/rastamanlonge/blob/main/docker-compose.yml): Docker service · Isolated PostgreSQL service in Docker Compose · `docker-compose.yml`

## Connections

- Client entry → React SPA: render · Bootstraps the SPA
- React SPA → API client: calls · Uses backend endpoints for business actions
- React SPA → PWA shell: installs · Enables app-like offline/install behavior
- API client → API entry: HTTP · Sends client requests to the API
- API entry → Auth: guards · Applies authentication and role boundaries
- API entry → DB access: queries · Reads and writes application data
- API entry → WhatsApp: sends · Triggers WhatsApp delivery for OTP and business events
- API entry → Migrations: starts · Runs schema migrations during startup
- API entry → Seed data: starts · Seeds initial admin configuration
- Migrations → PostgreSQL: applies · Executes SQL migrations against PostgreSQL
- Seed data → PostgreSQL: writes · Creates initial records in PostgreSQL
- DB access → PostgreSQL: uses · Primary persistence backend
- Auth → PostgreSQL: reads · Checks users and hashes from the database
- WhatsApp → PostgreSQL: logs · Writes send attempts and failures to notification_logs
- Core schema → PostgreSQL: defines · Base relational model
- Scheduling schema → PostgreSQL: extends · Adds scheduling and availability tables
- Verification schema → PostgreSQL: extends · Adds OTP and phone verification tables
- Campaign schema → PostgreSQL: extends · Adds campaign and discount tables
- Reminder schema → PostgreSQL: extends · Adds reminder support tables
- App container → API entry: runs · Packages the application stack
- App container → React SPA: serves · Includes the browser app build
- DB container → PostgreSQL: hosts · Runs the database service
- Uploaded files → App container: mounted in · Persisted in a Docker volume attached to the app container
