Přeskočit obsah

Vendor docs pull-sync

Audience: platform admin (super_admin) + vendor developers

Cíl: Vendor app docs se pravidelně sjednoceně sync do central MkDocs site. Vendor drží 3 flavory (publika) v <repo>/docs/{user,dev,admin}/; každý flavor jde do vlastního central tabu (Uživatelská / Programátorská / Admin). Bez vendor PR cyklu do avax-platform repa.

Proč pull-sync (a ne push)

Tři možné modely:

Model Pro Proti
Pull-sync (tento) Vendor pushne do svého repa, central script pulluje. Unified MkDocs build, jednotná search, RAG corpus integration zachycuje. Central dependency (avaxdev musí mít service account). 15min latency od push k live docs.
Push-trigger (webhook) Real-time propagation. Decoupled. Multi-source MkDocs build složitější. Search napříč rozbitá.
Per-app S3 site Plná decoupling. Style inconsistency. Search broken. RAG composite scrape.

AVAX velikost (predicted 5-20 apps / 2 roky) → pull-sync je nejlepší trade-off. Single MkDocs build = unified styling + global search + RAG corpus z jednoho zdroje.

Konvence vendor docs — 3 flavory (publika)

Docs portál má 3 taby = 3 publika. Vendor drží pro každé publikum vlastní subdir v <repo>/docs/; pull script každý mapuje do jiného central target base:

Flavor (subdir) Publikum / tab Central target
docs/user/ Uživatelská docs/user-guide/apps/<docs_slug>/
docs/dev/ Programátorská docs/dev/apps/<docs_slug>/
docs/admin/ Admin (superadmin) docs/admin/apps/<docs_slug>/

Vendor repo (git.avaxis.cz/avax-apps/<slug>-app):

<repo>/
  docs/
    user/                 ← UŽIVATELSKÁ (→ user-guide/apps/<docs_slug>/)
      index.md            ← landing page
      prvni-kroky.md      ← quick-start
      funkce/             ← per-feature deep dive (volitelné)
        chat.md
        rag-search.md
      faq.md
    dev/                  ← PROGRAMÁTORSKÁ (→ dev/apps/<docs_slug>/)
      index.md            ← integrace / SDK / architektura pro vývojáře
      api.md              ← endpointy, connectory, capability
    admin/                ← ADMIN/superadmin (→ admin/apps/<docs_slug>/)
      index.md            ← onboarding / provoz / RBAC / limity
      provoz.md
    AI_INTEGRATION.md     ← volné root .md (NEPULLOVAT)
    ARCHITECTURE.md
    DEPLOY.md
  src/
  ...

