Handoff

Цель: новая сессия должна за 5 минут понять где остановились и продолжить. Читай в порядке: этот файл → Rules.mdImplementation_Workflow.md → конкретная Phase.


TL;DR

Phase 0-14 🟢 done. MVP scope §IV почти полностью покрыт. Live + работает. Phase 15-16 осталось: Onboarding → Production readiness (~8 дней).

Side feature: URL-import (master spec v1.3 §V unparked) — architecturally complete, parked для V1 launch decision:

  • Pipeline (Phase 1+5+6+10): packages/url-import-extractor — works on real sites (~70-80% coverage для small-biz target)
  • Backend: 5 API endpoints, 3 DB migrations (0007-0009)
  • Frontend: /app/imports list + detail + edit + preview
  • 95 tests passing
  • 12 ADRs (0007-0018) documenting all design decisions
  • См docs/url_import_spec.md, docs/runbooks/url_import_deployment.md
  • Pending: legal review (lawyer ~$500-1000), production DB migration, deploy
  • Decision: shipped as separate small-biz onboarding path OR rolled into Phase 15 main wizard

Live infrastructure

ServiceURLNotes
Frontend (CF Pages)https://arno-ijr.pages.dev (opens in a new tab)static export Next.js, auto-deploy on push
Backend (CF Workers Paid)https://arno-api.vadimpianof.workers.dev (opens in a new tab)Hono + Drizzle Neon HTTP driver
DB (Neon Postgres 17)ep-dry-block-al36bkvg.c-3.eu-central-1.aws.neon.tech/neondbFrankfurt, free tier
ARNO repo (GitHub)https://github.com/vadimpianov/arno (opens in a new tab)main branch auto-deploys via CF git integration
AlfaBank repo (GitHub)https://github.com/vadimpianov/- (opens in a new tab)имя - (был а, нормализовано)
AlfaBank gh-pageshttps://vadimpianov.github.io/-/arno-bundle.js (opens in a new tab)render adapter bundle, GH Action rebuild on push
Liveblocks dashboardhttps://liveblocks.io (opens in a new tab)project arno, region Earth, env Development

Secrets / credentials map

Wrangler secrets (на CF Workers, arno-api):

  • DATABASE_URL — Neon connection string
  • GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET — для user OAuth (Phase 9)
  • JWT_SECRET — 256-bit hex, HS256 signing
  • LIVEBLOCKS_SECRET_KEY — для room auth (Phase 11)

Local .dev.vars (apps/api/.dev.vars, gitignored) — те же ключи для wrangler dev.

Frontend env vars: нет. Liveblocks public key не используется (authEndpoint flow).

CF Pages dashboard: project arno, env vars: NODE_VERSION=20, PNPM_VERSION=11.1.3.

GitHub OAuth App (для user sign-in, Phase 9):

  • Application ID/Client ID: Ov23liPTOBHJwGiboeoc
  • Callback URL: https://arno-api.vadimpianof.workers.dev/auth/github/callback
  • Device Flow: enabled (для Phase 13 CLI)

ARNO GitHub App (Phase 13 sync, separate entity!):

  • Name: arno-dev-vadimpianov
  • App ID: 3810588
  • Client ID: Iv23li8Ime5iRYpMDc4U
  • Installation ID: 134630026 (на vadimpianov/- repo)
  • Webhook URL: https://arno-api.vadimpianof.workers.dev/webhooks/github
  • Permissions: Contents R/W, Pull requests W, Webhooks R/W, Workflows R/W, Packages R/W, Metadata R
  • Events: push, pull_request
  • Private key + webhook secret в Workers secrets (GITHUB_APP_PRIVATE_KEY, GITHUB_APP_WEBHOOK_SECRET)

Account ownership (SPOF — see master spec §III.2.9)

  • GitHub username: vadimpianov (был ChrisPianof, переименован)
  • CF account: vadimpianof@gmail.com
  • Neon account: GitHub OAuth (vadimpianov)
  • Liveblocks: GitHub OAuth (vadimpianov)
  • Single-owner risk для всех — Phase 16 launch checklist требует multi-owner CF + secrets backup в 2 password managers.

Architecture decisions (ADRs)

