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:
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/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¶
- Naklonuj template (
tools/avax-app-template/z avax-platform) - Edituj flavory podle publika (aspoň
user, dev/admin volitelné): docs/user/index.md+prvni-kroky.md— koncový uživateldocs/dev/index.md— vývojář/integrátor (API, SDK, connectory)docs/admin/index.md— superadmin (onboarding, provoz, RBAC, limity)- Anchory v každém H2/H3:
## Section { #id } - Commit + push do vendor repo (
avax-apps/<slug>-app) - Do 15 min se každý flavor objeví ve svém tabu:
https://docs.avaxis.cz/user-guide/apps/<docs_slug>/https://docs.avaxis.cz/dev/apps/<docs_slug>/https://docs.avaxis.cz/admin/apps/<docs_slug>/- 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.jsonna 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-failednebono-docspro 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í tamdev/admin? → vendor nemá odpovídající subdir. Musí to být adresářdocs/dev//docs/admin/(nedocs/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).
Anchor #some-id v ⓘ link 404¶
- 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