# CRM Server – Architektúra a flow

Tento dokument popisuje, ako backend funguje: aká je štruktúra kódu, akou cestou prechádza požiadavka, aké služby spolu komunikujú a kde sa riešia bezpečnostné a chybové scenáre. Všetky cesty v kóde sú písané v ES modules.

## Základný stack
- **Express 4** (ESM) + **Drizzle ORM** (PostgreSQL)
- **JWT** pre prístupové/refresh tokeny (httpOnly cookies), **bcrypt** pre heslá
- **Zod** na validačné schémy, **helmet**, **cors**, **express-rate-limit**
- **JMAP** integrácia pre e-maily (Truemail) + AES-256-GCM šifrovanie hesiel k e-mail účtom

## Štruktúra priečinkov (hlavné časti)
- `src/app.js` – skladá middleware pipeline a mountuje routes, pridáva notFound/error handler.
- `src/index.js` – spúšťací bod servera.
- `src/routes/` – deklarácie endpointov (1 súbor = 1 doména). Všetky používajú middlewares + volajú controller.
- `src/controllers/` – spracovanie requestu, volanie service vrstvy, odoslanie odpovedí. Chyby posielajú cez `next(err)`.
- `src/services/` – biznis logika a práca s DB/JMAP (bez Express závislosti).
- `src/middlewares/` – auth (JWT + role), security (rate limiting, Zod validateInput), global (validateBody pattern check, 404, error handler).
- `src/utils/` – `errors.js` (AppError a formátovanie), `jwt.js`, `password.js`, `logger.js`.
- `src/validators/` – Zod schémy pre vstupy.
- `src/db/` – Drizzle schéma a config.

## Životný cyklus požiadavky (pipeline)
1) **Logovanie**: `morgan('dev')` (len stdout).
2) **Bezpečnostné hlavičky**: `helmet` s CSP (self + inline styles) a HSTS (preload, subdomains).
3) **CORS**: povolený pôvod z `CORS_ORIGIN` (default `http://localhost:5173`), credentials povolené.
4) **Body parsers**: `express.json` a `express.urlencoded` (limit 10 MB), `cookieParser` pre JWT v cookies.
5) **Global validateBody**: rýchly regex-detektor podozrivých payloadov (loguje a vráti 400 pri matches).
6) **Rate limiting**: `apiRateLimiter` na `/api/*` (100 req/15 min v production, 1000 v dev). Špecifické limitery na login a citlivé operácie sa aplikujú v routes.
7) **Routes**: `auth`, `admin`, `contacts`, `emails` (CRM), `email-accounts`, `timesheets`, `companies`, `projects`, `todos`, `time-tracking`, `notes`.
8) **404**: `notFound` middleware nastaví 404 a pošle ďalej ako Error.
9) **Global error handler**: `errorHandler` loguje, zvolí status (`err.statusCode` > `res.statusCode` ≥400 > 500) a formátuje pomocou `formatErrorResponse`. Ak už sú hlavičky poslané, púšťa chybu ďalej.

## Validácia a bezpečnosť
- **Zod validácia**: `validateBody/validateQuery/validateParams` (v `middlewares/security/validateInput.js`) na úrovni routes; nahrádzajú `req.body/query/params` validovanými dátami.
- **Auth**: `authenticate` vytiahne JWT z Bearer header alebo cookie, overí cez `verifyAccessToken`, načíta usera (`auth.service.getUserById`) a uloží do `req.user` + `req.userId`.
- **Role**: `requireRole` / `requireAdmin` / `requireOwnerOrAdmin` (role middleware) na autorizáciu.
- **Rate limiting**: `loginRateLimiter` (default 5 pokusov/15 min, počíta len neúspechy), `sensitiveOperationLimiter` (10 prod / 50 dev za 15 min).
- **Šifrovanie**: `password.encryptPassword` používa AES-256-GCM (kľúč zo `JWT_SECRET` + `ENCRYPTION_SALT`). Heslá v DB sú bcrypt hashované.
- **Audit logy**: `audit.service` loguje login pokusy, zmeny hesla, role, tvorbu userov atď. do DB + konzoly.

## Error handling (kde a ako)
- **Typy chýb**: `AppError` + podtriedy (ValidationError, AuthenticationError, ForbiddenError, NotFoundError, ConflictError, RateLimitError).
- **Formát odpovede**: `formatErrorResponse` vracia `{ success:false, error:{ message, statusCode, details?, stack? } }`. Stack iba v NODE_ENV=development.
- **Použitie**: Kontroléry nemajú lokálne try/catch formatovanie; pri chybe volajú `next(err)`. Auth middleware vracia 401 pri Auth chybách, inak púšťa ďalej do globálneho handlera.

