Files
Fuchs_Intranet/Fuchs/Docs/Concepts/admin-specialties.md
T
Stefan 9569c1b65e
Playwright Tests / test (push) Canceled after 0s
feat: Enhance invoice file backup procedure to include JSON snapshots
- Updated the stored procedure `fds__admin_backupAndClearInvoiceFile.sql` to back up not only the invoice file but also JSON snapshots of related data (invoices, items, details, service requests) to ensure consistency and traceability.
- Modified the table structure of `fds__invoice_file_backups` to accommodate new JSON columns for storing these snapshots.
- Added an ADR (0030) document to outline the decision and rationale behind these changes, emphasizing the importance of maintaining a consistent set of data alongside the backed-up file.
2026-09-17 22:39:01 +02:00

82 lines
4.1 KiB
Markdown

---
status: Active
lastUpdated: 2026-09-17
applyTo:
- "Fuchs/Controllers/IntranetController.Specialties.cs"
- "Fuchs/js/intranet/modules/fis.specialties*"
- "Fuchs/js/intranet/fis_main_menu.js"
- "Fuchs/js/intranet/fis_main_go.js"
relatedDecisions:
- "0027-admin-invoice-file-backup-and-clear.md"
---
# Admin "Specialties" page (`/specialties`)
## Summary
An admin-only page that surfaces the otherwise hidden maintenance actions as
cards, each a small form. It exists so support does not need SSMS or a
hand-crafted POST for actions like resetting an invoice's stored PDF. It is
a regular lazily loaded frontend module (`fn = specialties`), gated like the
rest of the Administration menu (`fds_sys > 4`), and reachable both from the
menu (Administration → Spezialfunktionen) and by opening the URL
`/specialties` directly.
The menu entry is deliberately hidden: it only appears when the Administration
dropdown is opened with **Shift** held (Shift+click, or Shift+Enter/Space on
the focused toggle); a plain open hides it again
(`$fis.bindShiftOnlyMenuItems` in `fis_main_menu.js`, driven by the item's
`lclass: 'shift-only'`). This keeps the maintenance actions out of casual
reach without adding another authorization level — the item is still part of
the menu array, so the `/specialties` deep link is unaffected.
## How it works
- **Module load** follows the standard contract (see
`admin-system-status.md`): the menu item `init:specialties` →
`$ocms.init('specialties')` → `POST /do/specialties/auth` → when
`manage > 0`, import `web/fis.specialties.de.js` + `fis.specialties.css`
and call `init2`. `IntranetController.Specialties.cs` answers only that
auth probe (same `GetSystemAdminAuthAsync` gate as the Admin module) and
401s everything else.
- **Deep link.** `IntranetController.Index` renders the same SPA shell for
every `/{fn}` URL and ignores `fn`; there is no client router. `fis_main_go.js`
therefore calls `$fis.openModuleFromPath()` once the admin menu has settled:
it takes the first path segment and calls `$ocms.init(fn)` **only if the
user's menu offers an `init:<fn>` item** (admin dropdown included). A
non-admin opening `/specialties` sees the dashboard, as before; arbitrary
paths never trigger a module load.
- **Cards.** `fis.specialties.js` keeps an array `cards` of builder
functions. Each card is `title + description + <form> + result box`;
`$spc.submit(c, { button, confirm, run, report })` wires HTML5 validation,
a `confirm()`, the `postXT` call (`run(values)` returns the request) and
the inline result (`report(response)` → `{ ok, lines }`). The card calls
the action's **real** endpoint — every such endpoint enforces the admin
gate itself; the page adds no authority.
- **Current cards**
- *Rechnungsdatei zurücksetzen (Soft-Delete)* → `POST
/do/admin/backupclearinvoicefile/<internal Id>` (ADR 0027). Shows the
outcome and the blob backup URI, or the German text for the service's
`reason` (`invoice_not_found`, `not_final`, `external`, `no_file`,
`db_error`). An invoice without a stored file (`hasFile` from
`fds__getInvoice`) is answered `no_file` before any blob copy, so
repeated clicks leave no spare `backup_*` blobs.
- **Adding a card:** append a builder to `cards`, add its texts to
`fis.specialties_txt_de.js`, run `npx gulp min`. No server change is
needed unless the action itself is new.
- **Build:** bundle entries in `Fuchs/bdlconfig.json`
(`intranet:specialties`); generated files under `wwwroot/web/`.
## Key files
- `Fuchs/Controllers/IntranetController.Specialties.cs` — auth probe.
- `Fuchs/Controllers/IntranetController.cs` — `"specialties"` case in `Do`.
- `Fuchs/js/intranet/modules/fis.specialties.js` / `_txt_de.js` / `.scss`.
- `Fuchs/js/intranet/fis_main_menu.js` — menu item + `openModuleFromPath`.
- `Fuchs/js/intranet/fis_main_go.js` — deep link after menu settles.
- `Fuchs/js/intranet/fis_texts_gui_de.js` — `m_specialties` label.
## Related decisions
- [0027 — Admin invoice-file backup-and-clear action](../Decisions/0027-admin-invoice-file-backup-and-clear.md)