Files
baya-monorepo/docs/_plan/phase-0-inventory-and-scaffold.md
T
2026-07-29 23:20:46 +03:30

12 KiB
Raw Blame History

Phase 0 — Inventory & scaffold

Depends on: nothing · Blocks: every other phase · Size: one session

Goal

Before anything is moved, merged, or deleted, produce two things:

  1. A disposition for every one of the ~260 markdown files in the repo — so that "summarize without losing data" is a checkable claim rather than a hope.
  2. The empty docs/ skeleton with a real entry point, so later phases have somewhere to write.

Plus one piece of housekeeping every later phase needs: a fresh OpenAPI snapshot, because the committed one is 16 days behind the server code.

This phase writes almost no prose. It is a survey.


Inputs

  • The whole repo. Specifically: dev/ (199 files), product/ (48), root (4), client/ (5), server/ (6), telegram-otp-bot/ (2), .claude/skills/ (1), .githooks/ (1).
  • ../README.md — the target tree and the decisions.

Outputs

File What it is
docs/_plan/inventory.md The disposition table — every markdown file, one row
docs/README.md The single entry point: a map of docs/, product/, archive/ and what belongs where
docs/rules/index.md docs/integration/index.md docs/flows/index.md docs/status/index.md docs/roadmap/index.md Stub indexes, each with a one-line purpose and a "populated by phase N" note
docs/integration/openapi/swagger.v1.json Regenerated from the running server
docs/_plan/open-contradictions.md Running list of doc-vs-doc and doc-vs-code conflicts spotted during the survey — later phases resolve these

Steps

1. Build the inventory

Walk every .md file (exclude node_modules, bin, obj, .git). For each, record:

Column Meaning
path repo-relative
bytes size
last commit git log -1 --format=%ad --date=short -- <path>
kind rule · reference · contract · plan · report · history · business · ops · feedback
disposition keep-as-is · move · distill · merge-into · archive · delete
target where its content ends up (a docs/… path, or archive/…)
owner phase which phase (17) handles it
live facts? yes / no — does it contain anything not yet captured elsewhere?

Rules for assigning disposition:

  • dev/phases/backend/* and dev/phases/frontend/* (32 files, ~1 MB): these are prompts that were already executed. Disposition archive. But scan each for decisions and constraints stated in the prompt that are not visible in the code — those are live facts: yes and go to Phase 1 (if a rule) or Phase 4 (decisions.md).
  • dev/shared-working-context/reports/* (50 files): archive, but every "Follow-ups for later phases" / "Deferred" / "Known gap" section is a live fact for Phase 4. Extract the section headings now; Phase 4 reads them in detail.
  • dev/shared-working-context/*/STATUS.md (86 KB combined): distill → Phase 4 (decisions.md
    • implemented.md), then archive.
  • dev/shared-working-context/frontend/requests/for-backend.md (67 REQs): distill → Phase 4.
  • dev/post-phase/hardening/issues.md (18 open items): distill → Phase 4, with re-verification — the UI and refinement chains ran after this file was written and some items are probably already fixed.
  • dev/contracts/**: movedocs/integration/ — Phase 2 owns it, and refreshes it against code.
  • dev/post-phase/manual-testing-plan.md + refinement/RUNBOOK.md: distill → Phase 3 (docs/flows/testing-setup.md + the per-flow files). Both are stale on secrets handling.
  • dev/manual-testing/iteration-*/: distill → Phase 4 (unfinished items) then archive (keep the PNG screenshots — they are the only visual record of the pre-overhaul UI).
  • product/**: keep-as-is, every one. Not this chain's business.
  • client/CLAUDE.md, server/CLAUDE.md, server/CONVENTIONS.md, client/messages/STYLE.md, dev/phases/_shared/*, dev/contracts/conventions/*, .claude/skills/*/SKILL.md: distill → Phase 1.
  • DEPLOY.md: keep-as-is at root (it is the deploy procedure and it is current) — but Phase 2 fixes its stale user-secrets reference and Phase 2's topology.md links to it.
  • Prompt.md (0 bytes): delete.
  • temp/swagger.json (stale duplicate): delete — Phase 2 replaces it.
  • client/graphify-out/GRAPH_REPORT.md, server/graphify-out/GRAPH_REPORT.md: generated tool output. Decide keep-as-is if the tool is still used, else delete; check .gitignore first.

2. Log contradictions as you go

Write docs/_plan/open-contradictions.md with one row per conflict: claim A (file:line) vs claim B (file:line or code:line) — unresolved. Seed it with the ones already known:

  • user-secrets is required (18 files) vs user-secrets was removed and the store isn't read (root CLAUDE.md §6, commit 5885280).
  • dev/contracts/ describes the API (frozen 2026-07-13) vs server/src (through 2026-07-28).
  • Design language in .claude/skills/frontend-designer/SKILL.md §§17 vs client/CLAUDE.md "Theme System" / "Anti-patterns" — overlapping, possibly divergent.
  • Both vs the reality after iterations 12 (mobile-scoped shell, bottom nav, react-hook-form, new icon set) — the skill predates that overhaul.
  • 18 hardening items open (2026-07-16) vs UI phases 013 and the deploy commits that ran after.

Do not resolve these here. Phase 0 only finds them.

3. Regenerate the OpenAPI snapshot

Boot the server and capture the live swagger document:

cd server && dotnet run --project src/API/Baya.Web.Api/Baya.Web.Api.csproj
# then, from another shell:
curl -sk https://localhost:5002/swagger/v1/swagger.json -o docs/integration/openapi/swagger.v1.json