## Doménové moduly – kto koho volá

### Autentifikácia (`routes/auth.routes.js`, `auth.controller.js`, `auth.service.js`)
- **/login**: `loginRateLimiter` → `validateBody(loginSchema)` → controller zavolá `authService.loginWithTempPassword` (porovná temp/permanent heslo, nastaví lastLogin, vygeneruje tokeny) → audit `logLoginAttempt` (success/fail) → nastaví httpOnly cookies + response.
- **/set-password**: `authenticate` → `sensitiveOperationLimiter` → `validateBody(setPasswordSchema)` → `authService.setNewPassword` (bcrypt, zmaže tempPassword) → audit `logPasswordChange`.
- **/logout**, **/session**: vyžadujú `authenticate`; logout vyčistí cookies, session vráti `req.user`.
- **Tokeny**: generované v `utils/jwt.js` (access + refresh); overenie hádže `AuthenticationError` pri expirácii/neplatnosti.

### Admin (`routes/admin.routes.js`, `admin.controller.js`)
- `router.use(authenticate)` + `router.use(requireAdmin)` pre všetky admin-only akcie.
- CRUD nad používateľmi: create (generuje temp heslo + voliteľné linknutie email účtu), get/list, change role, delete. Používa `email-account.service` pri zakladaní účtu, loguje audit udalosti.

### Email účty (`routes/email-account.routes.js`, `email-account.controller.js`, `email-account.service.js`)
- Každá akcia vyžaduje `authenticate`.
- **Create**: `sensitiveOperationLimiter` + Zod schéma → service overí JMAP credentials (`validateJmapCredentials` z `email.service.js`), šifruje heslo (AES-256-GCM), vytvorí účet a many-to-many link do `userEmailAccounts`. Ak účet existuje, vie ho len „nasdieliť“ po overení hesla.
- **Set primary**: pre konkrétneho používateľa; transakčne zruší ostatné `isPrimary` a aktivuje účet.
- **Delete**: odstráni link, a ak nikto iný účet nepoužíva, zmaže aj samotný účet.
- **Get**: vracia účty používateľa; špeciálna funkcia `getEmailAccountWithCredentials` dešifruje heslo na JMAP operácie.

### CRM Emaily (`routes/crm-email.routes.js`, `crm-email.controller.js`, `crm-email.service.js`, `jmap.service.js`)
- Všetky endpointy za `authenticate`.
- **Listing/search**: DB filter + fulltext (subject/body/from), alebo JMAP full-text (`/search-jmap`). Filtrovanie podľa účtu, kontaktu, stavu prečítania.
- **Threads**: `/thread/:threadId` načíta konverzáciu; `/thread/:threadId/read` označí všetky maily v threade.
- **Sync**: `/sync` spustí fetch z JMAP pre daného používateľa/účet.
- **Mark contact read**: `/contact/:contactId/read` označí všetky maily od kontaktu ako prečítané.
- **Reply**: `/reply` cez JMAP; používa dešifrované heslo z email-account service.
- **Unread count**: `/unread-count` agreguje per účet.

### Kontakty (`routes/contact.routes.js`, `contact.controller.js`, `contact.service.js`)
- Všetko za `authenticate`.
- **Get/Discover**: zoznam kontaktov (voliteľný filter `accountId`), discover číta unikátnych odosielateľov z JMAP.
- **Create**: validácia + uloženie, následne auto-sync všetkých emailov od tohto odosielateľa.
- **Update/Delete**: meno/poznámky, prípadne zmazanie; pri delete ostávajú emaily, len sa odpojí contact_id.
- **Link/Unlink company** a **create company from contact** využívajú company service.

### Companies (`routes/company.routes.js`, `company.controller.js`, `company.service.js`, `company-email.service.js`, `company-reminder.service.js`)
- `authenticate` povinné.
- **CRUD firmy**, plus **email threads** pre firmu (agregácia emailov naprieč účtami používateľa).
- **Unread counts** per firma (agreguje emaily podľa kontaktov a účtov).
- **Notes** (vnořené /:companyId/notes) používajú `note.service`.
- **Reminders**: CRUD + summary/endpoints na prehľad (upcoming, counts, summary). Všetko cez `company-reminder.service`.

