Adds SlpModularCms.Api.SlpSoftware and extracts shared CmsHost composition
Continuous Integration / config (pull_request) Successful in 11s
Continuous Integration / changes (pull_request) Successful in 21s
Continuous Integration / backend-build (pull_request) Successful in 6m10s
Continuous Integration / vulnerability-scan (pull_request) Successful in 4m59s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m27s
Continuous Integration / backend-test (pull_request) Failing after 7m48s
Continuous Integration / frontend-build (pull_request) Successful in 2m5s
Continuous Integration / frontend-test (pull_request) Successful in 4m24s
Continuous Integration / frontend-lint (pull_request) Successful in 2m0s
Continuous Integration / publish-test (pull_request) Skipped
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-test (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Continuous Integration / config (pull_request) Successful in 11s
Continuous Integration / changes (pull_request) Successful in 21s
Continuous Integration / backend-build (pull_request) Successful in 6m10s
Continuous Integration / vulnerability-scan (pull_request) Successful in 4m59s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m27s
Continuous Integration / backend-test (pull_request) Failing after 7m48s
Continuous Integration / frontend-build (pull_request) Successful in 2m5s
Continuous Integration / frontend-test (pull_request) Successful in 4m24s
Continuous Integration / frontend-lint (pull_request) Successful in 2m0s
Continuous Integration / publish-test (pull_request) Skipped
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-test (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Unit 1 of the slpsoftware-api feature (FR-1/FR-2/FR-3): a new Client project in the Clients solution folder, intended to eventually become the deployed API for test.slpsoftware.nl/slpsoftware.nl, hosting the same four modules as SlpModularCms.Api plus a future Offerings module. - Extracts SlpModularCms.Api/Program.cs's hosting-pipeline composition into SlpModularCms.Core.Hosting.CmsHost (ConfigureServices/ConfigurePipeline), shared by both Client projects so they cannot drift apart - Moves StaticContentExtensions.cs + WebsitePlaceholder.html from Api into Core, since CmsHost cannot live in Api but Core cannot depend on Api - Adds SlpModularCms.Api.SlpSoftware with its own isolated local dev database and dev ports (5286/7223, distinct from Api's and Api.Slave's) - Adds SlpModularCms.Api.Tests with WebApplicationFactory-based pipeline regression tests (security headers, health check, SPA fallback, rate limiting), scoped to Api per NFR Design - Adds a frontend dev:slpsoftware pnpm script mirroring dev:slave - Fixes GlobalExceptionHandler logging routine 401s (e.g. an expired/missing refresh token) as unhandled errors -- pre-existing, unrelated to this feature's own scope, found while testing the new instance Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWyStNL2ZsjrS7FLd7xvvN
This commit is contained in:
+64
@@ -0,0 +1,64 @@
|
||||
# Deployment Architecture — Unit: SlpSoftware Client Setup
|
||||
|
||||
**Status note**: this diagram documents the **target state after** the Operations-phase cutover (D-15) — it is reference/planning context for Code Generation, not something this unit deploys itself. No infrastructure changes happen as part of this Construction stage.
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
visitor["Site Visitor / CMS Administrator browser"]
|
||||
proxy["Proxy Pi<br/>nginx + TLS (certbot)"]
|
||||
pimain["pi-main<br/>systemd --user"]
|
||||
svc_test["slpsoftware-test.service<br/>port 5100"]
|
||||
svc_prod["slpsoftware-production.service<br/>port 5101"]
|
||||
dll["SlpModularCms.Api.SlpSoftware.dll<br/>(replaces Api.dll at cutover)"]
|
||||
db["MariaDB<br/>SlpSoftwareTest / SlpSoftwareProduction"]
|
||||
sentry["Sentry (shared project)"]
|
||||
|
||||
visitor -->|"HTTPS"| proxy
|
||||
proxy -->|"proxy_pass, plain HTTP over LAN"| pimain
|
||||
pimain --> svc_test
|
||||
pimain --> svc_prod
|
||||
svc_test --> dll
|
||||
svc_prod --> dll
|
||||
dll -->|"EF Core / MariaDB provider"| db
|
||||
dll -->|"error/event reporting"| sentry
|
||||
|
||||
classDef external fill:#e9d8fd,stroke:#553c9a,stroke-width:2px,color:#000000,font-weight:bold;
|
||||
classDef proxy fill:#bee3f8,stroke:#2b6cb0,stroke-width:2px,color:#000000,font-weight:bold;
|
||||
classDef compute fill:#fefcbf,stroke:#b7791f,stroke-width:2px,color:#000000,font-weight:bold;
|
||||
classDef data fill:#c6f6d5,stroke:#2f855a,stroke-width:2px,color:#000000,font-weight:bold;
|
||||
|
||||
class visitor external;
|
||||
class proxy proxy;
|
||||
class pimain,svc_test,svc_prod,dll compute;
|
||||
class db,sentry data;
|
||||
|
||||
linkStyle default stroke:#666666,stroke-width:2px;
|
||||
```
|
||||
|
||||
Text alternative: a visitor's browser reaches the proxy Pi over HTTPS, which forwards plain HTTP over the LAN to pi-main; pi-main runs two systemd-managed instances (test on port 5100, production on port 5101), both eventually running `SlpModularCms.Api.SlpSoftware.dll` after the cutover, each talking to its own MariaDB database and the shared Sentry project (purple = external actor, blue = the TLS-terminating proxy, yellow = compute/hosting, green = data/observability backends).
|
||||
|
||||
## Local Development (Current Scope of This Unit)
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
dev["Developer machine"]
|
||||
api["SlpModularCms.Api<br/>(existing dev host)"]
|
||||
apislp["SlpModularCms.Api.SlpSoftware<br/>(new, this unit)"]
|
||||
dbA["Local DB: Api"]
|
||||
dbB["Local DB: Api.SlpSoftware (isolated)"]
|
||||
|
||||
dev --> api
|
||||
dev --> apislp
|
||||
api --> dbA
|
||||
apislp --> dbB
|
||||
|
||||
classDef dev fill:#fefcbf,stroke:#b7791f,stroke-width:2px,color:#000000,font-weight:bold;
|
||||
classDef data fill:#c6f6d5,stroke:#2f855a,stroke-width:2px,color:#000000,font-weight:bold;
|
||||
|
||||
class dev,api,apislp dev;
|
||||
class dbA,dbB data;
|
||||
|
||||
linkStyle default stroke:#666666,stroke-width:2px;
|
||||
```
|
||||
|
||||
Text alternative: locally, `Api` and the new `Api.SlpSoftware` each connect to their own separate, isolated database (decision Q1 = B) — no shared local dev data between the two.
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
# Infrastructure Design — Unit: SlpSoftware Client Setup
|
||||
|
||||
## Production / Test Infrastructure — No Change Now, Documented Target for the Future Cutover
|
||||
|
||||
Sourced directly from `aidlc-docs/features/gitea-deployment-workflow/operations/deployment/deployment-instructions.md` (the authoritative, existing deploy documentation, owned by that feature):
|
||||
|
||||
| Aspect | Current (`Api`) | Target after D-15 cutover (`Api.SlpSoftware`) |
|
||||
|---|---|---|
|
||||
| Host | Single Raspberry Pi ("pi-main") | **Same Pi** — no new host |
|
||||
| TLS termination | Separate "proxy Pi", reverse-proxies to pi-main | **Unchanged** |
|
||||
| Process manager | `systemd --user`, units `slpsoftware-test.service` / `slpsoftware-production.service` | **Same unit names** — only the `ExecStart` line's `.dll` filename changes |
|
||||
| Ports | 5100 (test), 5101 (production) | **Unchanged** |
|
||||
| Database | MariaDB on pi-main, `SlpSoftwareTest` / `SlpSoftwareProduction` | **Unchanged** — same instance, same database names (this is a cutover of which binary runs, not a new environment) |
|
||||
| Monitoring | Shared Sentry project, distinguished by `Observability__Environment` | **Unchanged** |
|
||||
| Reverse proxy config | nginx on the proxy Pi, `proxy_pass` to pi-main's port | **Unchanged** — nginx doesn't know or care which `.dll` is listening (D-6/NFR-1) |
|
||||
|
||||
**What actually changes at cutover time** (Operations phase, D-7/D-15 — explicitly **not** this Construction stage or this unit's Code Generation):
|
||||
- The systemd unit's `ExecStart` line: `SlpModularCms.Api.dll` → `SlpModularCms.Api.SlpSoftware.dll`
|
||||
- The CI/CD pipeline's publish/artifact step, to build and ship `Api.SlpSoftware` instead of `Api`
|
||||
|
||||
**Why this matters for Code Generation (this unit, now)**: `SlpModularCms.Api.SlpSoftware` must be structurally deployable into this exact same shape without modification — same `wwwroot/web` symlink convention, same `/health` endpoint contract, same `ASPNETCORE_URLS=http://0.0.0.0:<port>` binding pattern, same environment-file-based configuration approach. This is already satisfied by design, since `Api.SlpSoftware` consumes the same `CmsHost` composition as `Api` (Unit 1's own FR-3) — there is nothing extra to build here, only something to avoid accidentally breaking.
|
||||
|
||||
## No Changes to CI/CD or Gitea Actions Configuration in This Stage
|
||||
|
||||
`.gitea/workflows/continuous_integration.yaml`, `deploy-scp.yaml`, and the Gitea Actions variables/secrets listed in deployment-instructions.md § 1.9 are **not** touched by this unit or this Construction phase. That retarget is explicitly Operations-phase scope (D-7, D-15) and belongs to a later stage of this feature, coordinated with the `gitea-deployment-workflow` feature that owns those files.
|
||||
|
||||
## Local Development Database (Decision Q1 = B)
|
||||
|
||||
`Api.SlpSoftware` uses its **own, isolated local development database**, separate from `Api`'s local dev database. Rationale: developing and testing the Offerings module (Unit 2) against `Api.SlpSoftware` should not risk touching or corrupting whatever local data `Api` already has, and vice versa.
|
||||
|
||||
**Implication for Code Generation**: `Api.SlpSoftware`'s `appsettings.Development.json` gets its own `ConnectionStrings:DefaultConnection` pointing at a distinct local database name (e.g. a `SlpModularCmsSlpSoftwareDev`-style name — exact naming is a Code Generation Planning detail, not decided here), following the same `dotnet-appsettings` pattern already used by `Api`.
|
||||
|
||||
## Shared Infrastructure
|
||||
|
||||
None applicable — single-tenant deployment (per deployment-instructions.md's explicit note that a future second customer would get an entirely separate instance, not shared infrastructure within this one).
|
||||
Reference in New Issue
Block a user