Tmavý režim
Architektura
Přehled systému
Atrea User API je centralizovaný backend pro správu uživatelů. Žádná z aplikací v ekosystému si nespravuje oprávnění sama — vše jde přes tento servis.
┌──────────────────────────────────────────────────────────────────┐
│ Klientské aplikace │
│ (web frontendy, mobilní apps, admin panely) │
└──────────┬───────────────────────────────────────────────────────┘
│ JWT Bearer token (Zitadel / Microsoft / Google)
▼
┌──────────────────────────────────────────────────────────────────┐
│ Atrea User API :3001 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ /api/check │ │ /api/users │ │ /api/profile/me │ │
│ │ /api/check │ │ /api/roles │ │ /api/profile/me/... │ │
│ │ /bulk │ │ /api/perms │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └────────────┬────────────┘ │
│ │ │ │ │
│ ┌──────▼────────────────▼───────────────────────▼────────────┐ │
│ │ Services vrstva │ │
│ │ CheckService · UserService · ProfileService · ... │ │
│ └──────────────────────────┬──────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼──────────────────────────────────┐ │
│ │ TypeORM (PostgreSQL 16) │ │
│ └──────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│
│ Service-to-service (x-internal-api-key)
▼
┌──────────────────────────────────────────────────────────────────┐
│ Backend aplikace Atrea │
│ (volají /check, /internal/notifications bez JWT tokenu) │
└──────────────────────────────────────────────────────────────────┘Tech Stack
Backend
| Vrstva | Technologie | Verze |
|---|---|---|
| Runtime | Node.js Alpine | 20 |
| Jazyk | TypeScript | 5.7 |
| HTTP Framework | Express | 4.21 |
| ORM | TypeORM | 0.3 |
| Databáze | PostgreSQL | 16 |
| Konfigurace | config (YAML) | 3.3 |
| Logování | Winston | 3.17 |
Autentizace & Bezpečnost
| Komponenta | Technologie |
|---|---|
| JWT verifikace | jsonwebtoken + jwk-to-pem |
| OIDC provider | Zitadel (self-hosted) |
| Multi-provider | Microsoft OAuth, Google OAuth, Amotion |
| Service-to-service | x-internal-api-key header |
Výkon
| Komponenta | Technologie | Detail |
|---|---|---|
| Permission cache | lru-cache | TTL 30 s, max 5 000 záznamů |
| HTTP logging | morgan | JSON structured |
| Validation | express-validator | Request validace |
Notifikace
| Komponenta | Technologie |
|---|---|
| nodemailer + DKIM | |
| Web Push | web-push (VAPID) |
| Template engine | Mustache-style (custom) |
Request Flow
Chráněný endpoint (JWT)
Klient → POST /api/users/:email
│
├─ authorizationMiddleware()
│ ├─ Načtení JWKS klíčů (cache)
│ ├─ Verifikace JWT podpisu
│ ├─ Extrakce emailu z claims
│ └─ req.token = { email, orgId, ... }
│
├─ loadSuperAdminFlag()
│ └─ SELECT FROM super_admins WHERE email = ?
│ req.isSuperAdmin = true/false
│
├─ requireAppAdmin() nebo requireSuperAdmin()
│ └─ 403 pokud podmínka nesplněna
│
└─ Route handler → Service → TypeORM → PostgreSQL
│
← Response JSONPermission check (bez JWT)
Backend app → POST /api/check
│
├─ (volitelně: x-internal-api-key validation)
│
└─ CheckService.check(email, app, permission)
│
├─ Zkontroluj LRU cache (TTL 30 s)
│ └─ HIT → vrátit { allowed }
│
├─ MISS → databázový dotaz:
│ ├─ Je uživatel aktivní? (user.active)
│ ├─ Je superadmin? (super_admins)
│ ├─ Resource-level override? (user_resource_permissions)
│ └─ Role permissions? (user_app_roles → role_permissions)
│
└─ Cache výsledek → vrátit { allowed }Databázová vrstva
TypeORM je nakonfigurován na synchronize: false v produkci. Schema je definováno v sql/init.sql a entity v src/entities/. Viz Databázové schema pro kompletní přehled.
Adresářová struktura
src/
├── index.ts # Bootstrap: DB, JWT, Express, Swagger
├── middleware/
│ ├── authorization.ts # JWT middleware stack
│ ├── JWTService.ts # Multi-provider JWKS manager
│ └── internalAuth.ts # x-internal-api-key validace
├── routes/
│ ├── router.ts # Hlavní agregátor routerů
│ ├── checkRouter.ts # /check — bez JWT
│ ├── userRouter.ts # /users — CRUD + role assignment
│ ├── profileRouter.ts # /profile — profil, preference, push
│ ├── applicationRouter.ts # /applications — superadmin only
│ ├── permissionRouter.ts # /applications/:code/permissions
│ ├── roleRouter.ts # /applications/:code/roles
│ ├── notificationRouter.ts # /internal/notifications
│ ├── adminNotificationRouter.ts # /admin/notifications
│ ├── adminBrandRouter.ts # /admin/brands
│ ├── adminDashboardRouter.ts # /admin/dashboard
│ └── zitadelRouter.ts # /zitadel — webhooks, OIDC, org mgmt
├── services/ # Business logika (18 servisů)
├── entities/ # TypeORM entity (17 tabulek)
└── utils/
├── ApiResponse.ts # Standardizovaný response wrapper
├── ApiException.ts # Custom exception s HTTP kódem
├── ApiExceptionCode.ts # Enum error kódů
├── data-source.ts # TypeORM DataSource
├── serverConfig.ts # Typovaná konfigurace
└── logger.ts # Winston loggerKlíčové architektonické vzory
1. Email jako primární identifikátor
Email je PK tabulky users a cizí klíč ve všech relacích. Eliminuje nutnost UUID mapping mezi JWT claims a DB.
2. Lazy vytváření entit
UserProfile, UserAppPreference a User záznamy se vytvářejí až při prvním přístupu (upsert pattern). Admin nemusí předem zakládat uživatele.
3. Tříúrovňová admin hierarchie
SuperAdmin (global)
└── AppAdmin (per-app)
└── User (jen co role + overrides povolí)4. Resource-level overrides
Pro granulární kontrolu (sdílení konkrétního projektu) bez nutnosti vytvářet novou roli:
user_resource_permissions (email, app, resourceType, resourceId, permission, granted)5. Stateless API s cacheovanými oprávněními
API je stateless — žádný session state. LRU cache v paměti zkracuje latenci permission checků na minimum. Cache se automaticky expiruje po 30 s.
6. Multi-provider JWKS
JWKS klíče se načítají ze všech providerů při startu a refreshují každých 60 minut. Verifikace probíhá vyzkoušením všech providerů, dokud jeden neuspěje.