ADRs
ADR 003 — Design-system source: local snapshot → GitHub API
  • Date: 2026-05-20
  • Status: Accepted (replaces interim local snapshot)
  • Phase: 5

Context

Phase 5 requires замены mock library на реальную AlfaBank design-system. Implementation_Workflow допускает оба варианта: GitHub API или "local file fetch для MVP".

Изначально AlfaBank repo был только локальный (без GitHub remote). Сделали snapshot apps/web/public/design-system/*.md → fetch через relative URL. После публикации AlfaBank на github.com/ChrisPianof/- переключились на GitHub Contents API + raw URLs.

Decision

GitHub Contents API + raw.githubusercontent.com для fetch'а:

const url = `https://api.github.com/repos/${OWNER}/${REPO}/contents/${PATH}?ref=${BRANCH}`;
const items = await fetch(url).then(r => r.json());  // listing
const mdFiles = items.filter(i => i.type === "file" && i.name.endsWith(".md"));
const parsed = await Promise.all(mdFiles.map(i => fetch(i.download_url).then(r => r.text())));
  • 1 запрос Contents API (rate-limited 60/hr unauthenticated, OK для browsing)
  • N запросов к raw CDN (НЕ учитывается в API rate limit)
  • CORS * на обоих endpoints
  • IDB cache layer (arno-local DB, library store) — instant UI, offline-safe

Hardcoded в design-system-loader.ts: OWNER=ChrisPianof, REPO=-, BRANCH=main, PATH=Design_system.

Consequences

Pros:

  • Real source of truth — изменение MD в AlfaBank → push → ARNO видит в следующем fetch (через cache invalidation)
  • Auto-discovery новых components — добавь файл с id/name frontmatter + fenced block → появится в library
  • Никаких manual sync скриптов
  • Cache layer = offline-safe + rate-limit-safe

Cons:

  • Hardcoded repo coords — Phase 13 (Sync с репой) сделает per-project через .arno/config.jsonconnected_repo table
  • Без auth — 60/hr Contents API limit. При активной разработке (multi-tab + hard refresh) можно упереться. IDB cache mitigates.
  • Зависит от GitHub uptime — fallback к IDB cache или к FALLBACK_LIBRARY (mock из Phase 3)

MD format contract

---
id: cmp-<name>-001
name: ComponentName
---
 
<!-- arno:props v1 -->
- id: p_<name>
  name: <name>
  type: string | enum
  default: "..."
  textEditable: true  # optional, only on string
  values: [a, b, c]   # only on enum
<!-- /arno:props v1 -->
 
<!-- arno:slots v1 -->
- id: s_<name>
  name: <slot_name>
<!-- /arno:slots v1 -->
 
# Human-readable docs ниже...

MD без frontmatter → парсер возвращает null → игнорируется в library.

Related files

  • packages/editor/src/md-parser.ts
  • apps/web/src/lib/design-system-loader.ts
  • apps/web/src/components/persistence-loader.tsx (вызывает loader на mount)
  • AlfaBank: Design_system/Buttons.md, Input.md, TitleView.md, BackgroundPlate.md (4 augmented)