Přeskočit obsah

Konektor — registry cross-app API contractů

Status: draft (2026-06-01) Spec verze: 0.1 Cílový rollout: launcher2 0.7.x admin sekce Související: [[ai-helper]] (capabilities), [[companies-contacts-sync]] (pubsub), [[apps-gateway]] (REST routing), [[users]] (role-gate)

1. Motivace

Dnes AVAX má 5+ vendor apps + launcher2 + core-api. Vzájemné API komunikace probíhá přes 4 různé mechanizmy bez centrální registry:

Mechanizmus Příklad Definováno kde
REST endpoint + M2M scope POST /v1/chat, scope ai:chat App-ai-helper kód + m2m_clients DB
Pubsub Redis kanál companies.changed, apps.changed core-api kód + vendor subscriber
SDK namespace app.voice.record(), app.on_theme launcher2 IPC + SDK template
AI Helper capability transcribe_structured, embed.batch ai_helper.capability tabulka

Konkrétní bugy které dnes existují:

  1. Naming inconsistency: ai-helper-e2e-test má scope ai-helper.chat, app-kontakty má scope ai:chat. Stejná capability — dvě jména. Vendor Claude #1 vs #2 každý uhádne jiný formát. Reálné dnes 2026-06-01.
  2. Žádný discovery: Vendor Claude píšící app-mzdy nemá strojově čitelný seznam co může konzumovat. Memory project_next_session_roadmap ručně inventuje "AI Helper namespace". Konektor to dělá automaticky.
  3. Žádný compatibility check: Když AI Helper bump payload schema, závislé apps padají runtime. Žádné CI gate.
  4. Žádný impact analýza: Při změně companies.changed payload formátu nikdo neví kdo to konzumuje.
  5. Žádný versioning: Pubsub events nemají verzi. Apps fail-silent při mismatch.

Cíl Konektor modulu:

  • Centrální registry všech cross-app API surfaces s machine-readable spec + semver
  • Provides/consumes graf mezi apps + launcher + platform
  • Compatibility check při publish nové verze
  • Migration UX při breaking change (notifikace, sunset window)
  • Admin UI v launcher2 pro super_admin přehled

2. Konceptuální model

┌──────────────────┐  declares   ┌───────────────┐
│  PROVIDER (app)  │ ──────────► │   KONEKTOR    │
│  app-ai-helper   │   provides  │   ai-chat     │
│  __platform__    │             │   v0.4.4      │
│  __launcher__    │             └───────────────┘
└──────────────────┘                    ▲
                                        │ consumes
                                        │ version_range ^0.4.0
                                ┌───────────────┐
                                │ CONSUMER (app)│
                                │  app-hotline  │
                                │  app-kontakty │
                                └───────────────┘

Definice:

Term Význam
Konektor Pojmenovaná specifikace API surface (např. ai-chat, companies-sync, voice-record). Imutable identifier.
Verze konektoru Konkrétní semver revize specu (v0.4.4). Spec je JSON schema pro inputs+outputs + side effects.
Kind Typ komunikace: rest | pubsub | sdk | capability. Určuje shape spec dokumentu.
Provider App která konektor v dané verzi poskytuje. Může být __platform__ (core-api), __launcher__ (launcher2) nebo app-<slug>.
Consumer App která konektor konzumuje. Deklaruje version range (np. ^0.4.0).
Závislost Hrana v grafu: consumer_app@version --consumes(version_range)--> connector.
Kompatibilita Provider's current version splňuje consumer's version_range (semver semantika).

Speciální providers:

  • __platform__ — core-api endpointy + platform pubsub kanály (companies.changed, apps.changed)
  • __launcher__ — launcher2 SDK (IPC handshake, voice, theme broadcast)
  • app-<slug> — vendor app

3. Datový model

Migrace 030 (avax-platform):

