Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ NextAurora demonstrates a production-style distributed system with event-driven
> - **Two database engines on purpose.** **CatalogService** + **ShippingService** run on **PostgreSQL** (Npgsql); **OrderService** + **PaymentService** run on **SQL Server** (Microsoft.Data.SqlClient). NotificationService is stateless. The split exercises both EF Core providers and the per-provider primitives the architecture leans on: **Postgres `xmin`** (system column, no schema change) vs **SQL Server `rowversion`** (real column, requires migration) for optimistic-concurrency tokens; **Wolverine's `PersistMessagesWithPostgresql` vs `PersistMessagesWithSqlServer`** for the transactional outbox; **`DistributedLock.SqlServer` (`sp_getapplock`)** for the PaymentRecoveryJob sweeper.

> **How it was built — AI-assisted, multi-model review, verification at every layer.**
> - **Two AI reviewers, not one.** [Claude Code](https://claude.com/claude-code) (Opus 4.7) is the primary pair-programmer — reads [`CLAUDE.md`](CLAUDE.md), the project-specific [`.claude/skills/`](.claude/skills/) (e.g. the `dotnet-performance` skill loaded for EF Core review, `excalidraw-diagram` for architecture visuals), and a persistent project memory. **GitHub Copilot (GPT-5)** sits in-editor for second-opinion diff review, with project conventions encoded in [`.github/copilot-instructions.md`](.github/copilot-instructions.md). Disagreement between the two is treated as a signal to dig deeper, not pick the louder voice. The principle is not "AI wrote it" — it's *two models + a human author + automated checks all sign off before merge*. The working loop: implement → run unit + integration tests → cross-model review → fix → commit.
> - **Two AI reviewers, not one.** [Claude Code](https://claude.com/claude-code) (Opus 4.7) is the primary pair-programmer — reads [`CLAUDE.md`](CLAUDE.md) plus the [`.claude/`](.claude/) folder beside it (agents, [skills](.claude/skills/), [slash commands](.claude/commands/), hook scripts, hook + permission wiring) every session, and a persistent project memory. **GitHub Copilot (GPT-5)** sits in-editor for second-opinion diff review, with project conventions encoded in [`.github/copilot-instructions.md`](.github/copilot-instructions.md). Disagreement between the two is treated as a signal to dig deeper, not pick the louder voice. The principle is not "AI wrote it" — it's *two models + a human author + automated checks all sign off before merge*. The working loop: implement → run unit + integration tests → cross-model review → fix → commit.
> - **Continuous Rule Encoding — the compounding feedback loop.** Every meaningful finding (CodeRabbit catch, test failure, architecture-reviewer agent flag, manual code review, prod incident, even community articles audited via [`/article-audit`](.claude/commands/article-audit.md)) gets the question: *"could the next person repeat this?"* If yes, the rule gets written down at the right tier of an enforcement spectrum — **Convention** (CLAUDE.md + `.claude/`), **PR-review automation** ([`.coderabbit.yaml`](.coderabbit.yaml) + the [architecture-reviewer agent](.claude/agents/architecture-reviewer.md)), or **Mechanical** (build-fail / hook-block / CI-grep). Rules move down the spectrum as they prove their value — the looser the tier, the more you rely on noticing, and noticing always degrades first. CLAUDE.md itself stays lean (~300 lines; CI-guarded soft cap at 400, hard fail at 500); deep dives live in [`docs/`](docs/) and the [`dotnet-performance` skill](.claude/skills/dotnet-performance/SKILL.md). New features run through [`/feature-spec`](.claude/commands/feature-spec.md), which drafts the structured handoff (goal + acceptance + auto-referenced CLAUDE.md constraints) so the spec → implementation → encoding loop stays closed. Full mechanics + the 5 encoding surfaces: [`docs/dev-loop.md`](docs/dev-loop.md); scaffolding diagram: [`docs/dev-loop-scaffolding.svg`](docs/dev-loop-scaffolding.svg).
> - **Verification at every layer.** Build: `TreatWarningsAsErrors` + four build-time analyzers (Meziantou, SonarAnalyzer.CSharp, Roslynator, BannedApiAnalyzers — the last rejects concrete concurrency hazards at compile). Tests: 100+ unit + integration tests, with integration slices for all four DB-touching services via [Testcontainers](https://dotnet.testcontainers.org/) — Catalog (Postgres + Redis), Order (SQL Server + stubbed Wolverine transport), Payment (SQL Server), Shipping (Postgres). Each slice runs as its own step in CI so a single-slice failure doesn't mask the rest. CI: GitHub Actions runs build + tests + Coverlet/Cobertura coverage on every PR. Security: CodeQL on every push + weekly schedule. Dependencies: Dependabot weekly NuGet bumps (grouped per ecosystem). Local dev: Aspire orchestrates Postgres / SQL Server / Service Bus emulator / Redis / Keycloak in Docker so integration issues surface *before* push.
> - **Testing strategy was decided upfront, not retrofitted.** Unit tests cover handlers + domain rules with mocked infrastructure (NSubstitute, FakeTimeProvider). Integration tests use live containers to prove what mocks can't: EF migrations apply cleanly to fresh DBs, HybridCache actually invalidates on write, the `xmin` / `RowVersion` concurrency tokens actually fire under racing writes, Wolverine's transactional outbox + saga handlers actually persist and dispatch. Cross-service E2E over a live Azure Service Bus wire is tracked as deferred in [STATUS.md](docs/STATUS.md). Open issues and other deferred cleanups live there too.

Expand Down
2 changes: 2 additions & 0 deletions docs/dev-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ This is where most code originates. The tooling here shapes proposed edits
| Command | Purpose |
|---|---|
| [/new-feature-slice](../.claude/commands/new-feature-slice.md) | Scaffolds a VSA feature slice matching the [OrderService/Features/PlaceOrder.cs](../OrderService/Features/PlaceOrder.cs) canonical shape. |
| [/feature-spec](../.claude/commands/feature-spec.md) | Drafts a structured feature spec (goal + acceptance + auto-referenced CLAUDE.md constraints) — the handoff between intent and implementation. Feeds the encoding loop. |
| [/article-audit](../.claude/commands/article-audit.md) | Audits an external article (community blog, post, conference talk) against CLAUDE.md and the encoding surfaces — outputs a coverage map + verdict + draft issue body for any gaps. |
| [/sync-status](../.claude/commands/sync-status.md) | Refreshes STATUS.md from `git log` + open issues. |
| [/check-rules](../.claude/commands/check-rules.md) | Audits every `See CLAUDE.md` paraphrase against the canonical rule and flags drift. |

Expand Down
63 changes: 34 additions & 29 deletions docs/dev-loop.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading