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>
52 lines
1.5 KiB
JSON
52 lines
1.5 KiB
JSON
{
|
|
"name": "csbot-prototype",
|
|
"version": "1.0.0",
|
|
"private": true,
|
|
"type": "module",
|
|
"description": "Automia - web a klientsky portal. Automatizace, voiceboti, integrace, tickety a incidenty.",
|
|
"scripts": {
|
|
"build": "npm run build:server && npm run build:web",
|
|
"build:server": "tsc -p tsconfig.json",
|
|
"build:web": "vite build",
|
|
"start": "node dist/index.js",
|
|
"dev": "concurrently -n api,web -c magenta,cyan \"npm:dev:server\" \"npm:dev:web\"",
|
|
"dev:server": "tsx watch src/index.ts",
|
|
"dev:web": "vite",
|
|
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p web/tsconfig.json --noEmit"
|
|
},
|
|
"dependencies": {
|
|
"bcryptjs": "^2.4.3",
|
|
"cors": "^2.8.5",
|
|
"express": "^4.21.2",
|
|
"jsonwebtoken": "^9.0.2",
|
|
"pg": "^8.23.0",
|
|
"swagger-ui-express": "^5.0.1",
|
|
"zod": "^3.24.1"
|
|
},
|
|
"devDependencies": {
|
|
"@tailwindcss/vite": "^4.0.0",
|
|
"@types/bcryptjs": "^2.4.6",
|
|
"@types/cors": "^2.8.17",
|
|
"@types/express": "^4.17.21",
|
|
"@types/jsonwebtoken": "^9.0.7",
|
|
"@types/node": "^22.10.5",
|
|
"@types/pg": "^8.21.0",
|
|
"@types/react": "^18.3.18",
|
|
"@types/react-dom": "^18.3.5",
|
|
"@types/swagger-ui-express": "^4.1.7",
|
|
"@vitejs/plugin-react": "^4.3.4",
|
|
"concurrently": "^9.1.2",
|
|
"lucide-react": "^0.469.0",
|
|
"react": "^18.3.1",
|
|
"react-dom": "^18.3.1",
|
|
"react-router-dom": "^6.28.1",
|
|
"tailwindcss": "^4.0.0",
|
|
"tsx": "^4.19.2",
|
|
"typescript": "^5.7.3",
|
|
"vite": "^6.0.7"
|
|
},
|
|
"engines": {
|
|
"node": ">=20"
|
|
}
|
|
}
|