CREATE TABLE connectors (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name            VARCHAR(100) UNIQUE NOT NULL,
    kind            VARCHAR(20) NOT NULL,
        -- 'rest' | 'pubsub' | 'sdk' | 'capability'
    provider_slug   VARCHAR(100) NOT NULL,
        -- '__platform__' | '__launcher__' | 'app-<slug>'
    description     TEXT NOT NULL,
    is_public       BOOLEAN NOT NULL DEFAULT TRUE,
        -- public = libovolný consumer; false = jen invited
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    created_by      UUID REFERENCES users(id)
);
CREATE INDEX idx_connectors_provider ON connectors(provider_slug);

CREATE TABLE connector_versions (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    connector_id    UUID NOT NULL REFERENCES connectors(id) ON DELETE CASCADE,
    semver          VARCHAR(20) NOT NULL,
        -- '0.4.4', '1.0.0-beta', strict semver
    is_breaking     BOOLEAN NOT NULL DEFAULT FALSE,
        -- explicit flag — usnadňuje query "co breakne moji app"
    spec            JSONB NOT NULL,
        -- shape dle kind (viz §5)
    changelog       TEXT,
    deprecated_at   TIMESTAMPTZ,
    sunset_at       TIMESTAMPTZ,
        -- po sunset_at provider přestane podporovat → consumers MUSÍ upgradnout
    released_by     UUID REFERENCES users(id),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (connector_id, semver)
);
CREATE INDEX idx_conn_versions_lookup ON connector_versions(connector_id, semver);

CREATE TABLE app_connector_deps (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    app_slug        VARCHAR(100) NOT NULL,
        -- '__platform__' | '__launcher__' | 'app-<slug>'
    app_version     VARCHAR(50) NOT NULL,
        -- verze app která tu deklaraci přinesla (např. '0.6.52')
    connector_id    UUID NOT NULL REFERENCES connectors(id) ON DELETE CASCADE,
    role            VARCHAR(20) NOT NULL,
        -- 'provider' | 'consumer'
    version_range   VARCHAR(50) NOT NULL,
        -- provider: exact ('0.4.4'); consumer: range ('^0.4.0', '>=1.0,<2.0')
    is_active       BOOLEAN NOT NULL DEFAULT TRUE,
        -- false když app verze byla nahrazena novější deklarací
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (app_slug, app_version, connector_id, role)
);
CREATE INDEX idx_acd_active ON app_connector_deps(connector_id, role)
    WHERE is_active = TRUE;
CREATE INDEX idx_acd_app ON app_connector_deps(app_slug, app_version);

-- Cached compatibility výsledky (recompute pri publish)
CREATE TABLE connector_compatibility_issues (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    consumer_slug   VARCHAR(100) NOT NULL,
    consumer_version VARCHAR(50) NOT NULL,
    connector_id    UUID NOT NULL REFERENCES connectors(id) ON DELETE CASCADE,
    required_range  VARCHAR(50) NOT NULL,
    provider_slug   VARCHAR(100) NOT NULL,
    provider_current_version VARCHAR(50),
    severity        VARCHAR(20) NOT NULL,
        -- 'critical' (breaking, sunset reached)
        -- 'warning'  (sunset blíží)
        -- 'info'     (newer version available)
    reason          TEXT,
    detected_at     TIMESTAMPTZ NOT NULL DEFAULT now(),
    resolved_at     TIMESTAMPTZ
);
CREATE INDEX idx_compat_open ON connector_compatibility_issues(severity)
    WHERE resolved_at IS NULL;

4. Shape spec JSONB per kind

4.1 kind=rest

{
  "kind": "rest",
  "auth": "m2m_jwt",
  "scope": "ai:chat",
  "endpoints": [
    {
      "method": "POST",
      "path": "/v1/chat",
      "request": { "$ref": "https://json-schema.org/...", "schema": {...} },
      "response_streaming": "sse",
      "response": { "schema": {...} },
      "errors": [
        { "status": 401, "code": "invalid_token" },
        { "status": 429, "code": "rate_limited" }
      ]
    }
  ],
  "rate_limit": { "per_minute": 60 },
  "idempotent": true
}

4.2 kind=pubsub

