Files
ccn/Packages/Infrastructure
javier cdded06ba3 Renamed the Web package as Infrastructure (#25)
This PR contains the work done to rename the _Web_ package as _Infrastructure_, to provide a clear naming and purpose to this particular package within the project.

To provide further details about the work:

* Infrastructure
  * Asset fingerprinting: an FNV-1a token derived from the static files directory, appended as ?v= to asset URLs so deploys bust caches; pre-rendered pages also revalidate via weak ETags.
  * New middlewares: fixed-window RateLimitMiddleware (per-client budgets keyed by trusted X-Forwarded-For or remote address) and VaryMiddleware (Accept-Encoding on every response); SecurityHeadersMiddleware now also stamps error responses.
  * Auto-generated HEAD endpoints, cache max-age configuration, and Docker build/Compose refinements.
  * Protocols and scaffolding: Asset/AssetExtension, the Page protocol (viewport, stylesheets, scripts, versioned URLs), and LocalizedRequestContext.
  * Rate limiter's counter store swapped from an actor to a Mutex (no executor hop per request) with amortized batch eviction instead of O(n²) scans under client floods.
  * FingerprintAssets reports unreadable files to a logger instead of silently producing a token that never busts their cache.

Reviewed-on: rock-n-code/loud-amsterdam#25
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
2026-07-23 01:04:37 +00:00
..

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

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.module lookups. A type that needs a service's content takes it as a parameter: the bundle: whose String Catalog names the supported languages (LocalizationMiddleware, LocalizedHTMLCollectionResponse, NotFoundMiddleware), the document: closure that builds a page for a locale, and the metadata requirement through which a Page conformer 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, and NotFoundMiddleware+Defaults are the pattern to follow.
  • Method structs. Single-operation types such as FingerprintAssets hold their lifetime-fixed configuration in init and take only per-call inputs in callAsFunction.

Layout

Sources are split by visibility, then by kind, one type per file:

Sources/Public/<Kind>/     public API (Protocols, Middlewares, Responses, …)
Sources/Internal/<Kind>/   implementation details (e.g. FNV1aHash)
Tests/Cases/…              mirrors the source layout
Tests/Utils/…              stubs and test-only extensions

Requirements

  • Swift 6.3 toolchain (swift-tools-version:6.3).
  • macOS 15, matching the sibling Localization and Persistence packages (the services deploy to Linux containers; the packages carry no UI platforms).