feat: Enhance invoice file backup procedure to include JSON snapshots
Playwright Tests / test (push) Canceled after 0s

- 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.
This commit is contained in:
Stefan
2026-09-17 22:39:01 +02:00
parent 249a945f5e
commit 9569c1b65e
14 changed files with 187 additions and 23 deletions
+23 -3
View File
@@ -17,7 +17,13 @@
whose fds_sys authorization exceeds 4. One auth check gates the whole dropdown; it (and
therefore all module scripts) is only added after that check resolves, so lower-privileged
users never see it or fetch any module's code. Called from fis_main_go.js once the DOM (and
the initial main menu) is ready. Returns a promise that settles once the menu is final. */
the initial main menu) is ready. Returns a promise that settles once the menu is final.
Systemüberwachung and Spezialfunktionen are hidden entries: they are only shown while the
Administration dropdown is opened with the Shift key held (Shift+click on the toggle). A plain
click hides them again, so the diagnostics/maintenance pages are never one accidental click
away. The items still exist in the menu array, so the /admin and /specialties deep links
(openModuleFromPath) keep working. */
$fis.addAdminMenuButtonsIfAuthorized = function () {
if ($('#m_admin_grp').length > 0) { return Promise.resolve(); } // idempotent
return $fis.getAuth('fds_sys').then(function (auth) {
@@ -27,18 +33,32 @@ $fis.addAdminMenuButtonsIfAuthorized = function () {
itm: [
{ lbl: $t.m_usr, id: 'm_usr', fnc: 'init:usr', ico: 'glyphicon glyphicon-user' },
{ lbl: $t.m_usrgrp, id: 'm_usrgrp', fnc: 'init:usrgrp', ico: 'glyphicon glyphicon-list' },
{ lbl: $t.m_admin_status, id: 'm_admin', fnc: 'init:admin', ico: 'glyphicon glyphicon-dashboard' },
{ lbl: $t.m_specialties, id: 'm_specialties', fnc: 'init:specialties', ico: 'glyphicon glyphicon-wrench' }
{ lbl: $t.m_admin_status, id: 'm_admin', fnc: 'init:admin', ico: 'glyphicon glyphicon-dashboard', lclass: 'shift-only' },
{ lbl: $t.m_specialties, id: 'm_specialties', fnc: 'init:specialties', ico: 'glyphicon glyphicon-wrench', lclass: 'shift-only' }
]
});
/* Re-render the main menu cleanly: drop the previously generated menu list
(never the .nav-right settings dropdown) and rebuild it from the array. */
$('#mainmenu').children('ul:not(.nav-right)').remove();
$('#mainmenu').ocmsmenu($ocms.ocmsmenu);
$fis.bindShiftOnlyMenuItems($('#m_admin_grp'));
}
}).catch(function () { /* auth lookup failed → leave the menu unchanged */ });
};
/* Hides every `.shift-only` entry of a dropdown group and reveals them only for an opening
initiated with Shift held. Bound on mousedown (fires before Bootstrap's click toggle, so the
list is already in the right state when the dropdown becomes visible) and on keydown for
keyboard users (Shift+Enter / Shift+Space on the focused toggle). */
$fis.bindShiftOnlyMenuItems = function (group) {
let items = group.find('.shift-only').hide();
if (items.length === 0) { return; }
let apply = function (e) { items.toggle(e.shiftKey === true); };
group.children('a.dropdown-toggle')
.on('mousedown', apply)
.on('keydown', function (e) { if (e.key === 'Enter' || e.key === ' ') { apply(e); } });
};
/* Deep link: the server renders the same SPA shell for every /{fn} URL (IntranetController.Index
ignores fn), so opening e.g. /specialties directly would otherwise just show the dashboard.
Opens the module named by the first path segment — but only one the user's menu actually