{
  "kind": "pubsub",
  "channel": "companies.changed",
  "broker": "redis",
  "payload_schema": {
    "type": "object",
    "required": ["action", "company"],
    "properties": {
      "action": { "enum": ["created", "updated", "deactivated", "reactivated"] },
      "company": {
        "type": "object",
        "required": ["id", "ico", "name", "is_active", "is_vendor"],
        "properties": { ... }
      }
    }
  },
  "ordering": "best_effort",
  "delivery": "at_most_once",
  "retention_hint": "ephemeral"
}

4.3 kind=sdk

{
  "kind": "sdk",
  "language": "python",
  "namespace": "app.voice",
  "methods": [
    {
      "name": "record",
      "signature": "(seconds: int, path: str) -> bool",
      "errors": ["PermissionDenied", "DeviceUnavailable"]
    },
    {
      "name": "list_devices",
      "signature": "() -> list[dict]"
    }
  ],
  "callbacks": [
    {
      "decorator": "@app.on_theme",
      "signature": "(theme: str, font_size: int) -> None"
    }
  ],
  "ipc_messages": ["theme_changed", "session", "shutdown"]
}

4.4 kind=capability

{
  "kind": "capability",
  "capability_id": "speech.transcribe_structured",
  "invocation": {
    "mechanism": "application_call",
    "sdk": "app.application('hotline-transcribe', input=...)",
    "input_schema": { "type": "object", "properties": { "audio_url": ... } },
    "output_schema": { "type": "object", "properties": { "segments": ... } }
  },
  "side_effects": ["s3_write", "ai_quota_consume"],
  "latency_class": "long",
  "async_supported": true
}

5. Discovery flow — kdo deklaruje provides/consumes

5.1 Vendor app declaration

Vendor v root repu connector.json:

{
  "$schema": "https://docs.avaxis.cz/schemas/connector-v1.json",
  "provides": [
    {
      "connector": "hotline-transcribe",
      "version": "1.2.0",
      "kind": "capability",
      "spec": { ... }
    }
  ],
  "consumes": [
    { "connector": "ai-chat", "version_range": "^0.4.0" },
    { "connector": "companies-sync", "version_range": "^1.0.0" },
    { "connector": "ipc-session", "version_range": "^1.0.0" }
  ]
}

5.2 CI registration

Skeleton backend.yml přidá krok:

- name: Register connectors
  if: hashFiles('connector.json') != ''
  run: |
    curl -X POST $AVAX_API_URL/admin/connectors/register \
      -H "Authorization: Bearer $AVAX_AUTH_TOKEN" \
      -H "Content-Type: application/json" \
      --data @connector.json \
      --fail-with-body

Vendor publish path → connector deklaracje se zapíše do registry s app_slug=app-hotline, app_version=1.2.0. Pokud byl ten samý app_slug+app_version už registrovaný, idempotent overwrite.

5.3 Platform/launcher declaration

Pro __platform__ a __launcher__: deklarace je v platform repu (docs/connectors/platform.json a desktop/launcher2/connector.json), zaregistruje se přes core-api migrace 030 (seed) + při každém release build-backend / desktop-launcher workflow.

5.4 Manuální seed dnešních proto-connectors

Migrace 030 + seed script registruje:

Connector Kind Provider Současné verze
ai-chat rest app-ai-helper 0.4.4
ai-embed rest app-ai-helper 0.4.4
ai-rag-query rest app-ai-helper 0.4.4
ai-speech-transcribe-structured capability app-ai-helper 0.4.4
companies-sync pubsub platform 1.0.0
apps-changed pubsub platform 1.0.0
voice-record sdk launcher 1.0.0
ipc-session sdk launcher 1.1.0
theme-broadcast sdk launcher 1.0.0
hotline-transcribe capability app-hotline 0.3.0

Consumer linky se seedují podle reálných memory faktů (app-kontakty consumes ai-chat ^0.4.0, companies-sync ^1.0.0, atd.).

6. Versioning policy — semver strict

