- Introduced new JavaScript file `fis.admin_txt_de.js` for German translations of administration-related terms and messages. - Created `fis.admin.css` for styling the administration interface, including layout, cards, and buttons. - Added `fis.admin.de.js` for the main functionality of the administration module, implementing features such as system status checks and email testing. - Minified version of the German JavaScript file created as `fis.admin.de.min.js`. - Minified CSS file created as `fis.admin.min.css` for optimized loading.
4.0 KiB
4.0 KiB
status, date, applyTo, supersededBy
| status | date | applyTo | supersededBy | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Accepted | 2026-07-16 |
|
0011 — Admin module gated on fds_sys > 4
Context
Operators needed an in-app view of the running deployment's health: which host it
runs on, whether SQL Server / Azure Key Vault / Azure Blob Storage / the MFR ERP are
reachable, how the email service is configured (including the dev/test
Fuchs:Email:OverrideRecipient redirect), and a way to send a test email. The
StartupSelfTestService already probes most of these once at startup and writes the
result to the log — but that is invisible to a logged-in operator and cannot be re-run
on demand. This is privileged, infrastructure-revealing information (server names,
account names, connectivity state) that must not be exposed to ordinary users.
Decision
- Add an Admin module (
admin) alongside the existing invoice/reminder/report/banking modules, following the same frontend module contract (init:admin→admin/authreturns{ manage }→ lazy-load/web/fis.admin.de.js+/web/fis.admin.css→init2()). - Access is gated on the caller's
fds_sysmodule authorization being strictly greater than 4 (fis_getModuleAuth('fds_sys', authuser) > 4). The menu button is only rendered, and the module script only fetched, for such users; every Admin data endpoint additionally re-checks the level server-side (defense in depth) and returns 401 otherwise.admin/authis the sole endpoint that answers for unauthorized users too (it returnsmanage: 0), so the frontend can decide whether to render the module at all. - Backend diagnostics live in a new DI-registered
ISystemStatusService(scoped). It exposes a passiveGetInfo()snapshot and live, never-throwing connectivity probes (database,keyvault,blob,mfr) plusSendTestEmailAsync. The test email goes through the normalIComServicepipeline, so theOverrideRecipientsafety net applies exactly as for any other outbound mail. - The service never returns secrets — only presence flags and non-sensitive values (server/catalog/login name, storage account name, error text). Responses are serialized camelCase to match the frontend's lowercase convention.
Consequences
fds_sysis now a security-relevant authorization key: granting it a value > 4 exposes infrastructure status and the ability to send test emails. Provision it deliberately.SystemStatusServiceis intentionally separate fromStartupSelfTestServicerather than a shared refactor: the startup service's probe methods areprotected virtualand its tests override them, so folding both onto one probe surface would have broken that contract. The two therefore duplicate a little probe logic (Key Vault secret read, MFRGetEntities, SQLSELECT); keep them behaviourally aligned when either changes.- New probes (or new status facts) belong in
SystemStatusServicebehind the sameSystemProbeResult/SystemInfoSnapshotshapes; add the component id toSystemStatusService.Componentsand a card infis.admin.js. - Blob connectivity is checked via a new
IBlobStorageService.CheckConnectivityAsync(account-info request); it too never throws.
Alternatives considered
- Reuse
StartupSelfTestServicedirectly. Rejected — see Consequences; its virtual/overridden probe surface is owned by its tests, and it is a one-shotBackgroundService, not a request-scoped query service. - Gate only in the frontend (hide the menu button). Rejected — the endpoints would still be reachable by crafting the POST. Server-side enforcement on every endpoint is required.
- A separate
fds_admin/new module-auth key. Rejected —fds_sysalready models system-level privilege; reusing it avoids a parallel permission to provision.