Files
crm-server/README.md
richardtekula fa7129a5b4 Clean up: Remove documentation files
- Remove DOKUMENTACIA.md
- Remove SECURITY_CHECK.md
- Clean up README.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 10:27:34 +01:00

140 lines
12 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 10MB), `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 5MB, 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.