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,58 @@
|
||||
/**
|
||||
* Konfigurace z environment variables.
|
||||
* AppFactory je predava containeru, viz AGENTS.md, sekce Variables a secrets.
|
||||
* Zadna hodnota se nehardcoduje a zadny secret se neloguje.
|
||||
*/
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
function requiredInProduction(name: string, fallback: string): string {
|
||||
const value = process.env[name];
|
||||
if (value && value.trim().length > 0) return value;
|
||||
if (isProduction) {
|
||||
// Zamerne padame pri startu - tichy fallback na dev secret by byl bezpecnostni dira.
|
||||
throw new Error(`Chybi povinna promenna prostredi ${name} (NODE_ENV=production).`);
|
||||
}
|
||||
console.warn(`[config] ${name} neni nastavena, pouzivam DEV fallback. Nepouzivat v produkci.`);
|
||||
return fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix verejne adresy, napr. "/apps/csbot-prototype".
|
||||
* Caddy ho pred predanim do containeru odstranuje (handle_path), ale prohlizec
|
||||
* ho vidi - proto se z nej sklada base pro SPA, odkazy, Swagger i webhooky.
|
||||
*/
|
||||
function normalizeRootPath(value: string | undefined): string {
|
||||
const trimmed = (value ?? '').trim();
|
||||
if (trimmed.length === 0 || trimmed === '/') return '';
|
||||
const withSlash = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
||||
return withSlash.replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
export const config = {
|
||||
isProduction,
|
||||
/** Port urcuje AppFactory sablona, vychozi 3000. Nemenit bez upravy metadat. */
|
||||
port: Number(process.env.PORT ?? 3000),
|
||||
rootPath: normalizeRootPath(process.env.ROOT_PATH),
|
||||
jwtSecret: requiredInProduction('JWT_SECRET', 'dev-only-secret-nepouzivat-v-produkci'),
|
||||
jwtExpiresIn: process.env.JWT_EXPIRES_IN ?? '8h',
|
||||
/**
|
||||
* Povolene originy pro CORS. V nasazeni bezi web i API na stejne domene,
|
||||
* takze se CORS neuplatni. Je tu kvuli lokalnimu vyvoji s Vite dev serverem.
|
||||
*/
|
||||
corsOrigins: (process.env.CORS_ORIGIN ?? 'http://localhost:5173,http://localhost:4173')
|
||||
.split(',')
|
||||
.map((o) => o.trim())
|
||||
.filter(Boolean),
|
||||
/**
|
||||
* Verejna adresa bez prefixu, napr. "https://services.csbot.cz".
|
||||
* Sklada se z ni absolutni URL webhooku. Kdyz neni vyplnena, pouzije se
|
||||
* relativni tvar - nikdy se nehardcoduje produkcni domena.
|
||||
*/
|
||||
publicOrigin: (process.env.PUBLIC_ORIGIN ?? '').trim().replace(/\/+$/, ''),
|
||||
};
|
||||
|
||||
/** Zaklad verejne adresy aplikace vcetne prefixu proxy. */
|
||||
export function publicBaseUrl(): string {
|
||||
return `${config.publicOrigin}${config.rootPath}`;
|
||||
}
|
||||
Reference in New Issue
Block a user