Bump Kdy Příklad
Major (X.0.0) Breaking change Změna povinného field v request payload, nový status code, rename pubsub channel
Minor (1.X.0) Backward-compat addition Nový volitelný field, nový endpoint, nový event action
Patch (1.0.X) Bug fix bez schema change Internal fix, latency improvement

Breaking change definice:

  • REST: změna povinného field v request, smazání response field, status code change pro existing error
  • Pubsub: rename channel, změna required field v payload, change ordering guarantee
  • SDK: rename method, change signature, smazání callback
  • Capability: change required input field, change output shape

Deprecation lifecycle:

released → deprecated_at (T0)
        → sunset_at (T0 + 30d default)
        → removed (provider zastaví podporu)

Consumer dostane warning od deprecated_at a critical issue od sunset_at.

7. Compatibility check algoritmus

Při každém: - Provider publish nové verze - Consumer publish s novou consumes deklarací - Manuální trigger v admin UI

def check_compatibility() -> list[Issue]:
    issues = []
    # Pro každého aktivního consumer
    for consumer in app_connector_deps.where(role='consumer', is_active=True):
        provider_versions = connector_versions.where(
            connector_id=consumer.connector_id
        ).order_by('semver DESC')
        if not provider_versions:
            issues.append(Issue('critical', 'no provider', consumer))
            continue

        # Najdi nejvyšší provider verzi co matchne consumer.version_range
        match = first(v for v in provider_versions
                      if semver_in_range(v.semver, consumer.version_range))
        if not match:
            issues.append(Issue('critical', 'no compatible version', consumer,
                                provider_current=provider_versions[0].semver))
            continue

        # Sunset check
        if match.sunset_at and match.sunset_at < now():
            issues.append(Issue('critical', 'sunset reached', consumer))
        elif match.deprecated_at:
            issues.append(Issue('warning', 'deprecated, plan upgrade', consumer))

        # Newer available
        if provider_versions[0].semver != match.semver:
            issues.append(Issue('info', 'newer version available', consumer))

    return issues

Výsledek se cachuje v connector_compatibility_issues. Recompute denně + ad-hoc po publish.

8. Admin UI — sekce "Konektor" v launcher2

8.1 Navigace

Admin (super_admin tab)
├── Aplikace        (existing)
├── Uživatelé       (existing)
├── Vendoři         (existing)
└── Konektor        ← NEW
    ├── Přehled
    ├── Graf závislostí
    ├── Konektory (list + detail)
    ├── Issues (compatibility)
    └── Changelog

8.2 Přehled (landing)

┌─ Konektor · Přehled ──────────────────────────────────────┐
│  Konektorů: 10     Providerů: 4     Consumerů: 17         │
│  Issues: 0 critical · 1 warning · 3 info                  │
│                                                           │
│  Recent changes (7 dní):                                  │
│  • 2026-06-01  companies-sync v1.0.0 (initial)            │
│  • 2026-05-31  ai-chat v0.4.4 (patch)                     │
│  • 2026-05-30  voice-record v1.1.0 (minor: list_devices)  │
│                                                           │
│  ⚠ Issues:                                                │
│  • ai-chat: 2 consumers používají scope 'ai-helper.chat', │
│    1 používá 'ai:chat' — naming inconsistency             │
│    [Resolve →]                                            │
└───────────────────────────────────────────────────────────┘

8.3 Graf závislostí

Force-directed graph (CTk Canvas + simple physics, nebo embedded pyvis/networkx snapshot jako PNG):

  • Nodes: apps + launcher + platform (ikona, barva podle typu)
  • Edges: directed consumer → provider (label = version_range + status barva)
  • Filtry: jen app, jen pubsub, jen rest, ...
  • Click node → side panel s detailem (provides/consumes list)

8.4 Konektor detail

