feat(#67): /handover generates a stub C4 L2 container diagram#70
Conversation
Adds step 6 to /handover: after writing the assessment, emit a stub projects/<name>/architecture/container.md derived from repo signals. Detection table covers five container slots + external-system inference: - web (Next.js / React/CRA / Vite / Remix / SvelteKit / Nuxt / Angular / src/components heuristic) - api (Express / Fastify / Hono / NestJS / Koa / Next.js API routes / Go+gin / FastAPI / Django / Flask / Rails / Sinatra / Rust+axum / actix / rocket / fiber / chi / echo) - worker (BullMQ / bee-queue / agenda / Inngest / workers/ dir / Celery) - db (Prisma schema.prisma incl. provider extraction / Drizzle / Knex / DATABASE_URL protocol sniff / Supabase / Firestore) - cache (ioredis / redis / @upstash/redis / memcached / memjs, REDIS_URL / UPSTASH_REDIS_URL .env hints) - queue (SQS SDK / kafkajs / amqplib — only when distinct from worker) Externals: Auth0 / Clerk / Supabase Auth / next-auth → Auth Provider; Stripe / Paddle → Payment Processor; Postmark / SendGrid / Resend / SES → Email Provider; S3 / Vercel Blob / R2 → Object Storage; OpenAI / Anthropic / Google AI → LLM API. docker-compose.yml overrides package.json (compose services ARE the containers). Dockerfile-only case: one container with FROM-derived tech label, no fabricated DB. Skip semantics: - Existing architecture/container.md is preserved, NEVER overwritten (rule #11). Team refinements survive re-runs. - Zero signals detected → skip file entirely, note in summary, don't fabricate a diagram. Updated: - Output-location section mentions both files - Summary in step 8 includes architecture/container.md status (written | preserved | skipped) - Rules #11 (never overwrite) and #12 (starting point, not truth) added - Stub file includes a "auto-generated on YYYY-MM-DD — refine me" header so the team knows to review Closes #67
atlas-apex
left a comment
There was a problem hiding this comment.
Code Review: PR #70
Commit: 1df34e5f8a645cb63ee6b3d958892c5016bf2b73
Summary
Doc-only extension of /handover SKILL.md adding step 6 that emits a stub C4 L2 container diagram from repo signals. Six slots (web / api / worker / db / cache / queue) plus five external families, with docker-compose.yml overriding package.json. Skip-if-exists, summary distinguishes written | preserved | skipped, rules #11/#12 protect the stub from overwrite.
Checklist Results
- Architecture & Design: Pass (doc-only)
- Code Quality: Pass
- Testing: N/A (process doc)
- Security: Pass (rule #8
.envnever-read preserved) - Performance: N/A
- PR Description & Glossary: Pass (5 terms)
- Technical Decisions (AgDR): N/A — implements earlier decision (#67, template from #50); no new tech choice
Findings
Detection table (spot-checked):
@auth0/*→ Auth0 — correct (@auth0/nextjs-auth0,@auth0/auth0-react)prisma/schema.prismawithprovider = "postgresql"→ PostgreSQL — correct Prisma datasource syntaxioredis/redis/@upstash/redis→ Redis — correct@aws-sdk/client-sqs→ SQS queue — correct
Next.js web+api collapse logic: Actionable. "Collapse web + api into one container labelled Web App + API" is explicit. The api-row qualifier "same container as web, or split if clearly separate service" is slightly soft — a naive read could emit two — but the dedicated monolith paragraph plus rule #12 disambiguate. Acceptable.
docker-compose precedence: Clear — "When compose and package.json conflict, trust compose."
Skip-if-exists vs skipped: Unambiguous. preserved = file exists, skipped = zero signals. Rule #11 enforces never-overwrite.
Step renumbering integrity: Clean. All internal refs checked (line 181 "step 7", line 250 "step 3", line 457 "step 8", line 493 "step 3"). No stale pointers.
Non-goals boundary: Confirmed — no L1 context stub, no edge inference from code, no Structurizr DSL. Scope discipline held.
Suggestions (non-blocking)
drizzle.config.tsrow leaves<driver>to be filled — consider noting the config uses adialect:field as the hint source.
Verdict
APPROVED (posted as comment — cannot self-approve via GitHub review API)
Reviewed by Rex (Code Reviewer Agent)
Reviewed commit: `1df34e5f8a645cb63ee6b3d958892c5016bf2b73`
…sn't prematurely close (MD031)
…e2resh#70) * feat(me2resh#67): /handover generates a stub C4 L2 container diagram Adds step 6 to /handover: after writing the assessment, emit a stub projects/<name>/architecture/container.md derived from repo signals. Detection table covers five container slots + external-system inference: - web (Next.js / React/CRA / Vite / Remix / SvelteKit / Nuxt / Angular / src/components heuristic) - api (Express / Fastify / Hono / NestJS / Koa / Next.js API routes / Go+gin / FastAPI / Django / Flask / Rails / Sinatra / Rust+axum / actix / rocket / fiber / chi / echo) - worker (BullMQ / bee-queue / agenda / Inngest / workers/ dir / Celery) - db (Prisma schema.prisma incl. provider extraction / Drizzle / Knex / DATABASE_URL protocol sniff / Supabase / Firestore) - cache (ioredis / redis / @upstash/redis / memcached / memjs, REDIS_URL / UPSTASH_REDIS_URL .env hints) - queue (SQS SDK / kafkajs / amqplib — only when distinct from worker) Externals: Auth0 / Clerk / Supabase Auth / next-auth → Auth Provider; Stripe / Paddle → Payment Processor; Postmark / SendGrid / Resend / SES → Email Provider; S3 / Vercel Blob / R2 → Object Storage; OpenAI / Anthropic / Google AI → LLM API. docker-compose.yml overrides package.json (compose services ARE the containers). Dockerfile-only case: one container with FROM-derived tech label, no fabricated DB. Skip semantics: - Existing architecture/container.md is preserved, NEVER overwritten (rule me2resh#11). Team refinements survive re-runs. - Zero signals detected → skip file entirely, note in summary, don't fabricate a diagram. Updated: - Output-location section mentions both files - Summary in step 8 includes architecture/container.md status (written | preserved | skipped) - Rules me2resh#11 (never overwrite) and me2resh#12 (starting point, not truth) added - Stub file includes a "auto-generated on YYYY-MM-DD — refine me" header so the team knows to review Closes me2resh#67 * fix: switch to ~~~ fence to avoid MD001 false-positive from nested backticks * fix: replace nested fenced block with prose instructions (markdownlint MD031) * fix: bump outer template fence to 4 backticks so inner yaml fence doesn't prematurely close (MD031) --------- Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
…e2resh#70) * feat(me2resh#67): /handover generates a stub C4 L2 container diagram Adds step 6 to /handover: after writing the assessment, emit a stub projects/<name>/architecture/container.md derived from repo signals. Detection table covers five container slots + external-system inference: - web (Next.js / React/CRA / Vite / Remix / SvelteKit / Nuxt / Angular / src/components heuristic) - api (Express / Fastify / Hono / NestJS / Koa / Next.js API routes / Go+gin / FastAPI / Django / Flask / Rails / Sinatra / Rust+axum / actix / rocket / fiber / chi / echo) - worker (BullMQ / bee-queue / agenda / Inngest / workers/ dir / Celery) - db (Prisma schema.prisma incl. provider extraction / Drizzle / Knex / DATABASE_URL protocol sniff / Supabase / Firestore) - cache (ioredis / redis / @upstash/redis / memcached / memjs, REDIS_URL / UPSTASH_REDIS_URL .env hints) - queue (SQS SDK / kafkajs / amqplib — only when distinct from worker) Externals: Auth0 / Clerk / Supabase Auth / next-auth → Auth Provider; Stripe / Paddle → Payment Processor; Postmark / SendGrid / Resend / SES → Email Provider; S3 / Vercel Blob / R2 → Object Storage; OpenAI / Anthropic / Google AI → LLM API. docker-compose.yml overrides package.json (compose services ARE the containers). Dockerfile-only case: one container with FROM-derived tech label, no fabricated DB. Skip semantics: - Existing architecture/container.md is preserved, NEVER overwritten (rule me2resh#11). Team refinements survive re-runs. - Zero signals detected → skip file entirely, note in summary, don't fabricate a diagram. Updated: - Output-location section mentions both files - Summary in step 8 includes architecture/container.md status (written | preserved | skipped) - Rules me2resh#11 (never overwrite) and me2resh#12 (starting point, not truth) added - Stub file includes a "auto-generated on YYYY-MM-DD — refine me" header so the team knows to review Closes me2resh#67 * fix: switch to ~~~ fence to avoid MD001 false-positive from nested backticks * fix: replace nested fenced block with prose instructions (markdownlint MD031) * fix: bump outer template fence to 4 backticks so inner yaml fence doesn't prematurely close (MD031) --------- Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
…books Nine new Rex handbooks from @G0maa's review on marsa-cloud/marsa#70: - builder-constructor-defaults — builders seed sensible defaults via constructor - nullable-column-type — nullable columns typed T | null - uuid-primary-key-naming — UUID PKs named uuid, FKs *_uuid - explicit-fk-relation — model relations as typed Ref<Parent> (ref: true) - test-layer-boundaries — unit use-cases, e2e endpoints, no repository unit tests - sinon-stub-instance — stub collaborators with createStubInstance - external-client-seam — one abstract client seam per external service (AgDR-0014) - constants-file — magic values in .constant(s).ts - types-file-placement — shared types in .types.ts Refs #9
Summary
Extends
/handoverwith a new step that writes aprojects/<name>/architecture/container.mdstub alongside the existing handover assessment. Detection covers six slots (web / api / worker / db / cache / queue) plus five external-system families (auth / payments / email / storage / LLM), withdocker-compose.ymloverridingpackage.jsonwhen both exist.What changed
.claude/skills/handover/SKILL.md— adds step 6 "Write the L2 container diagram stub (if missing)" between "Synthesise the assessment" and "Append to the portfolio registry". Subsequent steps renumbered (7 = registry, 8 = summary). Existing cross-refs updated.architecture/container.md: <written | preserved | skipped>.Testing
Doc-only change to the SKILL.md. No executable code; no unit tests.
Validation comes from the next real
/handoverinvocation on a JS/TS project (the detection tables are richest there; Python / Go / Rust / Ruby are covered but not as deeply as Node). The generated file should:c4-container.mdtemplate shapeprojects/<name>/architecture/container.mdalready existsNon-goals / deferred
fetch()calls to infer "api → llm-api") — too much false-positive risk. The skill emits a reasonable first-pass wiring and lets the team refine.Glossary
prisma/schema.prisma→ContainerDb)docker-compose.ymlexists, it supersedespackage.jsonfor composition — compose describes the actual deployment shapeRelated
templates/architecture/c4-container.md)