ea9387bea9ec558ec376968698220e00a4797858
15
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ea9387bea9 |
Seed z repozitare, zatezove testy, worker bez spanku, dialogy bez rozmazani
Nastaveni prezije nasazeni: seed/records.json se pri prazdnem ulozisti nacte misto ukazkovych dat (zive uloziste se nikdy neprepisuje). Soubor nese soucasny stav produkce (firmy s provozovatelem, role, typ ticketu, akce, widgety, skupiny, rozlozeni). Novy GET /api/admin/export a skript npm run seed:export pro dalsi exporty, Dockerfile slozku kopiruje. Vykonnostni testy (npm run test:perf) nad 200 firmami a 10 000 tickety a zatezovy skript (npm run load) proti bezici instanci vcetne davky udalosti na webhook. Mereni odhalilo strop workeru: po obsazeni vsech mist spal sekundu, takze fronta odbavila nejvys 4 behy za sekundu. Ted ceka na prvni dokonceny beh: 500 udalosti za 1,3 s (395 behu/s). Strop posluchacu streamu zvednut na 2 000. Dialogy: prekryv modalu a menu v portalu bez backdrop-blur, tecka Zive pulzuje jen pri navazovani spojeni - rozmazani cele obrazovky pod trvalou animaci sekalo video vedle portalu. Bublina udalosti drzi 0,5 s. Dokumentace 14, 19, 20, 22, 04, 01, 03, 15 a 99 aktualizovana. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
22dda2d139 |
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.
|
||
|
|
104ae36783 |
Revize projektu: prava, vykon, runtime, portal a ARES
Prava a bezpecnost: spravce firmy uz nemuze nastavit priznak spravce platformy ani clenstvi v cizi firme; pozvanky, konektory a automatizace kontroluji sve pravo; cizi firma v query je 404; zivy stream posila udalosti jen firmam, kterych se tykaji; akce nad ticketem maji kontrolu prava za firmu ticketu a strop viditelnosti; tokeny se nelogujou; limit pokusu na prihlaseni, kontakt a pozvanky; bezpecnostni hlavicky; zachyceni chyb v async handlerech; timing-safe porovnani tokenu. Vykon: audit neskenuje celou kolekci pri kazdem zapisu a konecne maze firemni zaznamy; ticket se uklada jednou misto trikrat; zapisy do Postgresu jsou serializovane podle ID; prava se pocitaji jednou na request; widgety nacitaji tickety jednou; strankovani seznamu; worker je pool misto kol; na webu udalost ze streamu neodmontuje stranku, dotazy maji spolecny debounce a cache, ciselniky drzi typovany sklad. Runtime: opakuji se jen chyby oznacene retryable; smycka nenarazi na strop 50 kroku (novy strop 1000 akci); podminka nad datem funguje; vystup MCP nastroje neprepisuje spoustec; sandbox skriptu firmy nejde opustit; MCP session id se drzi mezi volanimi; incident z kroku patri firme; jedno rozhodnuti o rezimu uloziste; snapshot neprepise soubor po chybe cteni. Refaktory: sdilene typy API v src/shared (web nic nekopiruje, osm rozjetych tvaru sjednoceno); spolecny modul net/guard pro volani ven; formularova vrstva ui/form; rozdeleni Connectors a FlowCanvas; jeden helper pro firmu z query, validaci a CRUD udalosti; pomucky ctx.util pro skripty konektoru; i18n verejneho webu vcetne anglictiny. Nova funkce: zalozeni firmy z registru ARES v Nastaveni (IC nebo nazev, dotazeni IC, DIC, sidla a pravni formy, vyber soucasnych statutarnich zastupcu a prokury, ucty spravce firmy s nahradnim e-mailem IC-poradi@placeholder.cz). Dokumentace: zaznam v 99-zmeny.md a aktualizace 15 dalsich dokumentu. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
f7ad429b3a |
Nazev znacky uz neni v kodu natvrdo
Server mel "Automia" napsanou primo v titulku Swaggeru a v OpenAPI - zbytek po prejmenovani, ktere probehlo jen na klientovi. Prejmenovat produkt tedy znamenalo hledat retezec po souborech. Dve promenne, a je to zamer: - server cte BRAND_NAME za behu, vychozi WorkNuke - klient cte VITE_BRAND_NAME pri buildu, vychozi tataz Klient je staticky soubor, takze runtime promenne containeru do prohlizece nedosahnou - proto se u nej dosazuje pri buildu. Obe maji tutéž vychozi hodnotu, takze bez nastaveni cehokoliv sedi. Zbytek firemnich udaju (claim, kontakty, adresa) zustava v brand.ts. Do promennych to nepatri, meni se to jednou za rok a env by z toho udelalo deset promennych, ktere nikdo nenastavi. Co se timhle nemeni: firma Automia v ukazkovych datech. Pozvanka ukazuje jmeno firmy, do ktere zve, a ta se v seedu jmenuje Automia - neni to zbytek po prejmenovani, je to zaznam zakaznika. Overeno: s BRAND_NAME=ZkouskaZnacky ma OpenAPI titulek "ZkouskaZnacky - portal a API" a Swagger "ZkouskaZnacky API". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
a771834e57 |
Realne sluzby, OpenAI, odesilani e-mailu a helpdesk
Katalog srovnany s tim, co opravdu bezi na services.csbot.cz/apps: trinact sluzeb dostalo pristupove udaje a levne cteci overeni, opravena appId, ktera nikam nevedla (ppl, microsoft365, transcription), a GA4, Search Console, Google Ads i Sklik ted stoji na aplikaci analytics, kazda s vlastnimi udaji. Nove sluzby SAP Business One, Google Workspace a Meta Ads. K tomu 23 skriptu, ktere s nimi opravdu neco delaji. OpenAI jako prvni sluzba, ktera nebezi u nas: Service.baseUrl s absolutni adresou, prepis pres <SLUZBA>_BASE_URL nebo adresu u konektoru, predpona hlavicky u pole udaju (uzivatel vlepi holy klic, Bearer dopise runtime). Dotaz na model, nahrani souboru, otazka nad souborem, prepis zvuku. Skript umi odeslat soubor pres ctx.http.postForm (multipart, obsah Base64). Sluzba E-mail pres SMTP. Neni to skript, ale vnitrni krok - SMTP neni HTTP. Konektor nese schranku firmy, krok ma HTML telo, ve kterem se dosazene hodnoty escapuji (znacky autora sablony jsou zamer, ostre zavorky od zakaznika ne). Overeni konektoru se prihlasi na server a nic neodesle. Helpdesk: Ticket.helpdeskSourceId drzi firmu, ktera pozadavek poslala, vlastnikem zustava ta, ktera ho resi - jinak by ho resitel nemel ve sve fronte. Komu pozadavek pripadne, urcuje Tenant.helpdeskProviderId. Zadavatel vidi jen svoje pozadavky a smi k nim pripsat komentar. Opravy v portalu: - hlasky o ulozisti a odchozi IP vidi jen spravce platformy - typ ticketu se v automatizaci vybira ze seznamu firmy, nebo dosadi z dat - stav ticketu je otevreny naseptavac, ne ciselnik - ticket jde zalozit rucne, zakaznik u nej neni povinny - kanal se prejmenoval a parametry u webhooku jsou oznacene jako nepovinne - srovnane markdown tabulky v cele dokumentaci Co z teto davky jeste neni: prepinac firmy je porad jen stav uvnitr stranky Prehled, takze se prepnuti neprojevi v Lidech ani jinde. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
4545de8076 |
Odchozi IP adresa portalu
Kdyz cizi sluzba odmitne pristup, prvni otazka je, z jake adresy se vlastne vola. Z containeru to videt neni, vidi to az protistrana, takze se zepta echo sluzby podle EGRESS_IP_URL a vysledek se drzi v pameti po EGRESS_IP_TTL_MS. Prazdna EGRESS_IP_URL funkci vypne, prepsat ji jde na vlastni echo pod svou domenou. Adresa je natvrdo na strance Konektory a u kazdeho odmitnuteho overeni v logu. Pripojuje se jen u 401 a 403 - jinde nema co rict a nestoji za volani ven. Neni to tajemstvi: kazda volana sluzba tuhle adresu stejne vidi. Endpoint egress-ip je registrovany pred GET /:id, jinak by ho router vzal jako id konektoru. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ef3080d3f6 |
Nastaveni prezije nasazeni, ukazkova data uz se nevraci
Bez databaze lezi data uvnitr containeru, takze redeploy je smaze a seed je nasype znovu. Dokud nebude Postgres, resi se to trema vecmi: Ukazkova data jen se SEED_DEMO=1. Automatizace, tickety a incidenty se uz po kazdem nasazeni nevraci. Konfigurace se nasypava dal, bez ni je portal nepouzitelny. Token webhooku z WEBHOOK_TOKEN_TEST. Driv se pri kazdem nasazeni vygeneroval novy, takze odesilatel musel prepisovat adresu ve svem kodu. Ted je token v promenne aplikace: neni v gitu a adresa se nemeni. Automatizace, ktera na instanci opravdu bezi, je v seedu. Je to provizorium, ne cil - az data prezijou nasazeni, patri zpatky do dat. Dal: - `ticket/upsert` umi vsechna pole ticketu: zakaznik, kanal, odkaz na zdroj, priorita, stitky, resitel, skupina a vlastni pole typu jako JSON. Zakaznik a kanal se vyplnuji jen pri zalozeni, aby pozdejsi udalost s prazdnym jmenem neprepsala, co uz tam je. - Kroky ve strome jdou sbalit, vychozi je sbaleno. Sbaleny krok ukazuje, co ma vyplneno, ne popis operace. - Seskupovani widgetu podle faze a dva nove widgety: tickety podle stavu a podle faze za tento mesic, obojí s proklikem na vyfiltrovany seznam. - Faze se ukazuje jako stav. Driv byl videt jen nas ctyrprvkovy ciselnik, coz u ticketu z cizi aplikace nedava smysl. Zivotni cyklus zustava vedle jako drobny text, protoze se z nej pocitaji statistiky. Overeno 18 kontrolami proti bezicimu serveru. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
a57eca123e |
Fronta a worker: webhook odpovi hned, praci udelaji workeri
Webhook uz nic nevykonava v requestu. Zapise udalost do fronty a odpovi 202 do jednotek milisekund; strom vykona worker na pozadi. Za konektory nerucime, takze cekat na cizi sluzbu v requestu znamena ztracet udalosti pri timeoutu. Fronta ma opakovani s rostouci prodlevou (30 s, 2 min, 10 min, hodina), spravedlive poradi po firmach (jedna firma s tisicem udalosti nezablokuje ostatni), navrat zaseknutych behu po restartu a uklid hotovych. Marna chyba se neopakuje - chybejici skript za minutu existovat nezacne. Tri druhy spoustecu: push (webhook), vnitrni udalost (vznik a zmena ticketu) a pull, tedy pravidelne dotazovani u sluzeb bez webhooku (posta, zpravy). Planovac jen rekne "je cas", samotny dotaz je prvni krok stromu, takze ma zaznam v logu a opakuje se pri chybe jako cokoliv jineho. Kontrakt tela webhooku: kazdy parametr ma cestu (data.order.id, errors.0.message), takze jde napojit i odesilatel s vnorenym modelem. U adresy je metoda, ukazka tela a kopiruje se cela adresa vcetne domeny. Vnitrni kroky, ktere sahaji do naseho uloziste: ticket/upsert (zaloz nebo dopln podle externiho ID), assign-least-busy, assign-by-external, set-type, set-stage, add-tags, set-status, incident/create, flow/pause a flow/log. Faze ticketu jako treti osa vedle stavu a stitku. Stav je zivotni cyklus a pocitaji se z nej statistiky, faze je workflow daneho typu a muze byt jen jedna, takze se na ni da spolehnout v podmince. ID z cizich aplikaci u resitele: voicebot posle voicebotId a ticket skonci u toho, komu patri. Vazba je na jednom miste, ne v kazde automatizaci. Kazda chyba zaklada incident se dvema urovnemi: impact cte klient a je srozumitelny, detail cte admin a je v nem cely beh, ktery krok selhal, cele hlaseni a data na vstupu. Detail vidi jen spravce platformy. Ochrana proti smycce: automatizace navazana na zmenu ticketu ticket meni, cimz se spousti znovu - pri vyvoji to server polozilo. Resi to oznaceni behu pres AsyncLocalStorage a strop peti behu na jeden ticket za minutu. Upozorneni pri prideleni prace vcetne cisla u zalozky Tickety. Zivy dashboard: dlazdice nad nasimi daty na udalost, data z konektoru podle ttlSec s moznosti vynutit nacteni znovu. Opraveno: path a intervalSec u spoustece se pri ulozeni zahazovaly; nad seznamem neslo pouzit contains, takze na stitky neslo postavit podminku; novejsi vystup kroku ted prekryje starsi misto hlaseni konfliktu. Overeno dvema scenari proti bezicimu serveru, 34 kontrol: firma se skladem, expedici a IT, a hovory z voicebota (callSid do externiho ID, status do faze, prirazeni podle voicebotId, tri zpravy = jeden ticket se tremi udalostmi). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
6e3d0640ff |
Soubor jako uloziste, kdyz neni databaze
Mockup se k databazi nedostane, takze pribyl treti rezim: JSON soubor. Prezije restart procesu i containeru, ale ne redeploy - filesystem containeru je docasny. Je to mezistupen, ne nahrada databaze, a tak je to i napsane v portalu. | Rezim | Kdy | Restart | Redeploy | | -------- | --------------------------------- | ------- | -------- | | postgres | DATABASE_URL i SECRETS_KEY | prezije | prezije | | file | neni DB, ale je DATA_DIR | prezije | ne | | memory | ani jedno, nebo nejde zapsat | ne | ne | Rozhodnuti zustava na jednom miste (src/data/connectorStore.ts). Pridano: - src/data/snapshot.ts: atomicky zapis (.tmp a prejmenovani), slucovani zapisu a dokonceni rozepsaneho zapisu pri SIGTERM. Bez atomickeho zapisu by pad uprostred nechal polovicni JSON, ktery se pri startu nenacte. Rozbity soubor se prejmenuje na .broken a jede se dal - aplikace, ktera nenastartuje, je pro AppFactory nefunkcni sluzba - src/data/connectors/local.ts: jeden kod pro pamet i soubor, lisi se jen tim, kam se zapisuje. Nahrazuje memory.ts, dve implementace by se casem rozesly - klic k sifrovani se mimo databazi vygeneruje do DATA_DIR/secrets.key s pravy 0600, takze sifrovani funguje bez nastaveni. Chrani to proti nahodnemu precteni JSONu, ne proti pristupu k disku - klic lezi vedle dat a je to tak napsane i v portalu. U databaze se negeneruje vubec: kdo ma zalohu tabulky, ma i klic ze stejneho stroje - DATA_DIR v konfiguraci, data/ v .gitignore a .dockerignore - hlaska v portalu rozlisuje tri nasledky: pamet, soubor a databaze Overeno bez databaze: konektor s vyplnenymi udaji prezil restart, v JSONu jsou hodnoty sifrovane a plaintext v nem neni. Pote s databazi: rezim postgres funguje dal a klic vedle dat se nevygeneroval. Kontejner i data/ po overeni smazany. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
78e7f99d60 |
Konektory do Postgresu, pristupove udaje sifrovane
Pristupove udaje konektoru se ukladaji do databaze a prezijou restart. Popis v documentation/14-databaze.md. Databaze je volitelna a rezimy jsou oddelene: - postgres kdyz je DATABASE_URL i SECRETS_KEY - memory jinak, tedy pri nasazenem mockupu a lokalnim vyvoji bez DB Rozhodnuti je jen na jednom miste (src/data/connectorStore.ts). Nikde jinde se nezjistuje, jestli databaze je - kdyby se to rozlezlo po kodu, jedno misto by se zapomnelo a chovalo by se pak jinak nez zbytek. Chybejici databaze nesmi shodit start: container, ktery nenastartuje, je pro AppFactory nefunkcni sluzba. Misto toho se do logu napise proc a portal to ukaze na strance Konektory. Stejne tak kdyz migrace selzou - psat do rozbiteho schematu je horsi nez neukladat. Databaze potrebuje oboji. Bez SECRETS_KEY by se udaje ukladaly v plaintextu a to je horsi nez ztratit je pri restartu: tabulku vidi kazda zaloha a kazdy dump pri ladeni. Pridano: - pool v src/db/pool.ts vcetne transakci a dbFor(tenantId) jako sev pro budouci oddelenou databazi jednoho klienta - migrace ze src/db/migrations/*.sql pod pg_advisory_lock, jinak je pri rolling deployi pusti vsechny instance naraz. Jeden soubor je jedna transakce - sifrovani AES-256-GCM s nahodnym IV a verzi klice. Nerozsifrovatelna hodnota nepada, chova se jako nevyplnena a zaloguje se - jeden rozbity konektor nesmi shodit seznam ostatnich - /health/ready s pingem do DB. /health na databazi zamerne nezavisi, kratky vypadek by jinak vedl k restartovani containeru - GET /api/dashboard/storage a hlaska v portalu o tom, ze data jsou jen v pameti - jediny vychozi konektor na firmu a sluzbu hlida castecny unikatni index, ne jen kod. Dva soubezne zapisy by jinak udelaly dva vychozi Zmeneno: cteni i zapis konektoru je asynchronni, vcetne validace stromu. Overeno proti Postgresu 16 v kontejneru: migrace, sifrovani v tabulce, preziti restartu, rozsifrovani spravnym klicem, degradace pri spatnem klici, PATCH bez tajneho pole, prepnuti a smazani vychoziho konektoru, pametovy rezim bez DATABASE_URL. Kontejner po overeni smazan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3279dd7dac |
Cele chybove hlaseni u konektoru i skriptu
U odpovedi 401 nebo 400 je duvod napsany v tele odpovedi sluzby, ne v tom, ze prislo 401. Dosud se telo zkracovalo na 400 znaku a u overeni konektoru se zahazovalo cele - zbyla veta "Pristup zamitnut", podle ktere se neda hledat. - ScriptError nese `request` (metoda a cesta) a `detail` s celou odpovedi sluzby, zkracenou az na SCRIPT_ERROR_DETAIL_BYTES (vychozi 8 kB). Chyby jsou vzacne, takze objem neroste jako u logu uspesnych kroku - do detailu jde surove telo, ne prochazene pres JSON.stringify. U chyby chceme presne to, co sluzba poslala, vcetne HTML nebo prosteho textu - u chyby spojeni se pridava i `cause`, u neocekavane vyjimky zasobnik volani (mimo produkci, stejne jako u centralniho error handleru) - overeni konektoru vraci `detail`, `status` i `request` - cely detail jde i do logu serveru, at je to dohledatelne bez portalu - do chyby se dava jen cesta, ne cela adresa: v query muze byt tajemstvi - nova komponenta ErrorDetail: rozbaleni cele odpovedi a tlacitko Kopirovat vse Overeno: npm run typecheck prochazi na serveru i webu. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ad56c7f513 |
Transformace dat, oprava ukladani udaju konektoru
Transformace dat ve dvou rezimech plus oprava chyby, kvuli ktere se neukladaly
pristupove udaje konektoru. Popis v documentation/13-transformace-dat.md.
Kroky si predavaji i cele struktury:
- FieldType ma object a list. Do sablony se nedosazuji, predavaji se jako celek
dalsimu kroku - proto je u nich v builderu vyber a ne textove pole. Z podminek
nad nimi ma smysl jen "prisla / neprisla"
- strop na velikost struktury (SCRIPT_MAX_VALUE_BYTES, vychozi 256 kB). Radek
s vystupem kroku je nejrychleji rostouci tabulka v systemu
Dva rezimy transformace, oba nad enginem v src/scripts/mapping.ts:
- transform.map-fields: pole na pole s prevody, klikatelne
- transform.to-json: sablona cileveho objektu s ${cesta}
Marker ${...} je zamerne jiny nez {{...}}. Sablony kroku se dosazuji driv, nez
krok bezi, takze {{total}} by strom stihl vyhodnotit, nenasel by parametr toho
jmena a dosadil by prazdno. Cely retezec navic zachova typ, takze
"unitPrice": "${total}" vyrobi cislo - jinak by cizi sluzba dostala castku jako
text a odmitla ji.
Prevod map pro seznamy je to, bez ceho by priklad nesel dokoncit. Bez nej jde
prevest hlavicku dokladu, ale ne polozky objednavky, a doklad by byl na nulu.
Dal pridano:
- idoklad.create-invoice-from-object: druha polovina prikladu, bere hotove telo
dokladu z transformace a doplni povinna pole ze vzoru iDokladu
- spoustec e-shopu predava celou objednavku jako objekt a polozky jako seznam
- klikaci editor pravidel vcetne rezimu JSON pro vnorena pravidla u map
- kontrola JSONu a tvaru pravidel uz pri ulozeni stromu. Preklep je nedodelek,
ne chyba ukladani - rozdelana prace se nezahazuje
Opraveno: konektor neukladal pristupove udaje. Server byl v poradku, overeno
volanim POST i PATCH. Chyba byla v prohlizeci: u pole type="password" prohlizec
ignoruje autocomplete="off" a dosazuje ulozene prihlaseni. Uzivatel pak videl
jednu hodnotu, React drzel jinou, a ulozilo se to, co drzel React, tedy nic.
Resi to autocomplete="new-password", jmena poli, ktera nepripominaji heslo,
a prepinac zobrazeni, aby slo overit, co je opravdu zapsane.
Zakladani a uprava konektoru se presunuly do dialogu, na strance jsou jen male
karty. Formulare rozlozene po strance byly u vic konektoru neprehledne.
Overeno: npm run typecheck prochazi na serveru i webu, node --check na skriptech.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
6f6b287d7e |
Skripty konektoru: vykonna cast s manifestem a kontrolou parametru
Konektory dostaly vykonnou cast. Jeden skript je jeden soubor, ktery nese manifest (vstupni a vystupni parametry) i kod. Diky manifestu s nim umi pracovat strom automatizace, aniz by o kodu cokoliv vedel. Soubory jsou zamerne obycejny JavaScript, ne TypeScript. TypeScript by se musel prelozit a to je presne to otaceni, ktere tady nema byt. Registr sleduje cas zmeny souboru, takze uprava v portalu, rucni uprava souboru i novy soubor ve slozce funguji stejne a bez restartu. Pridano: - scripts/ se skripty konektoru, nazev souboru je zaroven ID operace - kontrola vstupu i vystupu proti manifestu, jedna funkce pro obe strany. Chybejici povinny vystup je chyba skriptu, ne uzivatele - jinak by strom veril parametru, ktery nikdy nedosel - ctx predavany skriptu: http nad adresou napojeni, util, log, config, idempotencyKey, fail a retry. Skript nedostane pristupove udaje - rozliseni opakovatelne a koncove chyby. Runner nikdy nevyhodi vyjimku, vzdy vraci vysledek vcetne retryable - redakce tajnych hodnot pred zapisem do logu. Cizi API rado vraci prijaty token v chybove zprave a log ticketu vidi klient - napojeni z environment variables vcetne iDokladu - sest ukazkovych skriptu pro iDoklad proti skutecnemu API sluzby services.csbot.cz/apps/idoklad, kazdy na jiny vzor - stranka /dashboard/skripty: seznam, manifest, editor, zkusebni spusteni. Formular testu se sklada z manifestu, nepise se pro kazdy skript - endpointy /api/dashboard/scripts vcetne Swaggeru Zmeneno: - katalog konektoru uz neni jen staticky seznam. Akce ze skriptu se domeruji prekryvem v src/data/connectors.ts, takze se naraz objevi ve validaci stromu, ve vypoctu scope i v sablonach. Pri stejnem ID vyhrava skript - ConnectorOperation ma implementation a scriptId - ApiError na klientovi nese cele telo odpovedi a umi z nej vytahnout issues - Dockerfile kopiruje scripts/ do vysledneho image Ukladani nemuze rozbit fungujici skript: kod se nejdriv zapise do docasneho souboru, ten se nacte a overi, a az pak prepise puvodni. K tomu tri dokumenty navrhu dalsich kroku: 09 datove modely a prava, 10 runtime a rozpocet na 150 klientu, 11 popis skriptu konektoru. Overeno: npm run typecheck prochazi na serveru i webu. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e177ca2087 |
Oprava: aplikace padala pri startu v produkcnim rezimu
Dockerfile nastavuje NODE_ENV=production a config.ts pri chybejicim JWT_SECRET vyhazoval vyjimku. AppFactory tu promennou nastavenou nema, takze se container po startu ukoncil a sluzba byla nedostupna (502). Chybejici JWT_SECRET uz start neshodi. Vygeneruje se nahodny klic platny do restartu containeru a do logu jde varovani. Klic zapsany v kodu se nepouziva, aby nevznikla bezpecnostni dira. Dusledek: bez nastavene promenne prestanou po restartu platit vydane tokeny. JWT_SECRET se ma nastavit jako promenna aplikace v AppFactory. |
||
|
|
7b045a9f20 |
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/. |