Files
slp-modular-cms/aidlc-docs/features/master-cms-module/construction/master-backend/nfr-design/logical-components.md
T

5.7 KiB

Logical Components — Unit 1: master-backend

Full Component Wiring Diagram

graph TD
    subgraph ServiceLayer["Service Layer"]
        CmsService["CmsInstanceService"]
        Deps["MasterServiceDependencies\n(constructor record)"]
        Repo["ICmsInstanceRepository"]
        SlaveClientIface["ISlaveApiClient"]
        ApiKeyProt["IApiKeyProtector"]
        HttpCtxAcc["IHttpContextAccessor"]
        Logger["ILogger"]
        Opts["MasterModuleOptions\n(via IOptions)"]
    end

    subgraph SecurityLayer["Security Layer"]
        ApiKeyProtImpl["ApiKeyProtector"]
        DataProt["IDataProtectionProvider\n(ASP.NET Core)"]
        Purpose["Purpose string\nSlpModularCms.Master.ApiKey"]
    end

    subgraph HttpLayer["HTTP + Resilience Layer"]
        SlaveClientImpl["SlaveApiClient"]
        PollyPipeline["Polly ResiliencePipeline\nRetry x2 + Timeout"]
        HttpClientInst["HttpClient\n(IHttpClientFactory)"]
    end

    subgraph BackgroundLayer["Background Service"]
        BgSvc["IntegrityCheckBackgroundService"]
        ScopeFactory["IServiceScopeFactory"]
        Scope["IServiceScope\n(per tick)"]
        PeriodicT["PeriodicTimer\n(IntegrityCheckIntervalMinutes)"]
    end

    subgraph DataLayer["Data Layer"]
        RepoImpl["CmsInstanceRepository"]
        DbCtx["MasterDbContext"]
        Table["CmsInstances table"]
    end

    CmsService --> Deps
    Deps --> Repo
    Deps --> SlaveClientIface
    Deps --> ApiKeyProt
    Deps --> HttpCtxAcc
    Deps --> Logger
    Deps --> Opts

    ApiKeyProt --> ApiKeyProtImpl
    ApiKeyProtImpl --> DataProt
    DataProt --> Purpose

    SlaveClientIface --> SlaveClientImpl
    SlaveClientImpl --> PollyPipeline
    PollyPipeline --> HttpClientInst

    Repo --> RepoImpl
    RepoImpl --> DbCtx
    DbCtx --> Table

    BgSvc --> PeriodicT
    BgSvc --> ScopeFactory
    ScopeFactory --> Scope
    Scope --> CmsService

    classDef service fill:#9ae6b4,stroke:#2f855a,stroke-width:2px,color:#000
    classDef security fill:#FC8181,stroke:#C53030,stroke-width:1px,color:#000
    classDef http fill:#63b3ed,stroke:#2b6cb0,stroke-width:1px,color:#000
    classDef background fill:#CE93D8,stroke:#6A1B9A,stroke-width:1px,color:#000
    classDef data fill:#FFC107,stroke:#F57F17,stroke-width:1px,color:#000
    classDef record fill:#B0BEC5,stroke:#546E7A,stroke-width:1px,color:#000
    class CmsService,Repo,SlaveClientIface,ApiKeyProt service
    class Deps record
    class ApiKeyProtImpl,DataProt,Purpose security
    class SlaveClientImpl,PollyPipeline,HttpClientInst,HttpCtxAcc http
    class BgSvc,ScopeFactory,Scope,PeriodicT background
    class RepoImpl,DbCtx,Table,Logger,Opts data

Text alternative: CmsInstanceService receives all dependencies via MasterServiceDependencies record; IApiKeyProtector wraps Data Protection; ISlaveApiClient wraps SlaveApiClient backed by Polly pipeline; ICmsInstanceRepository wraps MasterDbContext; IntegrityCheckBackgroundService creates a new IServiceScope per PeriodicTimer tick to resolve CmsInstanceService.


Component Responsibility Summary

Component Type NFR Pattern
MasterServiceDependencies Record Constructor aggregation (reduces constructor arity)
IApiKeyProtector / ApiKeyProtector Interface + Singleton Security — Data Protection wrapper; mock-friendly
SlaveApiClient Typed HTTP client Resilience — Polly retry + timeout applied via AddResilienceHandler
IntegrityCheckBackgroundService Singleton BackgroundService Reliability — per-tick IServiceScope; exception isolation per slave
MasterDbContext EF Core DbContext Maintainability — per-module migrations; own connection
CmsInstanceService Scoped service Orchestration — resolved via IServiceScope by background service

DI Registration Order (in MasterModule.RegisterServices)

1. services.AddDataProtection()
2. services.AddSingleton<IApiKeyProtector, ApiKeyProtector>()
3. services.Configure<MasterModuleOptions>(config.GetSection("MasterModule"))
4. services.AddDbContext<MasterDbContext>(...)
5. services.AddScoped<ICmsInstanceRepository, CmsInstanceRepository>()
6. services.AddScoped<MasterServiceDependencies>()
7. services.AddScoped<ICmsInstanceService, CmsInstanceService>()
8. services.AddHttpClient<ISlaveApiClient, SlaveApiClient>()
             .AddResilienceHandler("slave-resilience", ...)
9. services.AddHostedService<IntegrityCheckBackgroundService>()
10. services.AddHttpContextAccessor()  (if not already registered by host)

NFR Coverage Traceability

NFR Pattern Applied Component
Fail-open (NFR-MASTER-01) SlaveApiClient catches failures, returns false; service continues SlaveApiClient, CmsInstanceService
API key security (NFR-MASTER-03) IApiKeyProtector wraps Data Protection; never returns key in DTO ApiKeyProtector, CmsInstanceDto mapping
Configurable interval (NFR-MASTER-04) PeriodicTimer reads MasterModuleOptions.IntegrityCheckIntervalMinutes IntegrityCheckBackgroundService
≥80% test coverage (NFR-MASTER-05) All service/repository/client classes have interfaces; MasterServiceDependencies simplifies test setup All interfaces
Per-module migrations (NFR-MASTER-06) MasterDbContext with own migration assembly; applied in UseModule MasterDbContext, MasterModule
Retry resilience (Q2) Polly exponential backoff on IHttpClientBuilder SlaveApiClient registration
Timeout (Q1) Polly AddTimeout per attempt, driven by HttpTimeoutSeconds SlaveApiClient registration
Logging levels (Q5) Error for status push failures; Warning for integrity check failures CmsInstanceService, IntegrityCheckBackgroundService