Relocates ModuleOrchestrator, ServiceCollectionExtensions, and ApiPrefixConvention from SlpModularCms.Api into SlpModularCms.Core.Hosting so a new Master-less SlpModularCms.Api.Slave host project (ports 5285/7222) can share the same bootstrap code without duplicating it. This lets a developer run a master instance and a slave instance side by side locally to test the master/slave connection, without touching the existing master/slave protocol itself. Relocates the two orchestrator/convention test files from Modules.Identity.Tests to Core.Tests, dropping an incidental ProjectReference to SlpModularCms.Api that existed only for those tests. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
11 KiB
Execution Plan — Local Dev Master/Slave Setup
Detailed Analysis Summary
Transformation Scope (Brownfield)
- Transformation Type: Single new component (host project) + configuration-only changes elsewhere. No architectural transformation, no deployment-model change, no infrastructure/cloud change.
- Primary Changes: New
SlpModularCms.Api.Slavehost project; extraction of shared bootstrap/orchestration code so it isn't duplicated between the master and slave hosts; per-instanceappsettings/launchSettings; frontend dev-server config for a second instance; a short runbook. - Related Components:
SlpModularCms.Api(reference/behavior parity, no functional change),SlpModularCms.Modules.Availability(already slave-capable, unchanged),SlpModularCms.Modules.Master(unchanged — simply excluded from the slave project),frontend(dev-server/env config only).
Change Impact Assessment
- User-facing changes: No — this is developer tooling, not a product feature.
- Structural changes: Yes, minor — one new project (
SlpModularCms.Api.Slave) and, to satisfy NFR-1 (no duplicated bootstrap code), a small new shared project/location forModuleOrchestrator,ServiceCollectionExtensions, andApiPrefixConventionthat bothSlpModularCms.ApiandSlpModularCms.Api.Slavereference. - Data model changes: No — no new entities, no new migrations.
- API changes: No — no new endpoints or contract changes; existing Master/Availability endpoints are reused as-is.
- NFR impact: Minor — addressed directly in requirements.md (NFR-1 no duplication, NFR-2 DB isolation, NFR-3 local-only scope, NFR-4 secrets hygiene). No new performance/security/scalability posture is introduced beyond what already exists.
Component Relationships (Brownfield)
- Primary Component: New
SlpModularCms.Api.Slaveproject (backend) - Shared Components: New shared bootstrap location (exact form decided in Application Design) referenced by both
SlpModularCms.ApiandSlpModularCms.Api.Slave - Dependent Components:
frontend(new dev-server mode pointing at whichever instance) - Supporting Components:
frontend/README.md/ root docs (runbook)
| Component | Change Type | Change Reason | Change Priority |
|---|---|---|---|
| Shared bootstrap (new) | Minor (extraction, no behavior change) | Avoid duplicating ModuleOrchestrator etc. between hosts (NFR-1) |
Critical — both hosts depend on it |
SlpModularCms.Api |
Configuration-only (adjust to consume shared bootstrap) | Keep master behavior identical, just sourced from shared location | Critical — must not regress existing master behavior |
SlpModularCms.Api.Slave (new) |
Major (new project) | Slave-only host, no Modules.Master reference |
Critical — the actual deliverable |
frontend |
Configuration-only | Point at either instance via env/script | Important |
| Docs/runbook | New content | Explain manual connection workflow | Optional but requested (FR-4) |
Risk Assessment
- Risk Level: Low — isolated to local dev tooling; no production code paths, no data model, no API contract changes; existing master build output is unaffected once the shared bootstrap is extracted correctly.
- Rollback Complexity: Easy — new project and config files only; deleting them reverts to the current state.
- Testing Complexity: Simple — existing unit tests for
Modules.Master/Modules.Availabilityare untouched; verification is mostly "does each instance start correctly and can the existing Add CMS Instance flow connect them."
Workflow Visualization
flowchart TD
Start(["User Request"])
subgraph INCEPTION["🔵 INCEPTION PHASE"]
WD["Workspace Detection<br/><b>COMPLETED</b>"]
RA["Requirements Analysis<br/><b>COMPLETED</b>"]
US["User Stories<br/><b>SKIPPED</b>"]
WP["Workflow Planning<br/><b>IN PROGRESS</b>"]
AD["Application Design<br/><b>EXECUTE</b>"]
UG["Units Generation<br/><b>EXECUTE</b>"]
end
subgraph CONSTRUCTION["🟢 CONSTRUCTION PHASE"]
FD["Functional Design<br/><b>SKIP (per unit)</b>"]
NFRA["NFR Requirements<br/><b>SKIP (per unit)</b>"]
NFRD["NFR Design<br/><b>SKIP (per unit)</b>"]
ID["Infrastructure Design<br/><b>SKIP (per unit)</b>"]
CG["Code Generation<br/><b>EXECUTE</b>"]
BT["Build and Test<br/><b>EXECUTE</b>"]
end
subgraph OPERATIONS["🟡 OPERATIONS PHASE"]
OPS["Operations<br/><b>PLACEHOLDER</b>"]
end
Start --> WD
WD --> RA
RA --> US
US --> WP
WP --> AD
AD --> UG
UG --> CG
CG --> BT
BT --> End(["Complete"])
style WD fill:#4CAF50,stroke:#1B5E20,stroke-width:3px,color:#fff
style RA fill:#4CAF50,stroke:#1B5E20,stroke-width:3px,color:#fff
style US fill:#BDBDBD,stroke:#424242,stroke-width:2px,stroke-dasharray: 5 5,color:#000
style WP fill:#FFA726,stroke:#E65100,stroke-width:3px,color:#000
style AD fill:#FFA726,stroke:#E65100,stroke-width:3px,stroke-dasharray: 5 5,color:#000
style UG fill:#FFA726,stroke:#E65100,stroke-width:3px,stroke-dasharray: 5 5,color:#000
style FD fill:#BDBDBD,stroke:#424242,stroke-width:2px,stroke-dasharray: 5 5,color:#000
style NFRA fill:#BDBDBD,stroke:#424242,stroke-width:2px,stroke-dasharray: 5 5,color:#000
style NFRD fill:#BDBDBD,stroke:#424242,stroke-width:2px,stroke-dasharray: 5 5,color:#000
style ID fill:#BDBDBD,stroke:#424242,stroke-width:2px,stroke-dasharray: 5 5,color:#000
style CG fill:#4CAF50,stroke:#1B5E20,stroke-width:3px,color:#fff
style BT fill:#4CAF50,stroke:#1B5E20,stroke-width:3px,color:#fff
style Start fill:#CE93D8,stroke:#6A1B9A,stroke-width:3px,color:#000
style End fill:#CE93D8,stroke:#6A1B9A,stroke-width:3px,color:#000
linkStyle default stroke:#333,stroke-width:2px
Text alternative: Workspace Detection, Requirements Analysis are complete (green). User Stories is skipped (gray, dashed). Workflow Planning is in progress (orange). Application Design and Units Generation are planned to execute (orange, dashed border indicating conditional-but-selected). Per-unit Functional Design, NFR Requirements, NFR Design, and Infrastructure Design are all skipped (gray, dashed) for both units. Code Generation and Build and Test always execute (green). Operations remains a placeholder.
Phases to Execute
🔵 INCEPTION PHASE
- Workspace Detection (COMPLETED)
- Requirements Analysis (COMPLETED)
- User Stories (SKIPPED)
- Rationale: Pure developer tooling / local run configuration with no user-facing functionality, no personas, no acceptance-criteria needs — matches the explicit skip criteria in the workflow ("Developer tooling or build process improvements").
- Execution Plan (IN PROGRESS)
- Application Design - EXECUTE
- Rationale: A new component boundary is introduced (the shared bootstrap location consumed by both
SlpModularCms.ApiandSlpModularCms.Api.Slave) and its responsibilities/dependencies need to be defined before code generation, even though no new business logic exists. Kept minimal — no service-layer business rules to design, just component boundaries.
- Rationale: A new component boundary is introduced (the shared bootstrap location consumed by both
- Units Generation - EXECUTE
- Rationale: The change spans two clearly separable concerns (backend dual-instance hosting vs. frontend dual-instance tooling), each independently completable and testable — decomposing into units keeps Code Generation focused.
🟢 CONSTRUCTION PHASE (per unit)
- Functional Design - SKIP (both units)
- Rationale: No new data models, schemas, or business logic — this is host/bootstrap wiring and configuration reuse of existing services.
- NFR Requirements - SKIP (both units)
- Rationale: NFRs are already fully captured in requirements.md (no duplication, DB isolation, local-only scope, secrets hygiene) and require no tech-stack selection or further elaboration.
- NFR Design - SKIP (both units)
- Rationale: Depends on NFR Requirements, which is skipped.
- Infrastructure Design - SKIP (both units)
- Rationale: No cloud/infrastructure resources involved — purely local processes and local SQL Server databases using existing patterns.
- Code Generation - EXECUTE (ALWAYS)
- Rationale: Implementation of the new project, config files, and frontend tooling.
- Build and Test - EXECUTE (ALWAYS)
- Rationale: Verify both instances build and start, existing test suites still pass, and the manual master↔slave connection flow works.
🟡 OPERATIONS PHASE
- Operations - PLACEHOLDER
- Rationale: Future deployment and monitoring workflows; not applicable to local dev tooling.
Proposed Units (for Units Generation)
- Unit 1 — Backend dual-instance hosting: Extract shared bootstrap (
ModuleOrchestrator,ServiceCollectionExtensions,ApiPrefixConvention) into a location both hosts reference; addSlpModularCms.Api.Slaveproject (noModules.Masterreference); add itslaunchSettings.json/appsettings*.json; updateSlpModularCms.Api's config for CORS/port clarity if needed; add both projects to the solution. - Unit 2 — Frontend dual-instance tooling & runbook: Add
.env.slave.local/.env.exampleupdates,dev:slavenpm script, and the runbook documenting how to start both instances and use the existing Add CMS Instance dialog to connect them.
Package Change Sequence
Unit 1 must complete before Unit 2 can be meaningfully tested end-to-end (the frontend needs a running slave backend to point at), though Unit 2's config/doc changes could technically be authored in parallel. Sequential execution (Unit 1 then Unit 2) is recommended for a clean verification story.
Estimated Timeline
- Total Phases: Application Design, Units Generation, Code Generation (2 units), Build and Test
- Estimated Duration: Small — a few hours of focused work; no research spikes needed since the master/slave protocol already exists and is unchanged.
Success Criteria
- Primary Goal: Developer can run a master instance (port 5284/7221, full stack) and a slave instance (port 5285/7222, no Master module) locally at the same time, on separate databases.
- Key Deliverables:
SlpModularCms.Api.Slaveproject, shared bootstrap extraction, per-instance config, frontend slave mode, runbook. - Quality Gates: Both backends build and start cleanly; existing test suites (
Modules.Master.Tests,Modules.Availability.Tests, frontend tests) still pass unchanged; manual verification that the master frontend's "Add CMS Instance" dialog can register and see the local slave as connected. - Integration Testing: Manual — start both instances, register the slave from the master frontend, confirm connected/healthy status.