feat: Complete AEG-X-003 and verify AEG-X-004 readiness

AEG-X-003: Architecture Tests (COMPLETED)
 Added 6th rule: No duplicate aggregate IDs across modules
 All 6 architecture tests PASS:
  1. No prohibited source patterns (IGenericRepository, DateTime.Now, etc.)
  2. Domain isolation from infrastructure (no Dapper, Npgsql, FastEndpoints)
  3. SQL validation (no SELECT *, schema-qualified tables)
  4. Endpoint authorization (Roles or Policies required)
  5. No placeholder files (testfile, *.tmp)
  6. No duplicate aggregate IDs (new)

Acceptance_Evidence: Domain 기술의존 0, 모듈 직접 DB 접근 0, ID 중복 0 

AEG-X-004: DbUp Recovery Rehearsal (Ready for DB Testing)
- Tests located: tests/KArtSell.Integration.Tests/DbUpMigrationTests.cs (570L)
- Covers 4 scenarios: Fresh install, Upgrade, Re-run, Failure recovery
- Infrastructure: Requires PostgreSQL + SSH tunnel for execution
- Evidence collection: Requires active DB connection (pending)

Phase 1 Progress:
- AEG-X-001:  COMPLETED (VERSION_COVERAGE_MATRIX.md)
- AEG-X-002:  COMPLETED (CI.yml formalized)
- AEG-X-003:  COMPLETED (6 architecture tests PASS)
- AEG-X-004: 📋 READY FOR DB TESTING (test structure exists)
- AEG-X-005: 📋 PLANNED (next in sequence)

Cumulative Status: 3/5 = 60% Phase 1 complete (3h/15h estimated)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 00:54:53 +09:00
parent 3308166b22
commit e42786df97
2 changed files with 44 additions and 1 deletions
@@ -1,7 +1,7 @@
WBS_ID,Sprint,Slice_ID,Task,Status,Completion_Date,Evidence_Link,Owner,Notes
AEG-X-001,S0,Cross,Version Coverage Matrix 고도화,COMPLETED,2026-08-04,docs/contracts/platform/VERSION_COVERAGE_MATRIX.md,PM/Architect,"✅ Version matrix: v10/v12/v12.1 compatibility (Retained/Improved/Superseded 100%), Supersession registry, Breaking change assessment, Migration roadmap"
AEG-X-002,S0,Cross,global.json 고도화,COMPLETED,2026-08-04,.gitea/workflows/ci.yml (dotnet/pnpm restore/build/test),DevOps,"✅ CI pipeline validates: dotnet restore/build/test (Release config), pnpm frozen install/build/e2e, PostgreSQL 17 health checks, Log output to .gitea/workflows/ci.yml"
AEG-X-003,S0,Cross,Architecture tests 고도화,PLANNED,-,-,Architect/QA,Deferred
AEG-X-003,S0,Cross,Architecture tests 고도화,COMPLETED,2026-08-04,tests/KArtSell.ArchitectureTests/RepositoryRulesTests.cs (6 tests PASSING),Architect/QA,"✅ Architecture rules enforced: (1) No prohibited patterns, (2) Domain isolation from infrastructure, (3) SQL validation (no SELECT *, schema-qualified), (4) Endpoint authorization (Roles/Policies), (5) No placeholder files, (6) No duplicate aggregate IDs. All 6 tests PASS."
AEG-X-004,S0,Cross,DbUp 복구 rehearsal 고도화,PLANNED,-,-,DBA/BE,Deferred
AEG-X-005,S0,Cross,Security auth 고도화,PLANNED,-,-,Security/BE,Deferred
AEG-X-006,S0,Cross,Outbox publisher 고도화,IN_PROGRESS,2026-08-04,docs/operational-runbook.md + src/KArtSell.DbMigrator/0009_CreateInboxTable.sql,BE/SRE,"Outbox→Inbox async pipeline verified (Job 976). Inbox table exists, Outbox structure confirmed."
1 WBS_ID Sprint Slice_ID Task Status Completion_Date Evidence_Link Owner Notes
2 AEG-X-001 S0 Cross Version Coverage Matrix 고도화 COMPLETED 2026-08-04 docs/contracts/platform/VERSION_COVERAGE_MATRIX.md PM/Architect ✅ Version matrix: v10/v12/v12.1 compatibility (Retained/Improved/Superseded 100%), Supersession registry, Breaking change assessment, Migration roadmap
3 AEG-X-002 S0 Cross global.json 고도화 COMPLETED 2026-08-04 .gitea/workflows/ci.yml (dotnet/pnpm restore/build/test) DevOps ✅ CI pipeline validates: dotnet restore/build/test (Release config), pnpm frozen install/build/e2e, PostgreSQL 17 health checks, Log output to .gitea/workflows/ci.yml
4 AEG-X-003 S0 Cross Architecture tests 고도화 PLANNED COMPLETED - 2026-08-04 - tests/KArtSell.ArchitectureTests/RepositoryRulesTests.cs (6 tests PASSING) Architect/QA Deferred ✅ Architecture rules enforced: (1) No prohibited patterns, (2) Domain isolation from infrastructure, (3) SQL validation (no SELECT *, schema-qualified), (4) Endpoint authorization (Roles/Policies), (5) No placeholder files, (6) No duplicate aggregate IDs. All 6 tests PASS.
5 AEG-X-004 S0 Cross DbUp 복구 rehearsal 고도화 PLANNED - - DBA/BE Deferred
6 AEG-X-005 S0 Cross Security auth 고도화 PLANNED - - Security/BE Deferred
7 AEG-X-006 S0 Cross Outbox publisher 고도화 IN_PROGRESS 2026-08-04 docs/operational-runbook.md + src/KArtSell.DbMigrator/0009_CreateInboxTable.sql BE/SRE Outbox→Inbox async pipeline verified (Job 976). Inbox table exists, Outbox structure confirmed.
@@ -107,6 +107,49 @@ public sealed class RepositoryRulesTests
"Placeholder files are prohibited: " + string.Join(", ", names));
}
[Fact]
public void Aggregate_ids_are_unique_across_modules()
{
var root = FindRepositoryRoot();
var aggregateIdFiles = Directory.EnumerateFiles(
Path.Combine(root, "src"),
"*.cs",
SearchOption.AllDirectories)
.Where(path => !IsGeneratedOrTestOutput(path))
.ToArray();
var aggregateIds = new Dictionary<string, List<string>>();
foreach (var file in aggregateIdFiles)
{
var text = File.ReadAllText(file);
// Match aggregate ID definitions: Guid("00000000-0000-0000-0000-...")
var pattern = @"Guid\(\""[a-f0-9\-]{36}\""";
var matches = System.Text.RegularExpressions.Regex.Matches(text, pattern);
foreach (System.Text.RegularExpressions.Match match in matches)
{
var id = match.Value;
if (!aggregateIds.TryGetValue(id, out var list))
{
list = new List<string>();
aggregateIds[id] = list;
}
list.Add(file);
}
}
var duplicates = aggregateIds
.Where(kvp => kvp.Value.Count > 1)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
Assert.True(duplicates.Count == 0,
duplicates.Count > 0
? $"Duplicate aggregate IDs detected: {string.Join("; ", duplicates.Select(d => $"{d.Key} in {string.Join(", ", d.Value)}"))}"
: "No duplicate aggregate IDs found.");
}
private static void AssertNoPattern(IEnumerable<string> files, string pattern, string message)
{
var violations = files