┌─ Konektor: ai-chat ───────────────────────────────────────┐
│  Kind: REST                                               │
│  Provider: app-ai-helper                                  │
│  Auth: M2M JWT (scope ai:chat)                            │
│  Visibility: Public                                       │
│                                                           │
│  Verze:                                                   │
│  ─────                                                    │
│  ▸ v0.4.4  (current)  2026-06-01  patch    [Spec]         │
│  ▸ v0.4.3             2026-05-28  initial  [Spec]         │
│                                                           │
│  Consumers (3):                                           │
│  ──────────                                               │
│  app-hotline 1.2.0     ^0.4.0  ✅ compatible (v0.4.4)     │
│  app-kontakty 0.1.0    ^0.4.0  ✅ compatible (v0.4.4)     │
│  __launcher__ 0.6.52   ^0.4.0  ✅ compatible (v0.4.4)     │
│                                                           │
│  [Vypsat nové verze]  [Označit deprecated]                │
└───────────────────────────────────────────────────────────┘

8.5 Issues

Filtruje connector_compatibility_issues WHERE resolved_at IS NULL, group by severity + connector. Action button "Resolve" → modal s detaily.

8.6 Changelog

connector_versions chronologicky, filtr po kind / provider. Užitečné pro post-mortem ("kdy se to změnilo?").

9. API endpointy

9.1 Public (M2M / app-side)

GET  /v1/connectors                 — list visible connectors (filtered podle access)
GET  /v1/connectors/{name}/versions — version list pro connector
GET  /v1/connectors/{name}/spec?version=X — full JSON spec

9.2 Admin (super_admin JWT)

POST /admin/connectors/register     — register provides+consumes (z connector.json)
GET  /admin/connectors              — full list s issues
GET  /admin/connectors/issues       — compatibility issues
POST /admin/connectors/{name}/versions/{semver}/deprecate
                                    — set deprecated_at + sunset_at
POST /admin/connectors/recheck-compatibility
                                    — force recompute

9.3 Self-service (vendor admin)

GET /admin/vendor/connectors/mine   — co moje firma poskytuje / konzumuje

10. Migration UX — co se stane při breaking change

10.1 Provider publish v2.0.0 (breaking ai-chat schema)

  1. Při CI register POST → backend detekuje breaking (major bump)
  2. Trigger check_compatibility() → najde 3 consumers s ^0.4.0 (incompatible)
  3. Vytvoří 3 connector_compatibility_issues s severity=critical
  4. Notifikace:
  5. Gitea issue v každém consumer repu: "Action required: ai-chat v2.0.0 breaks your ^0.4.0 range. Sunset of v0.x: 2026-07-01"
  6. Admin UI Issues tab ukáže red flag
  7. Email super_admin (opt-in)
  8. Provider má volbu:
  9. Udržet dual support (paralelní v0.x + v2.x endpoints) do sunset_at
  10. Sunset rychleji s souhlasem všech consumers
  11. Consumer vendor Claude:
  12. Bumpni version_range v connector.json na >=0.4,<3.0
  13. Test compatibility
  14. Push → new version registers + issue auto-resolves

10.2 Launcher gate (defense in depth)

Per memory reference_role_gate — launcher2 ma install/launch gate. Rozšířit o connector check:

def _can_launch_app(app: dict) -> tuple[bool, str]:
    # Existing role check
    ok, msg = _check_role(app)
    if not ok:
        return False, msg

    # Nový: connector compatibility
    issues = api.get(f"/admin/vendor/connectors/{app.slug}/issues")
    critical = [i for i in issues if i['severity'] == 'critical']
    if critical:
        return False, (f"Aplikace {app.name} má nekompatibilní závislosti: "
                       f"{', '.join(i['connector_name'] for i in critical)}. "
                       f"Aktualizujte aplikaci.")
    return True, "ok"

11. Bezpečnost a zóny

  • Public connectors — viditelné všem M2M klientům s libovolným scopem
  • Internal connectorsis_public=false, vyžadují explicit grant (connector:read:<name> scope na M2M client)
  • Provider authority — pouze provider_slug app může bumpnout své verze. Pro __platform__ a __launcher__ jen super_admin.
  • Spec immutabilityconnector_versions row je immutable po vytvoření (kromě deprecated_at / sunset_at). Změna spec = nová verze.

12. Vztah k existujícím komponentům

