docs: pivot to modulith with strict service boundaries#59
Conversation
Captures the architectural decision to make every module a service contract from day 1, so extraction is a redeploy rather than a refactor. This is a foundation PR — no production code change yet; subsequent PRs in the rollout (broker, gRPC, per-module DB, EF migrations, deployment) each follow with their own code. - ADR-001, ADR-002, ADR-009 marked superseded; ADR-010..023 added. - ARCHITECTURE.md rewritten: containers include Kafka, Schema Registry, Vault, Grafana stack; per-module DB layout; Identity as remote dependency. - CLAUDE.md P0/P1 rules rewritten for strict service boundaries: cross-module = Kafka event or gRPC; no shared kernel impl; MediatR intra-module only; EnsureCreated forbidden. - patterns.md § Cross-module communication rewritten for Kafka + gRPC pattern with Avro/CloudEvents example. - PROGRESS.md tracks the 5-phase rollout (Phase 0 doc work here; Phase 1-4 in follow-ups). Existing module ✅ states get a "Service-boundary retrofit ⏳" line because the implementation predates ADR-010.
📝 WalkthroughWalkthroughThis PR updates five documentation files to formalize a strict modulith architecture with explicit service boundaries, replacing prior guidance. The changes establish per-module database isolation, event-driven cross-module communication via Kafka (Avro+CloudEvents), gRPC sync escape hatches, JWKS-based local JWT validation, and a phased retrofit roadmap for existing modules. ChangesModulith Service Boundaries & Implementation Roadmap
Sequence Diagram(s)No sequence diagrams generated: this PR is documentation-only, describing architectural principles and governance rules rather than introducing new interactive control flows or system behaviors. Estimated code review effort🎯 2 (Simple) | ⏱️ ~18 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/playbooks/patterns.md`:
- Line 1049: The in-file anchor links pointing to the old heading id
"`#cross-module-data-pattern`" are now stale after renaming the heading to
"Cross-module communication pattern"; update all internal links in this document
that reference "`#cross-module-data-pattern`" to the new anchor (dash-cased form
of the updated heading) so they match the renamed section title (search for
occurrences of "`#cross-module-data-pattern`" and replace with the current
heading's anchor form).
In `@docs/TECH_STACK.md`:
- Line 15: Update the ADR-023 markdown link fragment so it matches the actual
heading anchor used in this document: replace occurrences of
([ADR-023](`#adr-023-per-module-ef-core-migrations-no-ensurecreated`)) with the
correct fragment that corresponds to the heading for ADR-023 (use the exact
slugified heading text used in the file), and apply the same replacement
wherever ADR-023 is linked (e.g., the instance in the Entity Framework Core row
and the other occurrence noted).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: c4082c7d-8669-430b-99de-0ec821b30f79
📒 Files selected for processing (5)
CLAUDE.mddocs/ARCHITECTURE.mddocs/PROGRESS.mddocs/TECH_STACK.mddocs/playbooks/patterns.md
Markdown link check flagged seven broken fragments across CLAUDE.md, ARCHITECTURE.md, PROGRESS.md, TECH_STACK.md, patterns.md, patterns-index.md. Two root causes: - ADR-010..023 headings used em-dashes, slashes, semicolons, and parentheses, so GitHub's slugifier produced anchors that did not match the hand-written links (e.g. the actual slug for ADR-023 was longer than the link target). - patterns.md renamed "Cross-module data pattern" to "Cross-module communication pattern" but in-file and external links still pointed at the old anchor. Rewrite the affected ADR headings to use only letters, digits, and single spaces so the slugifier is deterministic, then update every cross-reference in one bulk pass.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
docs/playbooks/patterns.md (2)
707-707:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate table display text to match the renamed section heading.
Same issue as line 37: the display text says "Cross-module data pattern" but should say "Cross-module communication pattern" to match the actual heading at line 1049.
📝 Proposed fix
-| Another module's data | [Cross-module data pattern](`#cross-module-communication-pattern`) | +| Another module's data | [Cross-module communication pattern](`#cross-module-communication-pattern`) |🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/playbooks/patterns.md` at line 707, Update the table row that currently reads "| Another module's data | [Cross-module data pattern](`#cross-module-communication-pattern`) |" so the link text matches the renamed heading; change the display text "Cross-module data pattern" to "Cross-module communication pattern" (i.e., update the markdown cell containing the linked text for the "Another module's data" row) so the visible label and the anchor "`#cross-module-communication-pattern`" are consistent with the heading.
37-37:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate TOC display text to match the renamed section heading.
The link anchor is correct (
#cross-module-communication-pattern), but the display text still says "Cross-module data pattern" while the actual heading at line 1049 is "Cross-module communication pattern." Update the display text for consistency.📝 Proposed fix
-- [Cross-module data pattern](`#cross-module-communication-pattern`) ★ +- [Cross-module communication pattern](`#cross-module-communication-pattern`) ★🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/playbooks/patterns.md` at line 37, Update the TOC entry text to match the renamed section heading: change the display text "Cross-module data pattern" to "Cross-module communication pattern" for the existing link that points to "`#cross-module-communication-pattern`" so the visible label and the section heading (the renamed heading at line 1049) are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@docs/playbooks/patterns.md`:
- Line 707: Update the table row that currently reads "| Another module's data |
[Cross-module data pattern](`#cross-module-communication-pattern`) |" so the link
text matches the renamed heading; change the display text "Cross-module data
pattern" to "Cross-module communication pattern" (i.e., update the markdown cell
containing the linked text for the "Another module's data" row) so the visible
label and the anchor "`#cross-module-communication-pattern`" are consistent with
the heading.
- Line 37: Update the TOC entry text to match the renamed section heading:
change the display text "Cross-module data pattern" to "Cross-module
communication pattern" for the existing link that points to
"`#cross-module-communication-pattern`" so the visible label and the section
heading (the renamed heading at line 1049) are consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8818ae98-7d6f-4797-bd3b-e85c4cb0ba13
📒 Files selected for processing (6)
CLAUDE.mddocs/ARCHITECTURE.mddocs/PROGRESS.mddocs/TECH_STACK.mddocs/playbooks/patterns-index.mddocs/playbooks/patterns.md
✅ Files skipped from review due to trivial changes (3)
- docs/playbooks/patterns-index.md
- CLAUDE.md
- docs/PROGRESS.md
Same trap as PRs #57/#59 fixed before: em-dash + comma in headings make GitHub's slugify produce unpredictable anchors. Lychee link check caught 3 broken refs across CONTRIBUTING.md, ARCHITECTURE.md, and TECH_STACK.md. Heading rewritten to alphanumeric-only: ADR-025: Transport selection rule by message-name suffix The lesson is in memory/feedback_github_actions_hyphen_expression.md and the playbook entry agent-checklist.md § Chore PRs — I missed applying it when authoring ADR-025 the first time. Anchors swept across 8 markdown files.
Summary
Captures the architectural pivot from "modular monolith that can extract later" to modulith with strict service boundaries — every module is a service contract from day 1, and extraction is a redeploy rather than a refactor. This is Phase 0 of the rollout: docs only, no production code change. Subsequent phases (broker, gRPC, per-module DB, EF migrations, deployment) follow in their own PRs.
Linked spec
Requirements & rules followed
./scripts/check-doc-drift.shgreen; PROGRESS.md updated with rollout plan; ADR cross-links + ARCHITECTURE diagrams referenced where they existTODO/FIXME/ placeholder / stub — implementation is intentionally deferred to subsequent PRs and tracked in PROGRESS.md's phase table, not as TODO markersWhat this PR does NOT do
Axis.Shared— Phase 1Axis.{Module}.Contractsprojects — Phase 2EnsureCreatedtoMigrateAsync— Phase 3The existing implementation continues to work as-is. The "Service-boundary retrofit ⏳" notes on each module in PROGRESS.md track what each module owes the new contract.
Summary by CodeRabbit