Все в docs/adr/:

  • 0001 — Static export Pages сейчас, edge adapter когда Auth/API
  • 0002 — Module-level stores + useSyncExternalStore (composition/library/workflow)
  • 0003 — Design-system source: GitHub Contents API + raw URLs (не local snapshot)
  • 0004 — Render adapter postMessage protocol v1 (iframe sandbox)
  • 0005 — Dedicated Worker arno-api, не Pages Functions
  • 0006 — Backend-driven OAuth (deviation от master spec §III.2.6) — Auth.js не работает со static export

Monorepo layout (стабильный)

apps/
  web/     — Next.js 14 App Router (CF Pages, static export)
  api/     — Hono + Drizzle (CF Workers Paid)
packages/
  shared/         — domain types + pure functions (no React)
  editor/         — md-parser + store classes (composition/library)
  render-adapter/ — typed postMessage protocol
  db/             — Drizzle schema + Neon HTTP driver
tools/
  tsconfig/       — base, nextjs, node
  eslint-config/  — base, next
  migrate/        — Drizzle Pool driver runner (CI/local)
docs/
  adr/            — 0001-0006 architecture decisions
  development.md, cloudflare-pages.md

CI: .github/workflows/ci.yml (typecheck + lint + test + build). AlfaBank: .github/workflows/arno-build.yml (bundle → gh-pages).


Что 🟢 в DB

Текущий schema (6 migrations applied):

  • user (Phase 9, GitHub OAuth)
  • project + project.owner_id FK
  • workflow (nodes/edges JSONB — Postgres mirror, primary в Liveblocks Yjs)
  • screen_composition (instances JSONB)
  • project_share_link (Phase 10)
  • component_md_raw + component_md_versions + trigger purge_old_md_versions() AFTER INSERT OFFSET 20 (Phase 12)
  • connected_repo + session_branch_state (Phase 13)

Что задеплоено backend (arno-api)

