Přeskočit obsah

AVAX Vendor Quickstart — pro AI asistenta v app repu

Cílová skupina: Claude / AI asistent pracující v repu konkrétní AVAX aplikace (git.avaxis.cz/avax-apps/<slug>-app). Tenhle dokument popisuje, JAK se aplikace vytváří, JAK se aktualizuje a JAK se publishuje — všechno z perspektivy vendora (uživatel firmy s companies.is_vendor=true).

Stav: F-Vendor F0+F1+F2+F3+F4 shipped (2026-05-21, commit 6333873).


1. Co je AVAX Platform — 30 s shrnutí

B2B distribuční platforma (Steam-like) pro ekonomické aplikace pro české firmy.

  • Launcher2 (Python customtkinter) — desktop klient. Stahuje, aktualizuje a spouští aplikace. Drží JWT session token, dělá IPC s aplikacemi.
  • Backend (FastAPI) — https://192.168.1.55:8000 (dev) / api.avaxis.cz (prod). Auth, RBAC, katalog, předplatné, S3 STS credentials, vendor self-service.
  • S3https://s3.avaxis.cz (Ceph/MinIO 30 TB). Per-app bucket pro distribuci + per-company bucket pro data.
  • Giteahttps://git.avaxis.cz, org avax-apps obsahuje vendor repa.

URL prostředí:

Dev:  http://192.168.1.55:8000     (avaxdev VM)
Prod: https://api.avaxis.cz        (vm-api, dnes ještě ne live)
S3:   https://s3.avaxis.cz
Git:  https://git.avaxis.cz/avax-apps/<slug>-app

2. Vendor self-service — jak vznikne aplikace

Vendor user (uživatel firmy s is_vendor=true) klikne v launcheru:

Hlavní menu → 🛠 Můj vývoj → + Nová aplikace

Vyplní slug ([a-z0-9-]+), jméno, popis, ✓ has_backend (volitelně). Submit volá POST /admin/app-management/create.

Backend automaticky udělá (žádný manuální krok v Gitea):

  1. Gitea repo avax-apps/<slug>-app:
  2. has_actions=true (CI poběží)
  3. default_branch=main
  4. PATCH pojistka (Gitea 1.21 občas ignoruje create payload).

  5. Skeleton push z tools/avax-app-template/:

  6. _replace_placeholders nahradí EDITME-slug, EDITME — Lidský název, EDITME — Stručný popis (1 věta). atd. ve všech text souborech.
  7. git init -b main && git add . && git commit && git push origin main.

  8. Vendor team write grant — firma s gitea_team_slug dostane write access na repo.

  9. Branch protection na main (PR + 1 approval, direct push blokován).

  10. Gitea Actions secrets auto-injection (klíčové!):

  11. APPDIST_S3_ENDPOINT
  12. APPDIST_S3_ACCESS_KEY
  13. APPDIST_S3_SECRET_KEY
  14. APPDIST_S3_REGION Hodnoty z core-api .env. NE AVAX_API_TOKEN — skeleton publish.yml používá --skip-finalize.

  15. DB row apps s:

  16. vendor_company_id = vendor company (F-Vendor-0 sloupec)
  17. publisher_id = vendor company
  18. distribution_bucket = "app-<slug>"

  19. Subscription + Assignment + ChannelAssignment(alpha) pro vendor company → vendor v Knihovně rovnou vidí aplikaci v alpha kanálu.

  20. Pokud has_backend=true: container_port alokace v apps-gateway range

  21. scaffold .gitea/workflows/backend.yml (per-app kontejner deploy na avaxdev, vzor app-legal commit 3c3c7d3).

3. Co je v skeletonu (tools/avax-app-template/)