Record in the file's sibling README.md: the date, the commit, and the endpoint count. Diff the endpoint paths against the old dev/contracts/openapi/swagger.v1.json and write the added/removed list into docs/_plan/open-contradictions.md — Phase 2 uses it as its worklist.

If the server will not boot (config, DB reachability), stop and report rather than guessing. A stale snapshot is what caused half of this mess.

4. Scaffold docs/

Create the directories and stub index files from the target tree in README.md. Each stub is ~10 lines: what lives here, which phase fills it, and a > Populated by phase N — not yet written banner. docs/README.md is the only one with real content: the map, and the product/ vs docs/ vs archive/ rule.

Do not create archive/ yet — Phase 6 does that, once there is something safe to put in it.


Verification

  • docs/_plan/inventory.md has a row for every .md file the survey walked; the count matches find . -name "*.md" -not -path "./node_modules/*" … | wc -l (~260 at baseline).
  • No row has an empty disposition or owner phase.
  • Every row with live facts: yes names the phase that will extract them.
  • docs/integration/openapi/swagger.v1.json exists and its endpoint count is recorded.
  • Every stub index exists and says which phase fills it.
  • Nothing outside docs/ was modified, except deleting Prompt.md and temp/swagger.json.

Definition of done

You can answer, for any markdown file in the repo, "where does this end up and who handles it?" without re-reading the file.

Handoff

Run 2026-07-29 against commit c99e3f4. All six outputs delivered; all six verification boxes pass.

Counts

Planned Actual
Markdown files surveyed ~260 275 (273 tracked + 2 gitignored graphify-out/GRAPH_REPORT.md)
dev/ 199 199 ✓
dev/shared-working-context/reports/ 50 53 reports + README.md + mocks-registry.md
`dev/phases/backend frontend` prompts 32
REQs in for-backend.md 67 67 ✓
Hardening items 18 open 18 of 18 unticked ✓
product/ 48 48 ✓

The extra 15 over "~260" are the 9 files of docs/_plan/ itself, the 2 gitignored graph reports, and 3 more reports than the plan counted.

Disposition split: 172 archive · 59 keep-as-is · 24 distill · 17 move · 2 merge-into · 1 delete. 209 of 275 carry live facts. Owner phases: 4 → 149 files, 7 → 31, 2 → 23, 1 → 17, 6 → 17, 3 → 2, 0 → 1, none → 35.

Four things that change a later phase's scope

  1. Phase 2 is smaller than budgeted at the OpenAPI layer. The 16-day-stale snapshot differs from the live server by one endpoint (POST /api/v1/webhooks/payouts/{provider}) and one schema (GeneratePayoutBatchCommand). Zero removals, zero method changes, identical schema count (339). Spend the budget on the 17 hand-written domains/*.md instead — that is where drift can hide, and nothing has ever checked them mechanically.

  2. Phase 3 fixes one stale bring-up doc, not two. The plan says manual-testing-plan.md and RUNBOOK.md are both stale on secrets. RUNBOOK.md was updated in 5885280 and is correct — it even has a troubleshooting row for the error you now get. Only manual-testing-plan.md (last commit bd06ef0, the day before) still instructs dotnet user-secrets. But Phase 3 inherits a bigger bring-up problem the plan did not list: contradictions C-3/C-4/C-5 — the API is http://, not https://, in ~18 places; the dev-certs step is therefore dead; and RUNBOOK.md builds a local Docker SQL Server while the committed dev config uses a remote, already-seeded one. Those are two different worlds and Phase 3 must pick one and walk it.

  3. Phase 7's premise is wrong in one direction and right in another. The frontend-designer skill does not predate the UI overhaul — it was rewritten at baa3cc6 (manual improvement 1) and already covers AppFrame, BottomBar, APP_FRAME_MAX_WIDTH and the Lucide-only registry. It is stale by exactly one iteration: client/CLAUDE.md was updated at e6a8f93 (manual improvement 2), which changed 44 files, +3419/2449 under client/src. Diff against iteration 2, not against the whole overhaul.

  4. Phase 4 is the heavy phase, not Phase 3. 149 of 275 files land on it. Two structural findings make it tractable: every dev/phases/* prompt shares a fixed layout where §5 "Critical rules you must not get wrong" is exactly the not-in-the-code decision set (verified in all 32), and all 53 reports carry a "Follow-ups for later phases" section (verified). Both are mechanically extractable.

Smaller notes

  • temp/swagger.json was never committed.gitignore:1 ignores temp. Deleting it removed local clutter, not repo content. The _plan/README.md diagnosis calls it a "second stale copy" in the repo; it is not in the repo.
  • dev/contracts/domains/messaging.md (851 B) is a headerless fragment that silently amends messaging-notifications-admin.md. Phase 2 should merge, not move both (C-8).
  • SET_VIA_USER_SECRETS_OR_ENV is still the placeholder string in appsettings.json and is enforced by StartupSecretsGuard and the pre-commit hook. Behaviour is correct; the name instructs a reader to use a store that no longer exists (C-2).
  • The graphify-out/ reports are gitignored generated output, so the plan's "decide keep or delete" is moot — they are not repo content and were left alone.
  • Leaf directories are not pre-created. docs/rules/{shared,client,server}/ and docs/integration/domains/ are named in their index stubs but not made on disk: git does not track empty directories, so an empty scaffold would silently vanish. Each phase creates its own with its first file.
  • Server boot gotchas worth reusing (recorded in docs/integration/openapi/README.md): it binds HTTP, first boot takes ~40 s because Development migrates and seeds against the remote DB, and curl to localhost returns 502 unless you pass --noproxy '*'.

Contradictions

14 logged in open-contradictions.md, including a corrections section covering the three seeded claims that did not reproduce as stated. Phase 0 resolved none, by design.