### Projekty (`routes/project.routes.js`, `project.controller.js`, `project.service.js`)
- `authenticate` povinné.
- CRUD projektov, správa členov projektu (assign/update role/remove), projektové poznámky (vrátane `reminderAt`).

### Todos (`routes/todo.routes.js`, `todo.controller.js`, `todo.service.js`)
- `authenticate`; CRUD + toggle completed.

### Poznámky (`routes/note.routes.js`, `note.controller.js`, `note.service.js`)
- `authenticate`; všeobecné poznámky s filtrom na company/project/todo/contact; CRUD operácie.

### Time Tracking (`routes/time-tracking.routes.js`, `time-tracking.controller.js`, `time-tracking.service.js`)
- `authenticate`; Zod validácia na start/stop/update.
- **Start/Stop**: vytvára/uzatvára bežiaci záznam (oprávnenie viazané na `req.userId`).
- **Bežiace položky**: `/running` (aktuálne pre usera), `/running-all` (všetkých userov – dashboard).
- **Listing/Filters**: všeobecný listing, mesačné výpisy a štatistiky, detail/relations.
- **Generate timesheet**: vytvorí XLSX výstup za mesiac (využíva `exceljs`).

### Timesheets upload (`routes/timesheet.routes.js`, `timesheet.controller.js`, `timesheet.service.js`)
- `authenticate`; Multer s **memory storage** a limit 5 MB, whitelist MIME (PDF, XLSX, XLS). Admin môže nahrávať za iných, inak len za seba. Ukladá súbory do `uploads/timesheets`.

### Admin (už popísané vyššie)

### Audit (`audit.service.js`)
- Jednotné logovanie udalostí do DB + konzoly (tag `[AUDIT]`). Použité v auth flow a user managemente; možno rozšíriť na ďalšie služby.

## Pomocné utility
- `utils/errors.js` – definícia AppError podtried + `formatErrorResponse`.
- `utils/jwt.js` – generovanie/verifikácia access/refresh tokenov.
- `utils/password.js` – bcrypt hash/compare, generovanie temp hesla, AES-256-GCM encrypt/decrypt pre email heslá.
- `utils/logger.js` – farebný stdout logger (info/success/warn/error/debug/audit).

## Request → DB/JMAP tok (v skratke)
`Route` → `Zod middleware` (+ auth/role/rate-limit) → `Controller` → `Service` → `DB (Drizzle)` alebo `JMAP` → späť do controller → JSON response. Chyby: buď AppError (očakávané, neseká stack v prod), alebo neočakávané → global `errorHandler`.

## Dôležité závislosti medzi modulmi
- **authMiddleware** závisí na `utils/jwt` a `auth.service` (pre user fetch). Bez prístupu k DB nie je možné overiť token.
- **crm-email.service** používa `jmap.service` + `email-account.service` (pre dešifrované heslo) + DB schémy.
- **contact.service** pri vytvorení kontaktu volá `crm-email.service` na sync emailov od odosielateľa.
- **company.controller** používa `company-email.service` (agregácia email threadov) a `note.service` / `company-reminder.service`.
- **time-tracking.service** používa Drizzle schémy `timeEntries`, `projects`, `todos`, `companies`, `users` na joiny a agregácie.
- **timesheet.controller**/routes využívajú Multer; uloženie súboru/metadata robí `timesheet.service`.

## Ako rozširovať
- Nový endpoint: pridaj Zod schému do `validators`, zapoj `validateBody/Params/Query`, použi `authenticate`/`requireAdmin` podľa potreby, v controllery volaj service a pri chybe `next(err)`.
- Nová logika: implementuj v `services` (bez Express závislosti), AppError pri očakávaných stavoch.
- Error/response shape je centrálne daný `errorHandler` + `formatErrorResponse` – nechaj ho pracovať.

## Environment a spustenie (stručne)
- Env vars: `PORT`, `CORS_ORIGIN`, `JWT_SECRET`, `JWT_REFRESH_SECRET`, `ENCRYPTION_SALT`, `RATE_LIMIT_*`, DB credentials atď. (pozri `.env.example` ak existuje / README bezpečnostný checklist).
- Skripty: `npm run dev` (nodemon), `npm start`, `npm test` (Jest), drizzle migrácie `db:generate/push/studio`.

Tento README má slúžiť ako rýchla mapa: čo kde je, čo koho volá a kde hľadať validačné/bezpečnostné háky alebo biznis logiku.
