Struktura podle zasad: rozdeleni souboru, lint, testy, prisny TypeScript
Projekt srovnan se zasadami v D:\GitHubRepository\CLAUDE.md bez zmeny chovani.
Struktura: scripts/ (skripty konektoru) -> connectors/, src/scripts ->
src/runtime/scripts; src/index.ts jen startuje, novy src/app.ts s createApp();
routes/dashboard.ts a routes/settings.ts rozdeleny do slozek; openapi.ts
rozdelen na openapi/{index,helpers,components} a paths/* (98 cest overeno
shodnych); ticketStore, automationStore a services jsou fasady nad slozkami
data/tickets, data/automations a data/services/catalog. process.env se cte
jen v config.ts. Web: hooky v hooks/, sdilena ui/Table a ui/ServiceIcon,
surove inputy nahrazeny komponentami, sedm velkych souboru rozdeleno.
Nastroje: eslint (typescript-eslint, react-hooks v7), prettier, editorconfig,
nvmrc, .env.example, vitest; skripty lint, format, test. Lint je cisty bez
jedineho eslint-disable (nove hooky useLatest a useSyncFromSource, odvozeny
stav misto setState v effectu). noUncheckedIndexedAccess v obou tsconfig,
84 mist zuzeno bez non-null operatoru; odhalilo zalohu backoffu fronty pri
nule pokusu a Retry-After NaN pri max 0. Cely kod naformatovan prettierem.
Testy: 8 souboru, 105 testu (prava, viditelnost, podminky a opakovani
v executoru, redaktor tajemstvi, sitove guardy, migrace resitelu, tickety,
health a prihlaseni pres supertest). Testy odhalily dve chyby ve vyhodnoceni
podminek, obe opravene: chybejici castka se porovnavala jako nula a podminka
nad vystupem druheho kroku cetla hodnotu prvniho se stejnym nazvem.
Pojmenovane konstanty misto magickych hodnot, ctx.util.base64 pro skripty
konektoru, README a dokumentace aktualizovany vcetne znamych odchylek.
This commit is contained in:
@@ -2,6 +2,119 @@
|
||||
|
||||
Nejnovejsi nahore.
|
||||
|
||||
## 2026-09-09 - Struktura podle zasad: rozdeleni souboru, lint, testy
|
||||
|
||||
`D:\GitHubRepository\CLAUDE.md` dostal zasady pro vsechny projekty (struktura
|
||||
Node a React, jedno cteni `process.env`, lint a format v repu, testy
|
||||
v `tests/`, soubor nad 500 radku je signal k rozdeleni). Projekt se od nich
|
||||
lisil na nekolika mistech naraz: `index.ts` skladal aplikaci i poslouchal,
|
||||
`routes/dashboard.ts` mel pres tisic radku a `openapi.ts` skoro tri tisice,
|
||||
katalog sluzeb byl jeden soubor, lint ani testy neexistovaly a `process.env`
|
||||
se cetl na sesti mistech. Tahle zmena to srovnava; nic z toho nemeni chovani
|
||||
aplikace, az na dve skryte chyby nize a dve chyby, ktere nasly prvni testy.
|
||||
|
||||
### Co se presunulo
|
||||
|
||||
| Driv | Ted | Proc |
|
||||
| --------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| `scripts/*.js` | `connectors/*.js` | `scripts/` je podle zasad pro pomocne skripty vyvoje, ne pro kod nacitany za behu |
|
||||
| `src/scripts/` | `src/runtime/scripts/` | je to runtime, ktery skripty spousti, patri k fronte a executoru |
|
||||
| `src/index.ts` | `src/index.ts` (jen start) a `src/app.ts` (`createApp()`) | aplikace jde postavit v testu bez portu (supertest) |
|
||||
| `src/routes/dashboard.ts` | `src/routes/dashboard/` (10 souboru po domenach a `shared.ts`) | jeden router = jedna domena, mount v `index.ts` |
|
||||
| `src/routes/settings.ts` | `src/routes/settings/` (jedna entita = jeden soubor) | totez |
|
||||
| `src/openapi.ts` | `src/openapi/{index,helpers,components}.ts` a `paths/*.ts` | popis endpointu lezi u sveho routeru; slozeny dokument ma stejnych 98 cest |
|
||||
| `src/data/ticketStore.ts` | `src/data/tickets/` (model, state, persist, queries, store, intake, trace, stats, seed, remap) | fasada zustava, importy se nemeni |
|
||||
| `src/data/automationStore.ts` | `src/data/automations/` (model, state, persist, store, validation, webhook, runs, seed, seedDemo, remap) | totez |
|
||||
| `src/data/services.ts` | `src/data/services/index.ts` a `catalog/<skupina>.ts` | jeden soubor na skupinu sluzeb, `catalog/index.ts` drzi poradi |
|
||||
| `web/src/lib/use*.ts` | `web/src/hooks/` | hooky maji vlastni slozku, `lib/` jsou ciste funkce |
|
||||
|
||||
`config.scriptsDir` ma vychozi `./connectors`, Dockerfile slozku kopiruje,
|
||||
promenna `SCRIPTS_DIR` se nemeni. `process.env` se ted cte **jen**
|
||||
v `src/config.ts`; pro `<SLUZBA>_BASE_URL` pribylo
|
||||
`config.serviceBaseUrlOverride(variable)`, protoze nazev promenne sklada
|
||||
katalog a vypisovat kazdou sluzbu do konfigurace by znamenalo dve mista.
|
||||
Skripty konektoru dostaly `ctx.util.base64`, `google.send-email` uz nesaha na
|
||||
`Buffer`.
|
||||
|
||||
### Web
|
||||
|
||||
Sdilene prvky: `components/ui/Table.tsx` (ctyri seznamy kreslily tabulku
|
||||
kazdy jinak: `EntityAdmin`, `InvitePanel`, `People`, `AuditView`),
|
||||
`components/ui/ServiceIcon.tsx`, vstupy v `Overview` a `TriggerConfig` z
|
||||
`ui/form` misto vlastnich `<input>`. Rozdelene soubory:
|
||||
`components/dashboard/scripts/{TestPanel,CodeEditor}`,
|
||||
`dashboard/settings/{FeaturesAdmin,AuditView,types}`, `flow/{SampleBody,ModelTree,WebhookCalls}`,
|
||||
`lib/exampleBody.ts`, `components/dashboard/EntityForm.tsx`, `widgets/EditBar.tsx`.
|
||||
Nad 500 radku zustavaji `AutomationDetail`, `TicketDetail`, `MappingEditor`
|
||||
a na serveru `data/services/catalog/ticket.ts`; duvody jsou
|
||||
v [03-architektura-a-mapa-kodu.md](03-architektura-a-mapa-kodu.md).
|
||||
|
||||
Magicka cisla na obou stranach dostala pojmenovane konstanty s komentarem
|
||||
(`JSON_BODY_LIMIT`, `STATIC_MAX_AGE_SEC`, `MAX_PAGE_LIMIT`, `KEEP_DAYS`,
|
||||
`WEBHOOK_TOKEN_BYTES`, `MD_UP`, ...), hodnoty se nezmenily.
|
||||
|
||||
### Nastroje
|
||||
|
||||
`eslint.config.js` (typescript-eslint, `react-hooks` v7 pro web, `connectors/`
|
||||
jako obycejny JS bez globalu, zadne `any`, zadny prazdny `catch`),
|
||||
`.prettierrc`, `.prettierignore`, `.editorconfig`, `.nvmrc` (20),
|
||||
`.env.example` se vsemi promennymi a komentarem, `vitest.config.ts`. Skripty
|
||||
`npm run lint`, `format`, `format:check`, `test`, `test:watch` vedle
|
||||
`typecheck`.
|
||||
|
||||
**Lint je cisty na celem repu bez jedineho `eslint-disable`.** Pravidla hooku
|
||||
Reactu v7 hlasi zapis do refu pri vykresleni, `setState` v effectu
|
||||
a komponentu vytvorenou pri vykresleni. Reseni je vzdy zmena navrhu, ne
|
||||
vyjimka: `hooks/useLatest.ts` (ref s posledni hodnotou, zapis v layout
|
||||
effectu), `hooks/useSyncFromSource.ts` (prevzeti dat ze zdroje pri vykresleni
|
||||
misto `useEffect`), odvozeny stav misto kopie ve stavu, dialogy jako vlastni
|
||||
komponenty, ktere se pri zavreni odmontuji (stav se resetuje sam),
|
||||
`useMediaQuery` pres `useSyncExternalStore`, `ServiceIcon` pres
|
||||
`createElement`.
|
||||
|
||||
### Prisnejsi TypeScript
|
||||
|
||||
Oba `tsconfig` maji `noUncheckedIndexedAccess`. Opraveno 55 mist na serveru
|
||||
a 29 na webu, vzdy osetrenim `undefined`, nikde `!`. Dve z nich byly skutecne
|
||||
chyby:
|
||||
|
||||
- `BACKOFF_MS[attempts - 1]` v `src/runtime/queue.ts` je pri `attempts = 0`
|
||||
`undefined` a `new Date(NaN)` by beh naplanoval na nikdy; cteni ma zalohu
|
||||
`MAX_BACKOFF_MS`.
|
||||
- `rateLimit` s `max: 0` posilal `Retry-After: NaN`; ted aspon 1 sekunda.
|
||||
|
||||
### Testy
|
||||
|
||||
`tests/` zrcadli `src/`: 8 souboru, 105 testu, vsechny prochazi.
|
||||
`tests/setup.ts` nastavi rezim pameti (`DATA_DIR=''`, `DATABASE_URL=''`,
|
||||
pevny `SECRETS_KEY` a `JWT_SECRET`, `SEED_DEMO=0`) a umlci `console.info`
|
||||
a `console.warn`; test migrace si bere docasny `DATA_DIR`.
|
||||
|
||||
| Soubor | Co hlida |
|
||||
| ----------------------------------- | ------------------------------------------------------------------------ |
|
||||
| `data/access.test.ts` | `accessFor`, `visibilityFor`, `resolveScope`: pohledy, strop viditelnosti, cizi firma je 404 |
|
||||
| `data/permissions.test.ts` | `permissionsOf` za firmu, `syncSystemRoles` |
|
||||
| `data/tickets.test.ts` | `intakeEvent` (externi ID za firmu), `listTickets` s povinnym filtrem, `updateTicketStatus` |
|
||||
| `data/migratePeople.test.ts` | prevod `ppl_` na ucty vcetne ticketu, skupin a stromu; zapis na disk |
|
||||
| `net/guard.test.ts` | `urlProblem` (privatni rozsahy), `readBodyLimited`, `readJsonLimited` |
|
||||
| `routes/health.test.ts` | `createApp()` pres supertest: health, 404 jako JSON, 401, prihlaseni, `/access` za firmu |
|
||||
| `runtime/executor.test.ts` | podminky (retezce, cisla, data, seznamy, `all`/`any`), stara podoba, stropy `MAX_STEPS`, `MAX_ACTIONS`, `MAX_LOOP_ITEMS`, vystupy, `retryable` |
|
||||
| `runtime/scripts/util.test.ts` | `createRedactor` ve ctyrech tvarech, `parseBool`, `parseNumber`, `pick`, `truncate` |
|
||||
|
||||
Prvni testy executoru nasly dve chyby v podminkach, obe opravene: prazdna
|
||||
hodnota se pri `gt`/`lt` porovnavala jako nula (`Number('')` je `0`) a hole
|
||||
jmeno vystupu melo prednost pred `krok.jmeno`, takze podminka nad druhym
|
||||
krokem se stejnym vystupem cetla hodnotu z prvniho. Podrobne
|
||||
v [20-fronta-a-runtime.md](20-fronta-a-runtime.md).
|
||||
|
||||
### Znamy stav proti zasadam
|
||||
|
||||
Jeden `package.json` pro server i web (workspaces az bude mit kazda strana
|
||||
vlastni build), logovani `console.*` s prefixem modulu misto strukturovaneho
|
||||
loggeru, zadny soubor CI. Prettier prosel celym kodem (`npm run format`,
|
||||
se svolenim); markdown je z formatovani vyjmuty (`.prettierignore`), protoze
|
||||
dokumentace ma vlastni styl tabulek. Zapsano v [01-prehled-a-stav.md](01-prehled-a-stav.md).
|
||||
|
||||
## 2026-09-09 - Incident jde otevrit a posunout do dalsiho stavu
|
||||
|
||||
Seznam incidentu ukazoval jen titulek, sluzbu a casy. Server pritom uz posilal
|
||||
|
||||
Reference in New Issue
Block a user