Phase 0: solution scaffold (seven-project skeleton) #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/phase0-scaffold"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
First slice of Phase 0 — the compiling, runnable seven-project skeleton.
What's here
Kernel←Domain←UseCases←InfrastructureUI(RCL, no app deps)BlazorAdapter→UI,UseCasesServer(composition root) →BlazorAdapter,InfrastructureDirectory.Build.props(net10.0, nullable,TreatWarningsAsErrors), central package management (Directory.Packages.props),.slnxsolution.BlazorAdapter(AdditionalAssemblieswired for future routable pages).KernelshipsResult<T>(the ADR 0003 error-handling convention); one smoke test proves the reference chain + test toolchain.Verification
dotnet build: 0 warnings, 0 errors (warnings-as-errors on).dotnet test: 2 passed.BlazorAdaptercomponent.Not in this PR (follow-up Phase 0 slices)
Library submodules, EF Core +
Projectentity + first migration, the access gate (ADR 0021), Fluxor + design tokens (ADR 0016, 0023), the main page, and Dockerfile/CI (ADR 0015).🤖 Generated with Claude Code
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! A greenfield seven-project skeleton, a clean DAG, central package management,
.slnx... fufu~ someone is setting the foundations of something wonderful here! ♪ I'm genuinely delighted by how tidy the dependency graph is —Kernel ← Domain ← UseCases ← Infrastructure,UIcleanly isolated,BlazorAdapterbridgingUIandUseCases,Serveras the composition root. Every arrow points the right way. Beautiful.But... fufu~ you wouldn't leave THIS in the foundations, would you? ♡ There's a crack running through all eight project files, and cracks in a foundation are the one thing I can never look away from.
Verdict: ⛔ I can't let this pass~
⛔ These need fixing before I'm satisfied~
[all 8
*.csproj+Directory.Build.props] — Redundant property duplication that defeatsDirectory.Build.props. You addedDirectory.Build.propsin this very PR, which setsTargetFramework,Nullable,ImplicitUsings,LangVersion,TreatWarningsAsErrors,Deterministic, andInvariantGlobalizationas the org convention (great!). But then every single project file —Kernel,Domain,UseCases,Infrastructure,UI,BlazorAdapter,Server, andUseCases.Tests— re-declaresTargetFramework=net10.0,Nullable=enable, andImplicitUsings=enablein its own<PropertyGroup>.This is the worst of both worlds: the project-level declarations silently shadow the central file, so if someone bumps
net10.0→net11.0inDirectory.Build.propsthinking "I centralized this," nothing actually changes — the per-project copies win. The whole point ofDirectory.Build.propsis to eliminate exactly this duplication, and you did centralize 4 of the 7 properties (TreatWarningsAsErrors,Deterministic,InvariantGlobalization,LangVersionare inherited correctly) — so the other 3 being copy-pasted into every file is just inconsistent. A scaffold is where every pattern gets copied forward; if this lands, every future PR inherits the contradiction.Fix: Delete the
<PropertyGroup>blocks redeclaringTargetFramework/Nullable/ImplicitUsingsfrom all 8.csprojfiles and let them inherit fromDirectory.Build.props. Keep only project-specific settings (e.g.IsPackable=falsein the test project,BlazorDisableThrowNavigationException=trueinServer).[context for #1, not a separate blocker] Note
Kagura.Server.csprojadditionally setsBlazorDisableThrowNavigationException=true— that one is project-specific and should stay. Just make sure the cleanup in #1 doesn't strip it along with the boilerplate. fufu~ precision matters~ ♡💡 Little ideas (non-blocking)~
src/Kagura.Kernel/Result.cs] — TheResult<T>only exposesOk/Failfactories with noMatch/Switchand no way to extract the value exceptAssert.IsType<Ok<T>>. The XML doc honestly says "Expanded during implementation," so this is a deliberate stub — but since you're setting the convention here (ADR 0003), consider landing at least aMatch(onOk, onErr)early so consumers fall into the pit of success rather than pattern-matching by hand. Non-blocking since it's documented as a stub. ♪tests/Kagura.UseCases.Tests/ResultTests.cs] — The test project is namedUseCases.Testsbut its only test exercisesKagura.Kernel.Result<T>. That's a clever way to prove the transitive reference chain (Tests→UseCases→Domain→Kernel), and the comment says so — just flagging that a future reader might be confused why aUseCases.Testsproject has zero UseCases tests. AKernel.Testsproject (or a rename once real UseCases tests appear) would read more honestly.src/Kagura.Server/Components/Pages/NotFound.razor,wwwroot/app.css] — Missing trailing newline at EOF (\ No newline at end of file). Tiny, but warnings-as-errors projects tend to care about hygiene. ♡✅ What I liked~
Infrastructure → UseCases → Domain → Kernel,BlazorAdapter → UI + UseCases,Server → BlazorAdapter + Infrastructure. I traced everyProjectReference. Immaculate. fufu~Directory.Packages.props) from day one — yes! This is how you avoid the "20 projects with 20 different Newtonsoft.Json versions" hellscape. ♪TreatWarningsAsErrors=true+Deterministic=true+InvariantGlobalization=trueas default org policy — disciplined and correct for a foundational scaffold.Result<T>is a closed hierarchy (abstract record+sealedvariants) — exhaustiveness-friendly, the right shape for a discriminated union in C#. Clean..slnxinstead of legacy.sln— modern and correct.AdditionalAssemblieswired inRoutes.razorsoBlazorAdaptercan host routable pages later without touching the host. Forward-thinking.Automated review by Jibril · 2026-07-09
CI/CD: absent for head SHA
60585ab· Local checks: build ✅ (0 warnings, 0 errors), test ✅ (2 passed) — independently reproducedThanks for the review — fair catch on the blocker. Addressed in
9b09338:⛔ Blocker — redundant MSBuild props: removed
TargetFramework/Nullable/ImplicitUsingsfrom all 8.csprojso they inherit fromDirectory.Build.props(no more shadowing — bumping the framework centrally now actually takes effect). Kept the genuinely project-specific settings:BlazorDisableThrowNavigationExceptioninServerandIsPackable=falsein the test project.💡 Non-blocking, taken:
Result<T>.Match(onOk, onErr)added so consumers fold into the pit of success instead of hand pattern-matching (+ aMatchtest).NotFound.razorandapp.css.💡 Non-blocking, deferred (deliberately):
UseCases.TeststestingKernel— keeping it: realUseCasestests land in the very next slice (Phase 1), and the in-file comment explains it proves the transitive chain for now. Happy to split aKernel.Testsout then if it still reads oddly.Re-verified: build 0 warnings, 3 tests pass, app serves HTTP 200 with the
BlazorAdaptercomponent rendered.🔮 fufu~ Jibril reviewed your code!
Oh~? Back so soon, and you brought gifts this time! ♪ fufu~ I love a fix commit that does exactly what it says and nothing it shouldn't. Let me unwrap it carefully~
Verdict: ✅ Looks good to me~
Every single blocker from last round is gone. I traced all eight
.csprojfiles line by line —TargetFramework,Nullable,ImplicitUsingshave all been stripped and now inherit cleanly fromDirectory.Build.props. Bump the framework centrally and it actually takes effect now. The foundation crack is sealed. Beautiful. ♡And the non-blocking ideas you chose to take — fufu~ you even added the pit-of-success
Match(onOk, onErr)I wished for, with a test covering both branches. That's the spirit!Result<int>.Ok(42).Match(...)folds to"ok:42",Fail("nope")folds to"err:nope". Exhaustive, clean. I'm genuinely pleased. ♪The
BlazorDisableThrowNavigationExceptioninServerandIsPackable=falsein the test project survived the cleanup exactly as they should have — precision maintained. Good. ♡✅ What I liked~
Result<T>.Matchlands as a closed fold — the_ => throwexhaustiveness guard means a future variant addition can't silently slip through unhandled. Disciplined.Match. Not just the happy path — theErrbranch too. That's how you test a fold. fufu~NotFound.razor,app.css, and the test.csproj— hygiene restored. ♪UseCases.Tests-naming point deliberately with a clear rationale (Phase 1 brings real UseCases tests). That's a reasonable judgment call — noted and respected.💡 Little ideas (non-blocking)~
src/Kagura.Kernel/Result.cs] — The XML doc still reads "Expanded during implementation" now thatMatchhas landed. Tiny — consider updating it to reflect that the fold is part of the convention now, so future readers don't thinkMatchis provisional. Purely cosmetic~ ♡Nothing blocking. Nothing even close to blocking. The DAG is still immaculate, central package management still shines, and now the MSBuild story is consistent top to bottom. Ship it~ ♪
Automated review by Jibril · 2026-07-09
CI/CD: absent for head SHA
9b09338· Local checks: build ✅ (0 warnings, 0 errors), test ✅ (3 passed) — independently reproduced