stralos-feature-user-settings is the Module Federation widget remote that owns the Your settings panel. It is a manifest v2 kind: widget remote with slot: floating-end. The shell mounts the slot once inside its authenticated layout and passes widgetProps = { assistantOpen }; this remote exposes the panel and its provider.
The panel is open to every signed-in member regardless of role. The shell’s authenticated layout controls access; the API scopes every read and write to the caller.
What this remote owns
Exposed entries
The remote exposes one module:./widget— theUserSettingsWidgetcomponent and theRemoteProvider+REMOTE_KEYthe shell wraps the slot with.
Host contract
1. Render the widget in the floating-end slot
Inside the authenticated layout the shell mounts the slot:assistantOpen prop is passed by the shell’s floating-end slot to every widget in it. This remote does not use that prop; the shared SideSheet resolves its modality when it opens.
2. Dispatch the open event
The shell’s user menu “Your settings” item dispatches:USER_SETTINGS_OPEN_EVENT in this remote without updating the shell leaves the menu item dispatching into silence.
3. Widget bundle size
The./widget entry is mounted on every chromed page and must remain Chakra-free. The sheet is a dynamic import() on first open. .ci/remote-size-baseline.json is the accepted gzip sum; build:remote fails more than 10% over it.
API endpoints
All calls are to the Global API (/api/global). Authentication follows the stralos.auth.* / window.__STRALOS_AUTH__ contract.
Response shapes
GET /me/default-office and PUT /me/default-office return:
source values:
chosen— the person has an explicit choice stored.first-office— no choice stored, or the choice is no longer an active office; the organisation’s first-created active office is used.none— the organisation has no active offices.
PUT of null clears the choice, returning the caller to the first-office or none source. A 422 with the code invalid_default_office means the chosen office can no longer be used (it may have been retired); the sheet shows a message asking the person to pick another.
Every response is parsed field by field. A shape the client does not recognise is treated as a failure rather than silently accepted.
Default office sheet behaviour
The sheet re-reads the default office on every open so it reflects changes made elsewhere (the Locations screen or an admin in Settings → Users) since the last open.
The Save button is disabled until the in-panel choice differs from the stored choice. After a successful save, a live region (visible and announced to screen readers) confirms the saved office name, or says the choice is automatic and names the current stand-in office.
If the sheet is closed with unsaved changes,
SideSheet’s confirmOnDirtyClose shows a confirmation dialog. The record name in that dialog is Default office.
Federation contract
This remote follows the thin-host contract (PRD D1/D3). Host-provided singletons arereact, react-dom, react-router-dom, and react/jsx-runtime, declared as caret ranges in .ci/shell-federation-contract.json. @stralos-co-nz/ui and @stralos-co-nz/domain are exact pins in package.json and are bundled into the remote — they are not shell-provided singletons.
src/widget.tsx opens with four specifier-less imports (import "react" etc.) that force @module-federation/vite to keep each import: false share’s full export surface. Deleting them makes the build intermittently red. See the file header and src/shareGuard.test.ts for the mechanism.
