This PR contains the work done to do a little bit of housekeeping pass across all packages and the Website service. To provide further details about the work: * Refreshed the READMEs and source documentation to match the current code; * Tagged every test case consistently across the Infrastructure, Localization, Persistence, and Website test targets; * Removed Website middleware tests now covered by Infrastructure's own suite; * Conformed the `PrepareDB` method to Sendable; * Relaxes the production Compose DATABASE_TLS default from require to prefer; * Added Persistence test verifying the prefer posture falls back to plaintext connections. Reviewed-on: rock-n-code/loud-amsterdam#27 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
3.4 KiB
3.4 KiB
Infrastructure
The shared Hummingbird toolkit the Loud services build on: declarative routing, hardened HTTP middlewares, pre-rendered localized HTML responses, and the page and asset scaffolding.
Overview
The package provides, grouped by role:
| Role | Types |
|---|---|
| Routing | RouterController, RouteCollectionBuilder, the addController extension on RouterMethods |
| Middlewares | SecurityHeadersMiddleware, VaryMiddleware, RateLimitMiddleware, LocalizationMiddleware, NotFoundMiddleware |
| Pages and assets | Page, Asset, AssetExtension, FingerprintAssets |
| Responses | CachedHTMLResponse, LocalizedHTMLCollectionResponse |
| Contexts | LocalizedRequestContext |
| Constants | The HTTPField.Name header names, Int.RateLimit limits, and String.Security header values the middlewares default to |
Design rules
The package holds only what every service can reuse; anything a service owns is injected, never referenced:
- No site-specific content. No page markup, no asset catalog, no
Bundle.modulelookups. A type that needs a service's content takes it as a parameter: thebundle:whose String Catalog names the supported languages (LocalizationMiddleware,LocalizedHTMLCollectionResponse,NotFoundMiddleware), thedocument:closure that builds a page for a locale, and themetadatarequirement through which aPageconformer supplies its icon links and theme colors. - Services fill the gaps once, via extensions. A service restores its convenient call sites with retroactive extensions — the Website's
Page+Defaults,LocalizationMiddleware+Defaults, andNotFoundMiddleware+Defaultsare the pattern to follow. - Method structs. Single-operation types such as
FingerprintAssetshold their lifetime-fixed configuration ininitand take only per-call inputs incallAsFunction.
Layout
Sources are split by visibility, then by kind, one type per file:
Sources/
├── Public/ public API
│ ├── Builders/ RouteCollectionBuilder
│ ├── Enumerations/ AssetExtension
│ ├── Extensions/ addController, plus the default header names and values
│ ├── Methods/ FingerprintAssets
│ ├── Middlewares/ the five HTTP middlewares
│ ├── Protocols/ Asset, LocalizedRequestContext, Page, RouterController
│ └── Responses/ CachedHTMLResponse, LocalizedHTMLCollectionResponse
└── Internal/
└── Types/ implementation details (FNV1aHash)
Tests/
├── Cases/ the test suites, mirroring the Sources/ layout
├── Catalogs/ the String Catalog fixture, copied verbatim so it loads on Linux
└── Utils/ stubs (StubAsset, StubPage, …) and the suite Tag constants
Testing
Every suite carries a tag naming the kind of API it exercises — .asset, .extension, .middleware, .protocol, or .type, declared in Tests/Utils/Extensions/Tag+Constants.swift — so test plans and result summaries can slice the run by kind. A new suite must adopt the tag matching its subject (or add a tag there if none fits).
Requirements
- Swift 6.3 toolchain (
swift-tools-version:6.3). - macOS 15, matching the sibling
LocalizationandPersistencepackages (the services deploy to Linux containers; the packages carry no UI platforms).