EndpointAuthPurpose
GET /healthpublicliveness
GET/POST /auth/github/*, /auth/me, /auth/logoutmixedOAuth flow + Bearer JWT issue/revoke
GET /api/v1/me/projectsBearerper-user list
POST /api/v1/projectsBearercreate
DELETE /api/v1/projects/:idBearer + ownershipdelete
POST /api/v1/projects/:id/shareBearer + ownershipgenerate share link
GET /api/v1/projects/:id/sharesBearer + ownershiplist
DELETE /api/v1/shares/:idBearer + ownershiprevoke
GET /api/v1/public/share/:tokenpublicviewer snapshot
GET/PUT /api/v1/workflow/:idBearer + ownershipPostgres mirror (primary в Liveblocks)
GET/PUT /api/v1/compositions/:id/:screenIdBearer + ownershipcomposition CRUD
POST /api/v1/liveblocks/authBearer + ownershiproom auth, returns session token
GET/PUT /api/v1/projects/:id/md?path=Bearer + ownershipMD load + save с 409 conflict
GET /api/v1/projects/:id/md-versions?path=Bearer + ownershiplast 20
GET/POST /api/v1/projects/:id/syncBearer + ownershipPhase 13 — push pipeline + status
POST /webhooks/githubHMAC-verifiedGitHub webhook handler (push to main resync)
GET/POST /debug/github/*, /debug/projects/:id/syncENVIRONMENT=developmentPhase 13 acceptance helpers (ping, deliveries, redeliver, merge-pr)

Что в frontend routes

/                        — landing (sign-in CTA если no JWT)
/app                     — projects list (после sign-in)
/app/workflow?project=   — workflow editor (Liveblocks room)
/app/screen?project=&id= — composition editor
/app/screen/preview?...  — preview iframe (AlfaBank bundle)
/app/component?project=&path= — MD editor (Phase 12)
/share?token=            — public viewer (read-only canvas)
/share/preview?token=&id= — public prototype walk

✅ Phase 13 — Sync с репой (write-back) — DONE

All 7 acceptance criteria verified live on vadimpianov/- repo:

  • Push pipeline: blob+tree+commit via Git Data API, session-branch arno/{user-login}
  • Auto-PR creation на first push (PR #1 was the test); reuse same PR on subsequent pushes
  • KV mutex push_lock:{project}:{branch} EX 60s prevents concurrent races
  • Pre-push HEAD check vs session_branch_state.last_known_push_sha — 409 head_diverged response
  • Webhook handler verifies HMAC-SHA-256, dedup via pushed_by_us:{sha} KV (TTL 5min)
  • On main push: resyncs changed MD files (added/modified) → component_md_raw, updates connected_repo.last_synced_sha

Frontend integration (debounce 30s, UI prompt для divergence, sync button) — Phase 14+ когда мы строим editor UX. Backend exposes ready endpoints.

Что НЕ сделано в Phase 13:

  • Frontend integration (sync button, divergence modal, debounce trigger)
  • Rate limiter (KV token bucket, 12,500/hour budget per §I.3.8) — defer пока traffic малый
  • GraphQL bulk initial scan — defer до Phase 15 (onboarding flow с реальным connected_repo)
  • Webhook job queue (DAG ordering, retries) — defer до Phase 16 (single project sequential ok)
  • installation / installation_repositories events — ack'нуты но не обработаны (Phase 15 onboarding)
  • pull_request events с PR merged/closed → cleanup session_branch_state — Phase 14+

✅ Phase 14 — Drift detection + CI — DONE

Implementation в commit 26cba92 feat: Phase 14 — drift detection backend + frontend:

  • ✅ DB schema componentDrift (status + details + commit_sha + check_run_id)
  • apps/api/src/webhooks.ts — check_run event handler (lines 119+, "ARNO drift check" name match)
  • apps/api/src/sync.ts — GET /api/v1/projects/:id/drift endpoint
  • apps/api/src/init-templates.ts — generates .github/workflows/arno-check.yml + arno-check.mjs checker
  • ✅ Frontend library-panel.tsx reads drift status, shows tooltip
  • ✅ 5 statuses (green/yellow/red/purple/gray)
  • ✅ Per-component opt-out via MD frontmatter

Что НЕ verified end-to-end на live repo: не было real PR с drift detection observed. Phase 15 onboarding flow создаст first connected_repo с workflow installed → first real test.


⬇️ Phase 15 — Onboarding flow — NEXT

Days: 3. Goal: Full first-run UX from sign-up к unblocked editing.


Phase 16 launch checklist key items (для context)

Per master spec §VII.2 — нужно перед public launch:

  • All MVP scope §IV implemented (Phase 0-15 cover)
  • Test coverage 90% critical paths
  • Lighthouse a11y >90, bundle <4MB
  • Multi-owner CF account + DNS TTL 300s + secrets в 2 password managers
  • All PAGE alert runbooks написаны
  • DPAs signed с vendors (CF, Neon, Liveblocks, Sentry, Grafana, Resend)
  • GDPR data export/delete endpoints
  • ToS + Privacy Policy published

Quick test plan (verify state в новой сессии)

# Backend liveness
curl https://arno-api.vadimpianof.workers.dev/health
# → {"ok":true,"ts":...}
 
# Frontend live
curl -I https://arno-ijr.pages.dev/
# → HTTP/2 200
 
# AlfaBank bundle
curl -I https://vadimpianov.github.io/-/arno-bundle.js
# → HTTP/2 200, ~395KB
 
# DB schema (если хочется проверить)
DATABASE_URL='postgresql://neondb_owner:npg_MIbePNd5BQ2l@ep-dry-block-al36bkvg.c-3.eu-central-1.aws.neon.tech/neondb?sslmode=require' \
  pnpm --filter @arno/migrate generate
# должно сказать "No changes detected"

Если всё 🟢 — стек целый, можно сразу в Phase 13.


Если что-то сломалось

  1. CF deploy failedgh run list --repo vadimpianov/arno --limit 3
  2. API 500wrangler tail --config apps/api/wrangler.toml (live logs)
  3. DB unavailable — Neon dashboard https://console.neon.tech (opens in a new tab) (auto-suspend free tier — open проект чтобы wake up)
  4. Liveblocks broken — dashboard → твой project → connection status
  5. Bundle outdated — push в AlfaBank → GH Action перебилдит за ~1 min

Last updated: session ending после Phase 14 done + URL-import V1 architecturally complete (parked). URL-import status: см TL;DR + docs/url_import_spec.md. Phase 14 backend + frontend committed (26cba92); end-to-end test pending первый real connected_repo при Phase 15.