Existing Konektor mapping
M2M allowed_scopes (ai:chat, companies.read) Scope = auth.scope field v kind=rest spec. Auto-grant scope při consumer install.
Redis pubsub kanály (companies.changed, apps.changed) kind=pubsub connectors. channel field = redis kanál.
SDK namespaces (app.voice.*, app.on_theme) kind=sdk connectors. Provider = __launcher__.
ai_helper.capability tabulka kind=capability connectors. Provider = app-ai-helper (worker capabilities) nebo vendor app (per-app capability).
apps.required_roles (migrace 029) Orthogonální k connector. Role gate = WHO může app vidět. Connector gate = JESTLI app může běžet (deps OK).

Migrace cesta pro existující M2M scopes:

Naming alignment proběhne během backfillu (krok rolloutu §13):

Stávající scope Konektor name
ai:chat ai-chat
ai-helper.chat ai-chat (alias, redirect při init)
ai:rag:read ai-rag-query
ai:rag:write ai-rag-index
ai:speech:transcribe_structured ai-speech-transcribe-structured
companies.read companies-sync (consumer side)

Backfill skript update existující m2m_clients.allowed_scopes na canonical naming + zachová staré aliases v connector_versions.spec.aliases[] pole.

13. Rollout fáze

Fáze 1 — Registry MVP (v0.1)

  • Migrace 030 + 4 tabulky
  • POST /admin/connectors/register endpoint (přijme connector.json)
  • GET /v1/connectors + /admin/connectors endpoints
  • Backfill seed: 10 dnešních proto-connectors (per §5.4)
  • Admin UI: Přehled + Konektor list + detail (read-only)

Acceptance: super_admin v UI vidí 10 connectors s providers + consumers, žádné CI integrace ještě nutné.

Fáze 2 — Vendor CI integrace (v0.2)

  • Template connector.json v skeleton (s 3 default consumers: ai-chat, ipc-session, companies-sync — opt-out)
  • Skeleton backend.yml register step
  • JSON schema pro connector.json (validation v register endpointu)
  • Vendor docs docs/dev/connector-declaration.md
  • Pull-sync timer + auto-register pro launcher2 a platform

Acceptance: new vendor app create v wizardu → connector.json auto-vygenerovaný s 3 default consumes → po push CI registr → admin UI vidí novou app.

Fáze 3 — Compatibility check (v0.3)

  • connector_compatibility_issues recompute (Celery task daily + on publish)
  • Admin UI Issues tab + filter
  • Gitea issue auto-create v consumer repech (opt-in via vendor settings)
  • Naming alignment backfill (ai-helper. → ai-)

Acceptance: breaking change v ai-chat v2.0.0 (synthetic test) → automaticky detekuje 3 issues + vytvoří Gitea issues + admin UI alert.

Fáze 4 — Graph + launcher gate (v0.4)

  • Graf závislostí v admin UI (CTk Canvas force-directed nebo embedded HTML)
  • Launcher install/launch gate dle connector issues
  • Migration wizard (provider-side: "Bump major? Plan dual support N dnů")
  • Auto-pin (vendor opt-in: "Pin ai-chat ^0.4 — neupgrad sám")

Acceptance: user otevře launcher2 → vidí "Aplikace X má nekompatibilní deps" → kliknu Instalovat → block s explainerem.

14. Příklady

14.1 App-kontakty connector.json (po Fázi 2)

{
  "$schema": "https://docs.avaxis.cz/schemas/connector-v1.json",
  "provides": [],
  "consumes": [
    { "connector": "ai-chat", "version_range": "^0.4.0" },
    { "connector": "ai-rag-query", "version_range": "^0.4.0" },
    { "connector": "companies-sync", "version_range": "^1.0.0" },
    { "connector": "ipc-session", "version_range": "^1.1.0" },
    { "connector": "theme-broadcast", "version_range": "^1.0.0" }
  ]
}

14.2 App-hotline connector.json (vendor provider + consumer)

