# Domain Entities — U1 Hosting & Serving
**Note**: U1 introduces **no persisted entity**. It adds no table, no migration and no database column. Its "domain" consists of in-memory configuration descriptors and a response model. They are documented here because they are the data structures the unit's logic operates on, and because reviewers should be able to confirm that nothing is being persisted.
---
## Concept Relationships
```mermaid
graph TD
host["Host application"]
mountweb["StaticMount: website
request path /"]
mountadmin["StaticMount: admin SPA
request path /admin"]
provider["File provider
per mount"]
fallbackweb["SPA fallback: website"]
fallbackadmin["SPA fallback: admin"]
placeholder["Placeholder page
embedded resource"]
report["HealthReport
response model"]
orchestrator["ModuleOrchestrator
existing"]
bypass["Bypass prefix list
existing, extended"]
tokenparams["Token validation parameters
existing, now shared"]
host -->|"registers"| mountweb
host -->|"registers"| mountadmin
mountweb -->|"resolves files via"| provider
mountadmin -->|"resolves files via"| provider
mountweb -->|"falls back to"| fallbackweb
mountadmin -->|"falls back to"| fallbackadmin
fallbackweb -->|"substitutes when index absent"| placeholder
host -->|"exposes"| report
report -->|"reads module names from"| orchestrator
host -->|"configures"| bypass
host -->|"shares"| tokenparams
bypass -->|"used by availability gate"| tokenparams
classDef hostnode fill:#90cdf4,stroke:#2b6cb0,stroke-width:1px,color:#000;
classDef mount fill:#9ae6b4,stroke:#2f855a,stroke-width:1px,color:#000;
classDef model fill:#fbd38d,stroke:#c05621,stroke-width:1px,color:#000;
classDef existing fill:#e2e8f0,stroke:#4a5568,stroke-width:1px,color:#000;
class host hostnode;
class mountweb,mountadmin,provider,fallbackweb,fallbackadmin,placeholder mount;
class report model;
class orchestrator,bypass,tokenparams existing;
```
Text alternative: the host registers two independent static mounts each with its own file provider and SPA fallback, plus a health response model that reads module names from the existing orchestrator; the bypass list and token validation parameters are existing structures this unit extends and shares.
---
## Static Mount Descriptor (configuration, in-memory)
Not a class to be persisted — this describes what each `UseStaticFiles` registration is configured with.
| Field | Website mount | Admin mount |
|---|---|---|
| Physical root | `{contentRoot}/wwwroot/web` | `{contentRoot}/wwwroot/admin` |
| Request path | `""` (root) | `/admin` |
| Default file | `index.html` | `index.html` |
| Directory browsing | Disabled | Disabled |
| Tolerates missing root | **Yes** — logs a warning | Yes — logs a warning |
| Registration order | Second | **First** |
**Registration order matters**: the admin mount must be registered first, or `/admin/...` would be resolved against the website root.
---
## HealthReport (response model, not persisted)
| Field | Type | Purpose |
|---|---|---|
| `status` | string | `"Healthy"`. A running process always reports healthy; absence of a response is the unhealthy signal |
| `timestamp` | timestamp with offset | When the report was produced, so a cached response is recognisable |
| `version` | string | The application's informational version, so a deploy can be confirmed without host access |
| `modules` | string array | Names of modules loaded by `ModuleOrchestrator` |
**Validation and constraints**:
- Every field is derived from in-process state. No field may require a database query, file read or network call (BR-U1-15).
- No field may contain configuration values, paths, connection details or environment variable contents (BR-U1-18).
- `modules` is read from the existing `ModuleOrchestrator.ModuleNames`, which is already exposed anonymously by `/api/v1/System/capabilities` — so this field introduces no new disclosure.
---
## Placeholder Page (embedded static content)
| Property | Value |
|---|---|
| Storage | Embedded resource in the assembly, not a file in `wwwroot` |
| Served when | The website fallback is needed and `wwwroot/web/index.html` is absent |
| Status code | `200` |
| Content | A statement that no website has been deployed yet, the expected target path, and a link to `/admin` |
**Why embedded rather than a file**: a file in `wwwroot/web/` would be inside the directory a website workspace owns and overwrites — it would be deleted by the first real website deployment, or worse, mistaken for part of the customer's site. Embedding keeps it outside that boundary entirely.
**What it must not contain**: no version, no environment name, no module list, no configuration. It is served anonymously to any visitor of the site root, which is a wider audience than `/health`.
---
## Extended Existing Structures
### Bypass prefix list (`AvailabilityMiddleware`)
| Aspect | Detail |
|---|---|
| Current contents | `/api/v1/Availability/status`, `/api/v1/Auth/`, `/api/v1/Setup/status`, `/api/v1/master/`, `/api/v1/SlaveStatus` |
| Added by U1 | `/health` |
| Matching | Case-insensitive prefix match, unchanged |
### Shared token validation parameters
| Aspect | Detail |
|---|---|
| Currently | Configured once inside `AddJwtBearer` in `ServiceCollectionExtensions.AddCoreInfrastructure` |
| Change | Extracted so the same instance is used by both the bearer scheme and the availability gate |
| Constraint | Exactly one definition. Two copies could drift, and a gate more permissive than the scheme would silently re-open the hole FR-24 closes |
---
## Persistence Summary
| Question | Answer |
|---|---|
| New tables? | None |
| New migrations? | None |
| New columns? | None |
| New configuration sections? | None — U1 adds no `appsettings` section |
| Anything written to disk at runtime? | No |
All persistence work in Round 1 belongs to **U2**, which adds the Data Protection keys table and the automatic Core migration.