42b3da83032d53a41d7155c7efee8ef5b9e68a7b
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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> |
||
|
|
6bcd7f845c |
Hierarchie firmy: kdo co vidi, a zalozka Firma
Pohled na celou firmu dostal kazdy, kdo do ni patril: scopes.push('tenant')
se v access.ts neptalo na nic. mine byl dobrovolny filtr, ne strop, takze
resitel s roli agent poslal ?scope=tenant a dostal cely provoz.
Rozdil, na kterem to ted stoji: pohled je co chci videt, strop je co vubec smim
videt. Existoval jen pohled a klientovi se veril.
Model:
- Membership.seesAllTenant - vidi cely provoz firmy. Postaveni uctu ve firme,
ne vlastnost resitele: clovek muze byt ve dvou firmach jednou reditel
a jednou brigadnik
- PersonGroup.members je { personId, seesAll } misto holeho personIds. seesAll
je vedouci sekce. Priznak visi na clenstvi, ne na cloveku a ne na skupine -
diky tomu muze byt clovek v peti sekcich a jen ve dvou videt vsechno, coz
role rict neumi, ta je jedna na celou firmu
- stara podoba personIds se dal cte, prevadi ji groupMembers
Vypocet stropu (visibilityFor), sjednoceni ne prunik: spravce platformy nebo
seesAllTenant vidi celou firmu, jinak svoje tickety plus vse ze sekci, kde ma
zaskrtnuto, plus jejich fronta. U zaznamu bez priznaku rozhoduje pravo
ticket.assign.others - kdo smel prehazovat cizi praci, uz stejne cely provoz
videl, takze se mu nic nebere.
Vynuceni:
- strop je povinna soucast TicketFilter, stejne jako tenantIds. Nepovinny filtr
na prava je filtr, ktery jednou nekde chybi - takhle prekladac ukazal vsech
trinact mist, ktera ho jeste nemela
- getWorkload a getAgentStats uz nesahaji do pole ticketu primo, jdou pres
listTickets. Driv obchazely kazde omezeni viditelnosti
- getTicket kontroluje strop i u jednoho ticketu, bez toho by stacilo znat ID
- detail a prevzeti pocitaji strop za firmu ticketu, ne za prave prepnutou
Helpdesk se ridi toutez hierarchii, jen "moje" znamena, co jsem zalozil -
zadavatel pozadavek nikdy nema prirazeny. Ticket proto nese createdById.
Zalozka Firma: pod jednim mistem Prehled, Resitele, Sekce, Role a prava, Typy
ticketu a Pozvanky. V Nastaveni zustal Muj ucet a platformni veci. Role a Typy
jsou samostatne komponenty, sekce maji vlastni panel - u kazdeho clenstvi je
prepinac a radek na cloveka obecny EntityAdmin neumi.
Obsah ticketu se cte i v helpdesku, v seznamu jako jednoradkovy nahled.
Overeno na bezici instanci se tremi ucty nad tymiz daty: spravce platformy vidi
vsechny tri tickety vcetne neprirazeneho, Vomacka jako vedouci Servicedesku dva
(tickety obou clenu sekce), Kriz jako radovy clen jeden, jen svuj. Adresa cizho
ticketu vraci 404, vytizeni tymu ukazuje jen viditelne a po zaskrtnuti priznaku
se rozsah zmeni hned.
Co z toho plyne: neprirazeny ticket bez skupiny nevidi nikdo krome toho, kdo
vidi celou firmu. Prichozi praci musi nekdo smerovat.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
e7cf499a0b |
Cely navrh rozsireni: role, firmy, typy ticketu, akce, widgety, audit
Implementace vsech bodu z documentation/09-navrh-rozsireni.md. Vsechno lezi v obecnem ulozisti, ktere umi Postgres i JSON soubor. Zaklad, aby se nepsalo osmkrat totez: - src/data/store/: jedno rozhrani EntityStore, dve implementace (local se souborem nebo pameti, postgres nad tabulkou records). Vyber je na jednom miste v store/index.ts - src/data/store/cached.ts: synchronni kopie v pameti pro entity ctene pri kazdem requestu (uzivatel v autorizaci, firmy pri vypoctu prav). Bez toho by se autorizacni middleware musel predelat na async - src/routes/crud.ts: fabrika na CRUD routy. Kazda entita by jinak znamenala stejnych sto radku a sedmkrat by se opravila spatne - src/data/bootstrap.ts: jedno misto, kde je seznam entit a jejich vychozi sady - migrace 002_records.sql: jedna tabulka s JSONB. Tvary se jeste hybou a nikdo se nad nimi nedotazuje po polich. Az se to usadi, entita se povysi na vlastni tabulku, presne jako uz maji konektory Prava a role (bod 5): - role jsou zaznamy, pravo je retezec, katalog prav je zdroj pravdy. Union 'admin' | 'agent' na ucetni a skladnika nestacil a pridavat hodnoty je slepa ulicka, kazdy klient chce jine - Membership.roleIds misto role. Systemove role admin a agent zustavaji, takze se zadny ucet nemusel predelavat - accessFor vraci prava i zalozky. Klient si nic nedovozuje Zalozky a limity za firmu (bod 6): - TenantFeatures: moduly, limity, zpristupnene sluzby. Dve vrstvy s jinym vlastnikem, ktere se nesmi michat: co ma firma zaplacene nastavujeme my, kdo z jejich lidi to smi nastavuje jejich admin. Efektivni viditelnost je prunik, takze vypnuty modul neexistuje ani pro admina te firmy - navigace ze serveru, ne konstanta na klientovi Firmy, uzivatele, resitele a skupiny: CRUD vcetne clenstvi a hesel. Heslo se z API nikdy nevraci, ani jako hash. Skupiny resitelu kvuli tomu, ze prehazovat praci na jmeno nestaci - clovek chce rict "tohle je pro ucetni". Typy ticketu a akce (body 1, 2, 3): - typ ticketu s vlastnimi polemi, plus tagy. Akce se vazou na typ nebo tag, ale za tagem nestoji zadna pole, takze akce na tagu umi jen vestavena pole - Ticket dostal typeId, fields, tags a assigneeGroupId - definice akce s telem jako operace, strom nebo skript. Pravo vznika spolu s akci jako action:<id>, admin pak zaskrtava akce, ne prava - CTA na ticketu filtruje server podle typu, tagu, podminek a prav. Kdyby to pocital klient, pocitalo by se to na dvou mistech - vestavene akce (typ, tagy, skupina) jdou pres tutez fabriku, takze maji svoje pravo a projdou auditem - spusteni zapise do logu ticketu hned, jeste nez se neco stane Vlastni widgety (bod 4): - rozdeleni na render a source, groupBy, filtr je tentyz, ktery umi seznam ticketu. Uzivatel nepise dotazy - jeden batch endpoint na cely prehled. Widget, ktery selze, vraci chybu na sve pozici a nezhasne prehled Audit a impersonace (bod 6c): - audit zapisuje i odepreni, jinak by pokusy o cizi firmu nikde nezustaly - impersonace: jen spravce platformy, nikdy na jineho spravce platformy, 30 minut bez obnoveni, vychozi jen cteni. Zapis pod rezimem cteni vraci 403 na urovni middleware, ne az v handleru Overeno bez databaze: vsech devet ulozist se nacte, role se zaloz1 a prezije restart, agent dostane 403 na spravu roli a uzsi navigaci, neznama prava se odmitnou, heslo se nevraci, typ a tagy ticketu se ulozi, CTA se objevi, widget data pocitaji vcetne seskupeni, impersonace odmitne zapis i prepnuti na admina, audit obsahuje actedBy. Degradace pri nedostupne databazi taky overena: migrace selzou, jede se do souboru a rekne se proc. Neovereno: migrace 002_records.sql proti zive databazi. Kontejner uz nebyl k dispozici, generickou vrstvu drzi tentyz pool a migrator jako konektory. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2a3d75c85e |
Firmy a prava: tenance napric portalem
Portal nemel zadnou tenanci. Kterykoliv prihlaseny uzivatel videl vsechny tickety vsech firem i cely seznam resitelu, requireRole se nikde nevolal. Tenant je hranice viditelnosti, tenantId na ticketu, resiteli i automatizaci. Uzivatel muze patrit do vic firem, v kazde s jinou roli. Pristup napric firmami je zvlast jako platformAdmin. Tri pohledy na tickety: all, tenant, mine. Admin mezi nimi prepina vcetne vyberu firmy. O pravech rozhoduje jedine data/access.ts, klient si nic nedovozuje a bere je z GET /api/dashboard/access. Filtr na firmu je v ulozistich povinny argument, takze zapomenuty filtr neznamena vse, ale nezkompiluje se. Cizi firma vraci 403 nebo 404, nikdy tise zuzeny vysledek. Prirazeni jen v ramci firmy. Prehazovat praci mezi lidmi smi jen admin, agent si smi vzit ticket na sebe. Zmena prihlasovani: ucet klient@firma.cz zanikl, demo ucty jsou nove. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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/. |