Feature Specification: Component overview
Created: 2026-10-07
Status: Implemented
Input: Reconstructed from the code at 093e68b6f (core/components/hosting-provider/overview/default.nix, core/components/hosting-provider/overview/page.nix, core/setups/hosts-common.nix, core/setups/overview-uis-test.nix, core/checks/nix-unit-tests.nix).
User Scenarios & Testing (mandatory)
User Story 1 - Find every web UI of a deployment (Priority: P1)
An operator opens one page and sees a tile for each web UI of the
deployment. Each tile links to https://<domain>/ and shows the logo, the
name and the host of the UI. The setups compute the list of UIs (see
005, FR-008). The component turns
the list into a static page and serves it with nginx.
Why this priority: the page is the entry point that an operator opens from the internet.
Independent Test: nix-unit-setups-overview-uis holds that the page
lists only the nodes that the deployment deploys.
Acceptance Scenarios:
- Given a UI whose
artworkgivesiconandiconDark, Whenpage.nixbuilds the tile, Then the logo is a<picture>with a darksrcsetforprefers-color-scheme: dark. - Given a UI whose
artworkgives onlyicon, Whenpage.nixbuilds the tile, Then the logo is an<img>. - Given a UI with
artwork = null, Whenpage.nixbuilds the tile, Then the logo is the first letter of the name in upper case. - Given the list of UIs, When the setups pass it as
deploymentUIs, Then the tiles are sorted by the lower-case name, then by domain.
User Story 2 - Serve the page at the apex (Priority: P2)
The operator types only the domain of the deployment. With servedAtApex
set, nginx serves the same page at apexDomain and at cfg.domain. The
setups give the apex its records (see
005, FR-009).
Why this priority: the apex is the shortest name. The page also works
on overview.<domain> alone.
Independent Test: No check of this component covers it.
Acceptance Scenarios:
- Given
servedAtApex = true, When the component applies, Then thetlsrequest askssslforcfg.domainandapexDomain, and nginx has onevirtualHostsentry for each name. - Given
servedAtApex = false, When the component applies, Then onlycfg.domaingets a certificate and a vhost.
Edge Cases
page.nixescapes each name and host withescapeXML.page.nixcopies the icons toicons/<index>.svgandicons/<index>-dark.svg, so the page closure holds only the icon files.- With
enable = false, the component emits no request.
Requirements (mandatory)
Functional Requirements
- FR-001: The component MUST declare
components.overviewwith the nameOverview,certAudience = "browser"and the default subdomainoverview. - FR-002: The component MUST declare
servedAtApex(defaulttrue) and the hidden optionapexDomain(defaultdeploymentDomain). - FR-003: The implementation MUST request
sslforcfg.domainand, withservedAtApex, forapexDomain. - FR-004: The implementation MUST request
spiffe.enableandfirewall.publicTCPPorts = [ 80 443 ]. - FR-005: The
coderequest MUST read the module argumentdeploymentUIs, build the page withpage.nixand serve it as the nginxrootof each name. - FR-006:
page.nixMUST render one<a class="card">tile per UI, with a link tohttps://<domain>/. - FR-007: On the central group (the one group whose roster provides
varsBackend), the setups MUST add the browser UIs of the groups that setcentralLogin, such as thehypervisorgroup (aggregatedHypervisorBrowserUIs), todeploymentUIs.
Key Entities
deploymentUIs: the list of browser UIs that the setups give to the module, fromsupportingRequests.browserUIsof each used node.- Browser UI of a node: the UI of its component on the name that
uiSubdomaingives, and the UIs thatbrowserUIsof its component gives on names of their own, for example the Swagger UI and AsyncAPI pages of the api node. A UI counts only when the node holds a certificate for its name. - Overview page: the
overview-pagederivation withindex.htmland the icons.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001:
nix-unit-setups-overview-uispasses. - SC-002: On a live node,
https://overview.<domain>/returns the page with one tile per deployed UI.
Assumptions
- Each UI that the page links to does its own sign-in. So the page needs no sign-in and can use a public certificate.
- Public DNS already shows each name on the page.
Known Deviations
None.