# Component Dependency — SlpSoftware Production API ## Dependency Matrix | Component | Depends On | Communication Pattern | |---|---|---| | `SlpModularCms.Api.SlpSoftware` (`Program.cs`) | `CmsHost` (Core), `ModuleOrchestrator` (Core) | Direct method calls (`ConfigureServices`/`ConfigurePipeline`) at startup | | `SlpModularCms.Api` (`Program.cs`) | `CmsHost` (Core), `ModuleOrchestrator` (Core) | Same as above — unchanged behavior, now via the shared method instead of inline code | | `CmsHost` | Existing `Core.Hosting.*` extension methods (`AddCoreInfrastructure`, `AddCmsCors`, `AddCmsRateLimiting`, `AddCmsHealthChecks`, `AddCmsSecurityHeaders`, `AddCmsObservability`, `AddCmsDataProtection`, `AddCmsLogging`, `UseCmsSentry`, `UseCmsSecurityHeaders`, `UseCmsStaticContent`, `MapCmsHealthChecks`, `MapSentryTunnel`, `MapCmsSpaFallbacks`, `MigrateCoreDatabase`) | Direct method calls — no new dependencies introduced, purely re-composing existing ones | | `OfferingsController` | `IOfferingsService` | Constructor-injected interface (DI) | | `IOfferingsService` (`OfferingsService`) | `IOfferingRepository` | Constructor-injected interface (DI) | | `IOfferingRepository` (`OfferingRepository`) | `OfferingsDbContext` | Constructor-injected `DbContext` (DI, scoped) | | `OfferingsDbContext` | MariaDB (`DefaultConnection`) | EF Core, `UseMySQL`, TLS-enforced connection string (SECURITY-01) | | `OfferingsModule` | `OfferingsDbContext`, `IOfferingRepository`/`OfferingRepository`, `IOfferingsService`/`OfferingsService` | DI registration (`RegisterServices`) + migration application (`UseModule`) | | `SlpModularCms.Api.SlpSoftware` | `SlpModularCms.Modules.Offerings`, `.Identity`, `.Availability`, `.Master` (project references) | Module DLLs discovered dynamically by `ModuleOrchestrator` at runtime — **not** an explicit list in code | | `SlpModularCms.Api` | `SlpModularCms.Modules.Identity`, `.Availability`, `.Master` (project references — **no** `.Offerings` reference) | Same discovery mechanism; `Api` never loads `Offerings` because it never references that project | ## Data Flow ```mermaid sequenceDiagram box rgba(246,224,94,0.4) Website participant Visitor as Site Visitor end box rgba(159,122,234,0.4) External Frontend participant FE as React Frontend end box rgba(99,179,237,0.4) Api.SlpSoftware participant Ctrl as OfferingsController participant Svc as OfferingsService participant Repo as OfferingRepository participant DB as OfferingsDbContext end Visitor->>FE: Loads website FE->>Ctrl: GET /api/v1/offerings Ctrl->>Svc: GetPublicOfferingsAsync() Svc->>Repo: GetAllAsync() Repo->>DB: query non-deleted, order by DisplayOrder DB-->>Repo: Offering rows Repo-->>Svc: List Svc-->>Ctrl: List Ctrl-->>FE: 200 OK, JSON array FE-->>Visitor: Renders offering cards ``` Text alternative: a Site Visitor's browser loads the frontend, which calls the public `GET /api/v1/offerings` endpoint; the request flows Controller → Service → Repository → DbContext and the resulting offerings flow back up the same chain to render as cards (yellow = visitor-facing website, purple = the external frontend app, blue = the new Api.SlpSoftware backend components). ```mermaid sequenceDiagram box rgba(246,224,94,0.4) Admin participant Admin as CMS Administrator end box rgba(99,179,237,0.4) Api.SlpSoftware participant Ctrl as OfferingsController participant Svc as OfferingsService participant Repo as OfferingRepository participant DB as OfferingsDbContext end Admin->>Ctrl: POST /api/v1/offerings/admin (AdminOnly) Ctrl->>Svc: CreateAsync(request) Svc->>Repo: GetFeaturedAsync() Repo-->>Svc: currently-featured Offering (or none) Svc->>Repo: UpdateAsync(previous featured to unfeature, if any) Svc->>Repo: AddAsync(new Offering) Repo->>DB: persist changes DB-->>Repo: saved Offering Repo-->>Svc: Offering Svc-->>Ctrl: OfferingAdminDto Ctrl-->>Admin: 201 Created ``` Text alternative: a CMS Administrator's create request flows through the same layered chain, with the Service first checking for and clearing any existing featured offering before persisting the new one, enforcing the exactly-0-or-1-featured rule from US-10 (yellow = the admin actor, blue = the new backend components). ## Notes - `SlpModularCms.Core` is the shared dependency for both Client projects (`CmsHost`) but has **no** dependency in the other direction — `Core` does not reference `Modules.Offerings` or any other module, preserving the existing module-isolation pattern. - The Gitea Actions pipeline (external to the application dependency graph) is not shown here — its retargeting (FR-9, D-15) is an Operations-phase, deployment-time concern, not an application-level dependency.