Soubor Účel
src/main.py Tk demo okno: jméno, verze, build date, slug, SDK status. Vendor přepisuje vlastní logikou.
src/avaxis_sdk.py IPC s launcherem (session token, on_shutdown, on_update_pending). NESAHAJ — vendored.
src/api.py REST klient AVAX backend s auto-refresh tokenu.
src/storage.py S3 helper přes /storage/token STS.
src/config.py Načtení .env + dev fallback.
version.py VERSION = "0.1.0" + BUILD_DATE = "YYYY-MM-DD". Bump při releasu.
manifest.json Slug, display name, popis, kategorie, platforma, kanály.
requirements.txt Runtime Python závislosti (drž minimální — PyInstaller bundle).
requirements-dev.txt Dev only (pytest, ruff).
build/app.spec PyInstaller spec — single-file exe, console=False GUI, excludes velkých knihoven (cv2, av, aiortc, customtkinter, PIL) → ~25 MB.
build/build.sh / build.ps1 Lokální build wrapper (Linux/Windows).
.gitea/workflows/publish.yml CI auto-publish do alpha (push do main/master).
.gitea/workflows/backend-deploy.yml.example Template pro per-app backend kontejner. Scaffold tvoří backend pokud has_backend=true.
tests/test_smoke.py Pytest smoke.
docs/ARCHITECTURE.md Tok dat launcher ↔ app ↔ backend ↔ S3.
docs/DEPLOY.md Step-by-step deploy návod.
CLAUDE.md Kontext pro AI asistenta — kompletní detail (čti první!).
.claude/settings.json Claude Code permissions (allow/ask/deny).
.env.example Šablona env proměnných pro dev (NIKDY do gitu).
pyproject.toml Python project metadata.
.gitignore /build/*/ ignorováno (PyInstaller temp), source spec v repu.

4. Update flow — jak klient launcher vidí novou verzi

Co děla vendor (publish):

  1. Edit src/main.py, bump version.py VERSION.
  2. git commit && git push origin main.
  3. Gitea Actions: workflow publish.yml:
  4. Setup Python 3.13 (avaxdev host runner má pre-installed).
  5. PyInstaller build/app.specdist/<slug>(.exe).
  6. Normalize do dist/win/<slug>.exe.
  7. publish.py app --slug X --version Y --source dist/win/ --platform win --channel alpha --skip-finalize:
    • Upload versions/<v>/files/win/<slug>.exe do app-<slug> bucketu.
    • Generate + upload versions/<v>/version-manifest.json (SHA-256 per soubor).
    • Update channels/alpha.json{"version": "Y", "promoted_at": "...", ...}.

Co dělá klient (download):

Launcher2 installer.py při otevření Knihovny / pravidelně volá:

GET /catalog/{slug}/check-update?installed_version=X&platform=win

Backend zkontroluje company channel assignment (alpha/beta/stable), načte channels/{channel}.json z S3 + version-manifest.json, vrátí klientovi seznam souborů ke stažení (presigned URLs).

Klient stáhne soubory přes presigned URLs, ověří SHA-256, atomic rename .tmp → finální path v %LOCALAPPDATA%/Avaxis/apps/<slug>/current/.

Vendor lokální test:

# Build lokálně
bash build/build.sh

# Publish ručně (bez CI) — vyžaduje APPDIST_S3_* env
bash publish/publish.sh --version 0.1.1 --channel alpha

5. Promote flow — alpha → beta → stable

Kanál Kdo smí promote Účel
alpha vendor (CI auto-publish) interní QA vendora
beta vendor (admin UI) vybrané firmy testovací
stable jen super_admin produkce všem zákazníkům

Promote v admin UI (Aplikace → detail → Aktivní verze v kanálech → ▶ beta / ▶ stable button) volá:

PUT /admin/apps/<slug>/versions/<v>/promote?to=beta

Backend promote_in_bucket: - Najde zdrojový AppVersion row. - Vytvoří nový AppVersion row pro cílový kanál (NEMUTUJE zdrojový — fix z 2026-05-20 commit 597d9fb). - Kopíruje app_version_files rows na nový version_id. - Update channels/{to}.json v S3 bucket. - Pokud stable + slug=='avax', také update latest.json shim.


6. Self-update launcheru samotného

Launcher se umí aktualizovat sám — paralelní problematika, pro vendora ne přímo relevantní, ale dobré znát:

  • Bootstrapper avax-updater.exe (samostatný PyInstaller exe, ~17 MB) čte https://s3.avaxis.cz/app-avax/channels/stable.json při startu.
  • Pokud remote > local: stáhne, ověří SHA, retry os.replace 10s×200ms.
  • Launcher má v menu ↻ Verze X tlačítko (vedle online tečky) — viditelné jen když heartbeat (10 min) detekuje novou stable verzi. Klik: subprocess.Popen(updater) + os._exit(0) → bootstrapper přepíše launcher.
  • Bootstrapper se sám neaktualizuje — pouze reinstall přes https://s3.avaxis.cz/app-avax/installers/avax-launcher2-setup-latest.exe.

7. S3 layout

app-<slug>/                                       (per-app distribution bucket)
  versions/<v>/files/win/<filename>.exe           (binaries)
  versions/<v>/files/linux/<filename>             (Linux binaries — TODO infra)
  versions/<v>/version-manifest.json              (per-version manifest: files + SHA-256 + size)
  channels/alpha.json                             ({"version": "0.1.1", "promoted_at": "..."})
  channels/beta.json
  channels/stable.json

backup-<company_ico>/                             (per-company data bucket)
  users/<user_id>/<dir_id>/...                    (sync_dirs payload — řeší launcher2)

Aplikace SAMA NIKDY nepíše do app-<slug>/ — to dělá publish.py. Aplikace MŮŽE psát do backup-<ico>/ přes STS credentials z /storage/token.


8. Klíčové soubory v hlavním repu (avax-platform)

Pokud druhý Claude pracuje v vendor repu, NEMÁ přístup k hlavnímu repu. Tahle sekce je referenční — kdyby user kopíroval kód.

  • backend/app/routers/app_management.py:147POST /create endpoint (rozšířený o vendor role)
  • backend/app/services/gitea.py — Gitea API klient (create_repo, push_template, _replace_placeholders, inject_publish_secrets, set_repo_secret)
  • tools/avax-app-template/ — skeleton (tento dokument popisuje co je v něm)
  • backend/migrations/versions/026_vendor_self_service.py — datový model (companies.is_vendor, apps.vendor_company_id)
  • desktop/launcher2/screens/vendor_dev.py — UI "Můj vývoj" tab + wizard

9. Gitea CI — gotchas (NEMĚŇ bez důvodu)

Gitea verze produkce: 1.21.7. Z toho plynou pravidla pro .gitea/workflows/*.yml:

  • NIKDY workflow_dispatch: — Gitea 1.21 parser ho odmítne, celý workflow je invalidní → 0 runs, žádná chyba (tichý CI výpadek). Až ≥ 1.22.
  • Žádné Actions REST API v 1.21 — stav CI sleduj přes web UI, ne API.
  • Runner běží v host módu (avaxdev jako user avax, bez rootu). Workflow step volající apt-get / vyžadující root SELŽE (Permission denied). Drž instalace deps uvnitř docker build (build kontejner má root), nebo používej předinstalované deps (Python 3.13 + pip má runner).
  • paths: filtr — workflow se spustí jen když commit mění daný path. Drobný commit (README.md) CI netriggeruje. Není to bug.
  • Image se zatím NEpushuje do registry — per-app kontejner deploy na avaxdev je docker rm -f <name> && docker run … <image>:<tag> (NE docker restart).
  • Rezervované secret prefixy: GITEA_*, GITHUB_* Gitea zakazuje (PUT .../secrets/GITEA_TOKEN → 400). Pokud potřebuješ token na klonování jiného privátního repa (např. claudAI/avax-platform kvůli avax-auth): vytvoř secret pod ne-rezervovaným jménem (např. AVAX_AUTH_TOKEN) a ve workflow použij --build-arg GITEA_TOKEN=${{ secrets.AVAX_AUTH_TOKEN }}.
  • Runner scope: repa v org avax-apps obsluhuje runner avaxdev-2 (act_runner2). Standardně to "prostě funguje" jakmile má repo has_actions=true (nastaví backend create_app flow).

10. Onboarding druhého Claude (návod pro user)

User chce, aby druhý Claude (v repu konkrétní aplikace) měl tyhle znalosti.

Krok 1 — druhý Claude přečte: - CLAUDE.md v root vendor repa (existuje v každém repu klonovaném z templatu — obsahuje detail o IPC, API, struktuře projektu). - Tento dokument (docs/spec/vendor-quickstart.md v hlavním repu) — kdyby user neměl plnou přístup, stačí zkopírovat obsah do nového souboru ve vendor repu.

Krok 2 — když druhý Claude pomáhá vendor user:

Vendor zadání Druhý Claude udělá
"Inicializuj novou aplikaci" Repo už je vytvořené z platformy (Můj vývoj wizard). Druhý Claude jen edituje src/main.py podle popisu app.
"Přidej feature X" Edit src/main.py, případně nový src/<modul>.py. Aktualizuj manifest.json (slug, popis), requirements.txt.
"Publishni" git commit && git push origin main — Gitea Actions zbytek vyřeší. Bump version.py.
"Bumpni verzi" Edit version.py:VERSION (semver) + BUILD_DATE.
"Vyřeš chybu v CI" Načti runner log na avaxdev (/var/log/act_runner*.log) — vendor nemá přístup, hlas user.

Krok 3 — co druhý Claude NIKDY nedělá: - NIKDY nemění src/avaxis_sdk.py — vendored, kompatibilita s launcherem. - NIKDY git push --force na main bez explicitní authorizace. - NIKDY ne-commitne .env (.env.example ano). - NIKDY nepřidává workflow_dispatch: do .gitea/workflows/*.yml.


11. Reference

  • Hlavní repo: git.avaxis.cz/claudAI/avax-platform
  • Skeleton: tools/avax-app-template/
  • Spec katalogu: docs/spec/app-catalog.md
  • Spec distribuce: docs/spec/app-distribution.md
  • Vendor onboarding (gitea teams): docs/spec/vendor-onboarding.md
  • Per-app container architektura: docs/spec/per-app-container.md

Live verze tohoto dokumentu: https://git.avaxis.cz/claudAI/avax-platform/raw/branch/master/docs/spec/vendor-quickstart.md