Rozdeleni na sluzby a konektory, pristupove udaje do konektoru
Slovo "konektor" v kodu znamenalo katalog toho, co umime. Ted znamena napojeni jedne firmy, tedy to, co tim mysli i uzivatel. Popis modelu je v documentation/12-sluzby-a-konektory.md. Tri vrstvy: - Sluzba: ze iDoklad existuje, co umi a co potrebuje k napojeni. Nase. - Skript: kod, ktery jednu operaci sluzby opravdu vykona. Nas. - Konektor: ucet firmy vcetne jejich pristupovych udaju. Firemni. Pristupove udaje se prestaly cist z environment variables. Cela instance by mela jedny udaje spolecne a dve firmy by fakturovaly z jednoho uctu. Napojeni je vlastnost firmy, ne prostredi. Z prostredi zustava jen SERVICES_BASE_URL. Pridano: - src/data/services.ts: sluzba nese general, appId, visibility, credentials a verifyPath. Kategorie "obecne" sdruzuje veci, ktere ma kazdy a nepotrebuji konektor: webhook, planovac, tickety, transformace dat, HTTP pozadavek, pauza, zapis do logu - viditelnost sluzby: vsichni, jen uvedene firmy a lide, nebo jen spravce platformy. Neviditelna sluzba se z API nevraci vubec, ne se stavem 403 - firma nema poznat, ze takova sluzba existuje - src/data/connectorStore.ts: konektory za firmu vcetne hodnot udaju. Hodnoty se z API nikdy nevraci, jen filled a missing. Prazdne pole hodnotu nemeni, takze ulozeni formularu bez tajnych hodnot nic nepresepe - FlowStep.connectorId: krok rika, pod kterym napojenim volat. null = vychozi konektor firmy, diky tomu je vzorovy strom prenositelny mezi firmami - overeni konektoru pres verifyPath, tedy cteci volani vyzadujici autorizaci. U sluzby bez nej se overi jen dostupnost a odpoved to rekne nahlas, jinak by zeleny vysledek uzivateli lhal - stranky /dashboard/sluzby a /dashboard/konektory vcetne formularu udaju - endpointy /api/dashboard/services a CRUD /api/dashboard/connectors ve Swaggeru - predvyplnene prihlaseni spravcem platformy a prepinac demo uctu na login strance, kvuli testovani prototypu Zmeneno: - stav "napojeno" se prestal cist z katalogu a zacal pocitat z konektoru firmy. Sluzba ma jen available nebo planned - validace stromu overuje i konektor. Cizi konektor je chyba, chybejici napojeni nedodelek - rozdelana prace se nezahazuje - prejmenovani napric kodem: Connector na Service, FlowStep.connectorId na serviceId, GET /connectors na GET /services, connectorIcons na serviceIcons, stranka Konektory (katalog) na Sluzby. Prevodni tabulka je v dokumentu 12 Overeno: npm run typecheck prochazi na serveru i webu. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6f6b287d7e
commit
8ad91a6c28
+212
-8
@@ -26,7 +26,9 @@ export function buildOpenApiDocument() {
|
||||
{ name: 'Dashboard', description: 'Data klientskeho portalu' },
|
||||
{ name: 'Tickety', description: 'Pozadavky, jejich resitele a log prubehu' },
|
||||
{ name: 'Automatizace', description: 'Sprava automatizaci a stromu akci' },
|
||||
{ name: 'Skripty', description: 'Vykonna cast konektoru: manifest, kod a zkusebni beh' },
|
||||
{ name: 'Sluzby', description: 'Katalog toho, co umime napojit' },
|
||||
{ name: 'Konektory', description: 'Napojeni firmy na sluzbu vcetne pristupovych udaju' },
|
||||
{ name: 'Skripty', description: 'Vykonna cast sluzby: manifest, kod a zkusebni beh' },
|
||||
{ name: 'Simulace', description: 'Vyvolani provoznich udalosti pro nahled' },
|
||||
{ name: 'Webhook', description: 'Verejny prijem dat do automatizace' },
|
||||
{ name: 'Kontakt', description: 'Poptavkovy formular z webu' },
|
||||
@@ -99,6 +101,43 @@ export function buildOpenApiDocument() {
|
||||
personId: { type: 'string', nullable: true },
|
||||
},
|
||||
},
|
||||
Connector: {
|
||||
type: 'object',
|
||||
description:
|
||||
'Napojeni firmy na jednu sluzbu. Hodnoty pristupovych udaju tady zamerne ' +
|
||||
'nejsou a nikdy nebudou - secrets se z beznych endpointu nevraci.',
|
||||
properties: {
|
||||
id: { type: 'string', example: 'con_1a2b3c4d' },
|
||||
tenantId: { type: 'string', example: 'tnt_automia' },
|
||||
serviceId: { type: 'string', example: 'idoklad' },
|
||||
name: { type: 'string', example: 'iDoklad Automia' },
|
||||
baseUrl: { type: 'string', nullable: true },
|
||||
enabled: { type: 'boolean' },
|
||||
status: { type: 'string', enum: ['untested', 'ok', 'error'] },
|
||||
lastCheckAt: { type: 'string', format: 'date-time', nullable: true },
|
||||
lastError: { type: 'string', nullable: true },
|
||||
isDefault: {
|
||||
type: 'boolean',
|
||||
description: 'Krok stromu bez vybraneho konektoru pouzije tenhle.',
|
||||
},
|
||||
filled: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
description: 'ID poli, ktera jsou vyplnena. Hodnoty se nevraci.',
|
||||
},
|
||||
missing: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
description: 'ID povinnych poli, ktera chybi.',
|
||||
},
|
||||
config: {
|
||||
type: 'object',
|
||||
additionalProperties: { type: 'string' },
|
||||
description: 'Necitliva nastaveni. Tajna pole tu nejsou vubec.',
|
||||
},
|
||||
ready: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
ScriptField: {
|
||||
type: 'object',
|
||||
description:
|
||||
@@ -135,9 +174,10 @@ export function buildOpenApiDocument() {
|
||||
id: {
|
||||
type: 'string',
|
||||
example: 'idoklad.get-issued-invoice',
|
||||
description: 'Tvar konektor.operace. Nazev souboru musi byt <id>.js.',
|
||||
description: 'Tvar sluzba.operace. Nazev souboru musi byt <id>.js.',
|
||||
},
|
||||
connectorId: { type: 'string', example: 'idoklad' },
|
||||
serviceId: { type: 'string', example: 'idoklad' },
|
||||
serviceName: { type: 'string', example: 'iDoklad' },
|
||||
operationId: { type: 'string', example: 'get-issued-invoice' },
|
||||
name: { type: 'string', example: 'Získat vydanou fakturu' },
|
||||
description: { type: 'string' },
|
||||
@@ -947,15 +987,179 @@ export function buildOpenApiDocument() {
|
||||
responses: { '200': { description: 'Proud udalosti text/event-stream' } },
|
||||
},
|
||||
},
|
||||
'/api/dashboard/services': {
|
||||
get: {
|
||||
tags: ['Sluzby'],
|
||||
summary: 'Katalog sluzeb pro builder',
|
||||
description:
|
||||
'Vraci jen sluzby, ktere uzivatel vidi. Neviditelna sluzba v odpovedi neni ' +
|
||||
'vubec, ne se stavem "nemate pravo". Operace, ktere obsluhuje skript, nesou ' +
|
||||
'implementation: script a maji skutecne inputs a outputFields.',
|
||||
security: [{ bearerAuth: [] }],
|
||||
responses: { '200': { description: 'Sluzby, kategorie a operatory podminek' } },
|
||||
},
|
||||
},
|
||||
'/api/dashboard/connectors/services': {
|
||||
get: {
|
||||
tags: ['Sluzby'],
|
||||
summary: 'Katalog sluzeb ocima firmy',
|
||||
description:
|
||||
'Jako /services, navic connectorCount, tedy kolik konektoru na sluzbu firma ma. ' +
|
||||
'Podle toho se rozlisi napojeno od muzete si napojit. Neni to vlastnost sluzby, ' +
|
||||
'ale te firmy.',
|
||||
security: [{ bearerAuth: [] }],
|
||||
parameters: [{ name: 'tenantId', in: 'query', schema: { type: 'string' } }],
|
||||
responses: { '200': { description: 'Sluzby vcetne pouziti ve firme' } },
|
||||
},
|
||||
},
|
||||
'/api/dashboard/connectors': {
|
||||
get: {
|
||||
tags: ['Automatizace'],
|
||||
summary: 'Katalog konektoru',
|
||||
tags: ['Konektory'],
|
||||
summary: 'Konektory firmy',
|
||||
description:
|
||||
'Operace, ktere obsluhuje skript, nesou `implementation: script` a `scriptId`, ' +
|
||||
'a maji skutecne `inputs` a `outputFields` z manifestu toho skriptu.',
|
||||
'Hodnoty pristupovych udaju se NIKDY nevraci, jen filled (co je vyplnene) ' +
|
||||
'a missing (ktera povinna pole chybi).',
|
||||
security: [{ bearerAuth: [] }],
|
||||
responses: { '200': { description: 'Konektory, kategorie a operatory podminek' } },
|
||||
parameters: [
|
||||
{ name: 'tenantId', in: 'query', schema: { type: 'string' } },
|
||||
{ name: 'serviceId', in: 'query', schema: { type: 'string' } },
|
||||
],
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Konektory firmy',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
items: {
|
||||
type: 'array',
|
||||
items: { $ref: '#/components/schemas/Connector' },
|
||||
},
|
||||
tenantId: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
tags: ['Konektory'],
|
||||
summary: 'Zalozit konektor',
|
||||
description:
|
||||
'Pristupove udaje se posilaji ve values s klici podle Service.credentials. ' +
|
||||
'Nevyplnene povinne pole neni chyba, konektor se ulozi a jen nepujde pouzit.',
|
||||
security: [{ bearerAuth: [] }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['serviceId', 'name'],
|
||||
properties: {
|
||||
serviceId: { type: 'string', example: 'idoklad' },
|
||||
name: { type: 'string', example: 'iDoklad Celo' },
|
||||
baseUrl: { type: 'string', nullable: true },
|
||||
values: {
|
||||
type: 'object',
|
||||
additionalProperties: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
'201': {
|
||||
description: 'Zalozeno',
|
||||
content: {
|
||||
'application/json': { schema: { $ref: '#/components/schemas/Connector' } },
|
||||
},
|
||||
},
|
||||
'400': { description: 'Obecna sluzba konektor nepotrebuje, nebo nezname pole' },
|
||||
'404': { description: 'Sluzba neexistuje nebo ji uzivatel nevidi' },
|
||||
},
|
||||
},
|
||||
},
|
||||
'/api/dashboard/connectors/{id}': {
|
||||
get: {
|
||||
tags: ['Konektory'],
|
||||
summary: 'Detail konektoru',
|
||||
security: [{ bearerAuth: [] }],
|
||||
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
||||
responses: { '200': { description: 'Konektor' }, '404': { description: 'Neexistuje' } },
|
||||
},
|
||||
patch: {
|
||||
tags: ['Konektory'],
|
||||
summary: 'Upravit konektor',
|
||||
description:
|
||||
'Ve values staci poslat jen to, co se meni. PRAZDNY RETEZEC hodnotu smaze, ' +
|
||||
'chybejici klic ji nechava - diky tomu jde ulozit formular, ktery tajne hodnoty ' +
|
||||
'neposila. Zmena udaju vzdy zrusi predchozi overeni.',
|
||||
security: [{ bearerAuth: [] }],
|
||||
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
baseUrl: { type: 'string', nullable: true },
|
||||
values: { type: 'object', additionalProperties: { type: 'string' } },
|
||||
enabled: { type: 'boolean' },
|
||||
isDefault: { type: 'boolean', enum: [true] },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { '200': { description: 'Upraveno' }, '404': { description: 'Neexistuje' } },
|
||||
},
|
||||
delete: {
|
||||
tags: ['Konektory'],
|
||||
summary: 'Smazat konektor',
|
||||
description:
|
||||
'Kdyz zmizel vychozi konektor, prevezme to prvni zbyly - jinak by kroky bez ' +
|
||||
'vybraneho konektoru prestaly fungovat.',
|
||||
security: [{ bearerAuth: [] }],
|
||||
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
||||
responses: { '204': { description: 'Smazano' }, '404': { description: 'Neexistuje' } },
|
||||
},
|
||||
},
|
||||
'/api/dashboard/connectors/{id}/test': {
|
||||
post: {
|
||||
tags: ['Konektory'],
|
||||
summary: 'Overit napojeni',
|
||||
description:
|
||||
'Zavola verifyPath sluzby, coz je zamerne cteci volani vyzadujici autorizaci. ' +
|
||||
'Kdyz ho sluzba nema, overi se jen /health a odpoved to v checked rekne - aby ' +
|
||||
'si nikdo nemyslel, ze jsou overene i pristupove udaje. Neuspesne overeni neni ' +
|
||||
'chyba API, vraci se 200 s ok: false.',
|
||||
security: [{ bearerAuth: [] }],
|
||||
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Vysledek overeni',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
ok: { type: 'boolean' },
|
||||
checked: { type: 'string' },
|
||||
status: { type: 'integer' },
|
||||
message: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'404': { description: 'Konektor neexistuje' },
|
||||
},
|
||||
},
|
||||
},
|
||||
'/api/dashboard/scripts': {
|
||||
|
||||
Reference in New Issue
Block a user