Nahrazeni sablony kompletnim webem a klientskym portalem
Web a portal Automia v jednom containeru. Express obsluhuje API i zbuildovanou React aplikaci z dist/public. Obsah: - verejny web: homepage, sluzby, o nas, kontakt, 404 - prihlaseni pres JWT, demo ucty - portal: prehled s grafem, tickety, incidenty, automatizace, konektory - builder automatizaci: strom akci, vetveni podminkou - katalog 25 konektoru v 8 kategoriich - webhook s registrovanou adresou, token generuje server - zivy dashboard pres SSE vcetne simulace provozu - Swagger UI na /docs a OpenAPI na /openapi.json Soulad s AGENTS.md: - ROOT_PATH z prostredi, prefix proxy nikde nehardcodovan - mount na koren i na prefix, funguje s handle_path i bez nej - base tag a window.__BASE_PATH__ vkladane do index.html za behu - OpenAPI servers obsahuje prefix, Try it out vola spravnou adresu - povinne /health a /docs, port 3000, naslouchani na 0.0.0.0 - secrets jen z environment variables, nikdy v logu Dokumentace ve slozce documentation/.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
# 04 - API
|
||||
|
||||
Interaktivni dokumentace je na `/apps/<app-id>/docs`. Tenhle soubor popisuje to,
|
||||
co ze Swaggeru neni videt.
|
||||
|
||||
## Endpointy
|
||||
|
||||
Verejne:
|
||||
|
||||
| Metoda | Cesta | Popis |
|
||||
| ------ | ------------------- | --------------------------------------- |
|
||||
| GET | `/health` | health check |
|
||||
| GET | `/docs` | Swagger UI |
|
||||
| GET | `/openapi.json` | OpenAPI definice |
|
||||
| POST | `/api/auth/login` | prihlaseni, vraci JWT |
|
||||
| POST | `/api/contact` | poptavka z webu |
|
||||
| POST | `/webhook/:token` | prijem dat do automatizace |
|
||||
|
||||
Vyzaduji `Authorization: Bearer <token>`:
|
||||
|
||||
| Metoda | Cesta |
|
||||
| ------ | --------------------------------------------------- |
|
||||
| GET | `/api/auth/me` |
|
||||
| POST | `/api/auth/logout` |
|
||||
| GET | `/api/dashboard/summary` |
|
||||
| GET | `/api/dashboard/tickets` |
|
||||
| GET | `/api/dashboard/incidents` |
|
||||
| GET | `/api/dashboard/connectors` |
|
||||
| GET | `/api/dashboard/stream` |
|
||||
| GET | `/api/dashboard/automations` |
|
||||
| POST | `/api/dashboard/automations` |
|
||||
| GET | `/api/dashboard/automations/:id` |
|
||||
| PUT | `/api/dashboard/automations/:id` |
|
||||
| DELETE | `/api/dashboard/automations/:id` |
|
||||
| POST | `/api/dashboard/automations/:id/webhook/regenerate` |
|
||||
| POST | `/api/simulate` |
|
||||
|
||||
## Format chyb
|
||||
|
||||
Jednotny pro cele API:
|
||||
|
||||
```json
|
||||
{ "error": "validation_error", "message": "Zadejte platny e-mail." }
|
||||
```
|
||||
|
||||
| HTTP | `error` | Kdy |
|
||||
| ---- | --------------------- | --------------------------------------- |
|
||||
| 400 | `validation_error` | vstup neprosel schematem |
|
||||
| 401 | `unauthorized` | chybi nebo neplatny token |
|
||||
| 401 | `invalid_credentials` | spatny e-mail nebo heslo |
|
||||
| 403 | `forbidden` | nedostatecna role |
|
||||
| 404 | `not_found` | zaznam nebo endpoint neexistuje |
|
||||
| 409 | ruzne | operace nedava v danem stavu smysl |
|
||||
| 500 | `internal_error` | neodchycena chyba, detail jen mimo produkci |
|
||||
|
||||
`message` je vzdy cesky a je urcena k zobrazeni uzivateli.
|
||||
|
||||
## Autentizace
|
||||
|
||||
Hesla se hashuji bcryptem, plaintext se nikde neuklada. Login vraci JWT
|
||||
podepsany `JWT_SECRET` s platnosti `JWT_EXPIRES_IN`.
|
||||
|
||||
Spatne heslo i neexistujici e-mail vraci stejnou odpoved, aby se neprozradilo,
|
||||
ktere ucty existuji. Pokus se loguje bez hesla.
|
||||
|
||||
Token si drzi klient v `localStorage`. Pro produkci je cilovy stav `httpOnly`
|
||||
cookie se `Secure` a `SameSite` plus CSRF token.
|
||||
|
||||
## Zivy stream
|
||||
|
||||
`GET /api/dashboard/stream` je Server-Sent Events. Po pripojeni posle potvrzeni
|
||||
a poslednich par udalosti, pak uz jen nove. Kazdych 25 sekund jde komentarovy
|
||||
radek, aby spojeni neuspalo proxy.
|
||||
|
||||
Typy udalosti: `ticket.created`, `ticket.updated`, `ticket.resolved`,
|
||||
`incident.started`, `incident.updated`, `incident.resolved`,
|
||||
`automation.created`, `automation.updated`, `automation.deleted`,
|
||||
`automation.run`, `webhook.received`.
|
||||
|
||||
Klient se pripojuje pres fetch s hlavickou `Authorization`, ne pres EventSource.
|
||||
Duvod je v [03-architektura-a-mapa-kodu.md](03-architektura-a-mapa-kodu.md).
|
||||
|
||||
## Webhook
|
||||
|
||||
Verejny endpoint bez prihlaseni. Autorizuje neuhodnutelny token v adrese,
|
||||
32 znaku z `randomBytes(24)` v base64url.
|
||||
|
||||
Token generuje **vyhradne server**. Hodnota `webhookToken` poslana klientem se
|
||||
ignoruje, jinak by si sel nastavit predvidatelnou adresu.
|
||||
|
||||
| Situace | Odpoved |
|
||||
| ----------------------------------- | ------- |
|
||||
| vse v poradku | 202 |
|
||||
| neznamy token | 404 |
|
||||
| automatizace je pozastavena | 409 |
|
||||
| chybi povinny parametr, spatny typ | 400 |
|
||||
|
||||
Parametry navic se neodmitaji, jen loguji. Odesilatele bezne posilaji i vlastni
|
||||
data a odmitat je by rozbijelo integrace.
|
||||
|
||||
```bash
|
||||
curl -X POST https://services.csbot.cz/apps/<app-id>/webhook/<token> \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"customer":"Nordis","score":18}'
|
||||
```
|
||||
|
||||
Prototyp pozadavek prijme, zvaliduje a zapocita do metrik, ale strom akci
|
||||
nevykona - runtime neexistuje.
|
||||
|
||||
## Simulace
|
||||
|
||||
`POST /api/simulate` vyvola provozni udalost pro nahled ziveho dashboardu.
|
||||
Zamerne meni skutecna data, ne jen posila falesnou notifikaci.
|
||||
|
||||
Akce: `ticket.created`, `ticket.resolved`, `incident.started`,
|
||||
`incident.resolved`, `automation.run`.
|
||||
|
||||
Nevyplnena pole server doplni ukazkovou hodnotou. U akci s "resolved" se bez
|
||||
zadaneho id pouzije prvni nevyrizeny zaznam.
|
||||
|
||||
## Pri pridani endpointu
|
||||
|
||||
Soucasne aktualizovat `src/openapi.ts` a tenhle soubor. Swagger musi odpovidat
|
||||
skutecnemu chovani aplikace, jinak je horsi nez zadny.
|
||||
Reference in New Issue
Block a user