{
  "$schema": "https://docs.avaxis.cz/schemas/connector-v1.json",
  "provides": [
    {
      "connector": "hotline-transcribe",
      "version": "0.3.0",
      "kind": "capability",
      "spec": {
        "capability_id": "speech.transcribe_structured",
        "invocation": { "mechanism": "application_call" },
        "input_schema": { "audio_url": "string" },
        "output_schema": { "segments": "array", "speakers": "array" }
      }
    }
  ],
  "consumes": [
    { "connector": "ai-chat", "version_range": "^0.4.0" },
    { "connector": "voice-record", "version_range": "^1.0.0" }
  ]
}

14.3 Platform connector.json (seed)

{
  "provides": [
    {
      "connector": "companies-sync",
      "version": "1.0.0",
      "kind": "pubsub",
      "spec": {
        "channel": "companies.changed",
        "broker": "redis",
        "payload_schema": { ... }
      }
    },
    {
      "connector": "apps-changed",
      "version": "1.0.0",
      "kind": "pubsub",
      "spec": { ... }
    }
  ]
}

15. Resolved decisions (Round 1 — 2026-06-01)

Po user review confirmed:

15.1 Naming alignment timing → Fáze 3 + alias mapping ve v0.1

  • v0.1 seed registers canonical naming (ai-chat, ai-rag-query, companies-sync, ...)
  • Alias zachování v connector_versions.spec.aliases: list[str]
  • Pro ai-chat v0.4.4 spec uloží aliases: ["ai:chat", "ai-helper.chat"]
  • M2M validation v auth.py akceptuje canonical OR alias scope
  • Fáze 3 backfill (per spec §13) — koordinovaná SQL update m2m_clients.allowed_scopes napříč apps + restart kontejnerů
  • Důvod: app-kontakty a app-hotline live s ai:chat, disruption bez win

15.2 Visibility model → Public/internal binární + scope grant

  • connectors.is_public BOOLEAN (DB) — public default true
  • Public (is_public=true) — libovolný M2M klient s relevantní auth scope může konzumovat. Vendor app nemusí žádat o consent.
  • Internal (is_public=false) — vyžaduje explicit grant scope connector:read:<connector_name> na consumer M2M client. Super_admin povoluje přes admin UI.
  • Out of scope: Per-org consent matrix (vendor X schvaluje Y). Pro AVAXIS primary vendor model nepotřeba.

15.3 Launcher gate severity → Warning v0.1-0.3, block v0.4

  • v0.1-v0.3 — UI varování only (⚠ ikona u app card, tooltip s detailem issue). Install + launch funguje normálně.
  • v0.4 — Critical issue (incompatible deps, sunset reached) blokuje install/launch. Warning issues (deprecated, newer available) zůstávají jen indikační.
  • Důvod: Gradual rollout — validate false positives před aktivací gate. Block od v0.1 by mohl blokovat user kvůli registry bug.

15.4 Topology → 1:N (one provider, many consumers)

  • v0.1-v0.4 single provider per connector
  • 95 % use case (AI Helper, platform pubsub, launcher SDK)
  • M:N (failover/A-B) extension odložená do v0.5+ když real HA potřeba (např. multi-instance AI Helper s load balance)

16. Resolved decisions (Round 2 — 2026-06-01)

16.1 Connector ownership transfer → Super_admin manual reassign + UI

  • Admin UI: connector detail má [Převést vlastnictví] button
  • Modal vybere nový provider_slug + volitelný grace period (sunset current version po N dnů, then auto-deprecate)
  • Audit log entry connector_ownership_transfer v audit_logs
  • Důvod: Edge case (provider apps lifecycle je delší než connector lifecycle). Manual flow je adekvátní pro pravděpodobnou frekvenci.

16.2 Semver pre-release support → Hned ve v0.1

  • Spec semver akceptuje 0.5.0-beta, 1.0.0-rc1, 2.0.0-alpha.3
  • Standardní npm-like chování:
  • version_range="^1.0.0" (stable) NEVIDÍ pre-release
  • version_range="^1.0.0-beta" (opt-in) VIDÍ pre-release
  • version_range=">=1.0.0-0" opt-in všech 1.x pre-releases
  • Provider workflow: bumpni 2.0.0-beta → opt-in consumers můžou testovat → po validation bump 2.0.0 stable
  • Důvod: Provider nemá jinou cestu testovat breaking change před stable release. Pre-release support má nulový marginal cost (semver knihovny už podporují).