Pull script kopíruje jen flavor subdiry (docs/user, docs/dev, docs/admin) do odpovídajících central target adresářů. Flavory jsou nezávislé — vendor může mít 0–3 z nich (typicky aspoň user). Volné vendor dev guides (docs/*.md v root — ARCHITECTURE.md, DEPLOY.md, …) zůstávají v vendor repo a nejsou public.

Anti-data-loss: Chybějící flavor subdir se přeskočí (status flavoru absent) — jeho existing central target zůstane nedotčený (ochrana proti omylem smazanému subdiru / Gitea outage). Explicit cleanup až s --prune-orphans (future).

STRICT (žádný legacy whole-docs/ copy): Pokud vendor nemá ani jeden flavor subdir (legacy docs/*.md přímo v root), pull script vrátí status no-docs a nic nekopíruje — vendor musí restrukturovat na flavor subdiry. Volné root .md se zásadně nepullují: public exposure + signal/noise (search napříč docs.avaxis.cz by špinil dev internals).

Anchor konvence v markdown

Pro kontextové ⓘ deep linky z UI MUSÍ vendor používat explicit anchory v H2/H3 titulkách (MkDocs Material syntax):

# Funkce X

## Přidání záznamu { #add-record }

Klik na "+ Nový" v levém sidebar...

## Editace záznamu { #edit-record }

...

### Validace { #edit-record-validation }

...

Pak deep link z UI funguje:

# V launcher2 nebo vendor SDK
help_icon(row, doc_path="apps/<docs_slug>/funkce/zaznamy#add-record")

Bez explicit anchorů jsou auto-anchory fragile (vendor přejmenuje titulek → URL se rozbije → ⓘ link selže). Lint script (TODO 1.x) ověří že všechny doc_path z help_registry.json reálně existují.

Pull script (tools/pull_vendor_docs.py)

# Manual run (z avax-platform repo)
export AVAX_API_URL=http://192.168.1.55:8000
export AVAX_LOGIN_EMAIL=docs-sync@avaxis.cz
export AVAX_LOGIN_PASSWORD=<service-account-pw>
export AVAX_GITEA_TOKEN=<gitea-token-s-read-na-avax-apps>
python tools/pull_vendor_docs.py

# Dry-run (bez fs změn)
PULL_VENDOR_DOCS_DRY=1 python tools/pull_vendor_docs.py

Flow: 1. GET /admin/app-management/list → list všech apps 2. Per app s gitea_repo_url: - Lookup last commit hash + seznam syncnutých flavorů v .cache/vendor-docs-sync-state.json - git clone --depth 1 --single-branch master/main <repo> do /tmp/ - Pokud HEAD == last_commit a všechny minule-syncnuté targety pořád existují: skip (idempotent; jinak force re-copy) - Jinak per flavor (user, dev, admin): - <clone>/docs/<flavor>/ existuje → replace příslušný central target (user-guide|dev|admin/apps//) - chybí → absent, existing target preserve (anti data-loss) - Žádný flavor subdir → status no-docs (nic nekopíruje) - Update state file (commit + seznam syncnutých flavorů) 3. Stats output: updated / skipped / no-docs / no-repo / clone-failed + per-app výpis syncnutých flavorů (např. user,dev,admin)

Idempotent: Repeated runs without vendor changes nepřepisují nic.

Tolerantní k failu: Per-vendor clone fail nezablokuje ostatní. Exit code 0 pokud aspoň 1 successful, 1 pokud všechno selhalo.

Systemd timer na avaxdev

Per project_apps_autosync pattern. Existing setup: - Service account docs-sync@avaxis.cz (super_admin, AVAXIS firma) - Heslo v /etc/avax-sync.env (chmod 640 root:avax) - avax-docs-sync.service + avax-docs-sync.timer (15 min interval, Persistent) - Dedikovaný clone /home/avax/avax-platform-docs-sync/

Rozšíření o pull_vendor_docs:

# Update /etc/avax-sync.env (přidat Gitea token)
echo 'AVAX_GITEA_TOKEN=<token>' | sudo tee -a /etc/avax-sync.env

# Vytvořit systemd drop-in override (pro existing avax-docs-sync.service)
sudo mkdir -p /etc/systemd/system/avax-docs-sync.service.d/
sudo tee /etc/systemd/system/avax-docs-sync.service.d/override.conf > /dev/null <<'EOF'
[Service]
ExecStart=
ExecStart=/bin/bash -c 'set -e; git pull --rebase --quiet origin master; /home/avax/avax-venv/bin/python tools/sync_app_docs.py; /home/avax/avax-venv/bin/python tools/pull_vendor_docs.py; if [ -n "$(git status --porcelain -- docs/)" ]; then git -c user.email=avaxdev-sync@avaxis.cz -c user.name=avaxdev-sync add docs/; git -c user.email=avaxdev-sync@avaxis.cz -c user.name=avaxdev-sync commit -m "docs: auto-sync apps + vendor" --quiet; git push --quiet origin master; echo PUSHED; else echo NO_CHANGES; fi'
EOF
sudo systemctl daemon-reload

Důležitý detail: git status --porcelain -- docs/ (NE git diff --quiet) je nutný protože pull script vytváří untracked soubory (nově pulled vendor docs adresáře), které git diff ignoruje. Bez --porcelain check by auto-commit nikdy nezachytil first-time pulled vendor docs.

Pull script + auto-commit + push zaručí že: - avaxdev má dedikovaný clone vždy in-sync - avax-platform repo má commit historii vendor docs changes - MkDocs systemd timer (5min interval, separate) rebuild docs site z pulled content

Pro vendor — quickstart

  1. Naklonuj template (tools/avax-app-template/ z avax-platform)
  2. Edituj flavory podle publika (aspoň user, dev/admin volitelné):
  3. docs/user/index.md + prvni-kroky.md — koncový uživatel
  4. docs/dev/index.md — vývojář/integrátor (API, SDK, connectory)
  5. docs/admin/index.md — superadmin (onboarding, provoz, RBAC, limity)
  6. Anchory v každém H2/H3: ## Section { #id }
  7. Commit + push do vendor repo (avax-apps/<slug>-app)
  8. Do 15 min se každý flavor objeví ve svém tabu:
  9. https://docs.avaxis.cz/user-guide/apps/<docs_slug>/
  10. https://docs.avaxis.cz/dev/apps/<docs_slug>/
  11. https://docs.avaxis.cz/admin/apps/<docs_slug>/
  12. Plus ⓘ ikony v UI mohou linkovat na konkrétní sekce

Gitea token pro service account

Service account docs-sync@avaxis.cz potřebuje Gitea API token s read scope na avax-apps/* org repos.

# Na Gitea web UI:
# Settings → Applications → Generate New Token
# Name: avax-docs-sync
# Scopes: read:repository, read:organization
# Vystavený token uložit do /etc/avax-sync.env jako AVAX_GITEA_TOKEN

Token pro interní avax-platform repo je separátní (per reference_avaxdev_infra_gotchas ho má paincelebrator admin user v c79ca2d...). Service account docs-sync má jiný token jen na avax-apps org.

Troubleshooting

clone-failed pro všechny vendor repos

  • Síťová chyba (Gitea down)? Check curl https://git.avaxis.cz/api/v1/version
  • Token expiroval? Re-vystavit + update /etc/avax-sync.env
  • Vendor repos všechny private + token nemá scope? Update scope na read:repository

Vendor pushne ale docs se neupdatovaly

  • Check .cache/vendor-docs-sync-state.json na avaxdev — má stejný commit hash? Pokud ano, vendor ne-pushnul (nebo pushnul na jiný branch než master/main).
  • Check journalctl -u avax-docs-sync.service -n 30 — vidíš clone-failed nebo no-docs pro daný slug?
  • Smaž state file: rm .cache/vendor-docs-sync-state.json → next run pull vše force.

Jeden flavor (dev/admin) se neobjevil, user ano

  • Per-app výpis v logu ukazuje syncnuté flavory (např. user,dev,admin). Chybí tam dev/admin? → vendor nemá odpovídající subdir. Musí to být adresář docs/dev/ / docs/admin/ (ne docs/dev.md).
  • Flavor byl dřív syncnutý, teď zmizel z výpisu (absent), ale jeho target pořád svítí na webu = anti-data-loss (smazaný vendor subdir target nemaže). Ručně smaž docs/<dev|admin>/apps/<docs_slug>/ (než přijde --prune-orphans).
  • Vendor neměl explicit anchor v markdown — { #some-id } chybí
  • Vendor přejmenoval H2 → auto-anchor se změnil
  • Fix: vendor přidá explicit anchor + push

Související

  • Script: tools/pull_vendor_docs.py (Gitea)
  • Template vendor docs: tools/avax-app-template/docs/user/ (dev/admin flavory analogicky — stejná struktura + anchor konvence)
  • Spec: docs/spec/platform-docs.md
  • ⓘ deep links: docs/dev/help-deep-links.md
  • Sister script (metadata): tools/sync_app_docs.py