16.3 Vendor connector.json defaults → Auto-fill 3 common consumers, opt-out

Create-app wizard (Fáze 2) vygeneruje connector.json s defaultními consumers které typický vendor app potřebuje:

{
  "provides": [],
  "consumes": [
    { "connector": "ipc-session",      "version_range": "^1.1.0" },
    { "connector": "theme-broadcast",  "version_range": "^1.0.0" },
    { "connector": "ai-chat",          "version_range": "^0.4.0" }
  ]
}

Vendor Claude může: - Odstranit consumer pokud nepotřebuje (např. background service bez UI odstraní theme-broadcast) - Přidat další (companies-sync, voice-record, hotline-transcribe, ...)

Důvod: Discoverability + correctness by default. Empty consumes risk: vendor zapomene declarovat → graph incomplete → compatibility check míjí breaking changes.

16.4 Provider seed → Manual JSON v platform repu + migrace 030

  • docs/connectors/seed.json v platform repu obsahuje 10 connectors + verzí (per §5.4)
  • Migrace 030 jako součást upgrade load souboru a INSERT do connectors
  • connector_versions + app_connector_deps (pro consumers per memory state)
  • Idempotent re-run: INSERT ... ON CONFLICT DO NOTHING
  • Důvod: Code review-able (JSON soubor v PR), verzovaný v gitu, reproducible. Introspection z DB by minulo SDK + capability connectors které nejsou v m2m_clients.

17. Remaining minor questions

17.1 Deprecated SDK callback helper (Q5 unresolved)

Decision (inline): Standardní deprecation lifecycle bez auto-rewrite.

  • Provider (launcher) označí on_theme deprecated v0.4 → bump connector theme-broadcast minor (1.1.0 add on_appearance, mark on_theme deprecated v aliases)
  • SDK runtime detekuje deprecated callback usage → log warning (DeprecationWarning: @app.on_theme is deprecated, use @app.on_appearance)
  • Vendor Claude vidí warning v stderr + má sunset_at deadline
  • Žádný auto-rewrite — fragile + risk silent behavior change

17.2 Test contracts (Pact.io) — out of scope v1

Confirmed off-roadmap. Mock provider/consumer testing si vendor řeší vlastní testy. Konektor registry NEní contract test framework.

17.3 Auto-generated SDK stubs — out of scope v1

Confirmed off-roadmap. gRPC-like generated Pydantic models z spec JSON schema je ambitious. v0.5+ když validace v0.1-v0.4 ukáže reálný need.

18. Out of scope (v0.1–v0.4)

  • Mock servers pro testing (jako Pact / WireMock)
  • Auto-generated typing stubs (Pydantic models z spec)
  • Per-version analytics (kolikrát byl endpoint volán per verze)
  • A/B routing mezi provider verzemi
  • Cross-platform SDK (.NET, Java) — Python SDK only
  • Connector marketplace (3rd party publish bez Avaxis approval)

19. Naming + i18n

  • DB / kód: connector, connector_versions, app_connector_deps
  • UI (cs): "Konektor", "Konektory", "Verze konektoru", "Závislosti"
  • UI (en — future): "Connector", "Connector Versions", "Dependencies"

20. Související

  • [[ai-helper]] §7 — M2M auth flow (auth pro kind=rest connectors)
  • [[companies-contacts-sync]] — první formální kind=pubsub connector
  • [[apps-gateway]] — routing layer pro kind=rest connectors mezi apps
  • [[role-gate]] — orthogonální gate (role vs. connector compatibility)
  • [[vendor-onboarding]] — vendor workflow incl. připojení deklarace
  • [[ai-helper-as-service]] (roadmap) — relies on kind=sdk connectors pro app.ai.* namespace