feat: Implement admin-only specialties management interface
Playwright Tests / test (push) Canceled after 0s

- Added MailerAttachmentPolicy for validating email attachments against server rules.
- Introduced fis.specialties.js for managing hidden maintenance actions via an admin interface.
- Created fis.specialties.scss for styling the specialties management UI.
- Added German localization for specialties management in fis.specialties_txt_de.js.
- Developed CSS for specialties management in fis.specialties.css.
- Implemented server-side stored procedure fds__admin_backupAndClearInvoiceFile for backing up and clearing invoice files.
- Created fds__invoice_file_backups table to store backup records of invoice files.
This commit is contained in:
Stefan
2026-09-17 21:17:23 +02:00
parent 86f6a60860
commit 249a945f5e
59 changed files with 2720 additions and 457 deletions
+13 -5
View File
@@ -216,7 +216,9 @@ flowchart TD
## 6. Sending the invoice by email
Email delivery is handled by `IComService` / `ProcessWebComService`, which
talks to the **ProcessWeb Mailer API** (`push_com`, `comType=email`).
talks to the **ProcessWeb Mailer API** (`POST /api/mailer/push_com`,
`comType="e"`; contract: https://processweb.de/api/mailer/fc, client side
described in `Docs/Concepts/processweb-mailer-interface.md`).
- `HandleRequestSconf` builds the HTML body via `BuildInvoiceBody(balance,
paymentTerms)` — a fixed German thank-you text, the amount (if non-zero),
@@ -234,8 +236,12 @@ talks to the **ProcessWeb Mailer API** (`push_com`, `comType=email`).
- A signature is appended to the HTML body.
- If the mailer is disabled (`_settings.Enabled == false`), sending is a
documented no-op.
- Attachments are base64-encoded inline (`{ filename, mimeType,
contentBase64 }`) and POSTed to the Mailer API.
- Attachments are pre-validated against the Mailer's limits (size, count,
no empty file, extension rules) and POSTed as `multipart/form-data` —
envelope JSON in an unnamed field plus one file part per attachment, with
`attachmentCount` in the envelope.
- The Mailer's 200 response must confirm `attachmentsProcessed` equal to
the number sent; otherwise the send is reported as failed (ADR 0028).
- Only on a **successful** send does the controller call
`fds__setInvoiceSent @auto=true`, which sets `IsSent = 1` — so a failed
mailer call leaves the invoice finalised but *not marked sent* (visible via
@@ -252,8 +258,10 @@ sequenceDiagram
C->>Com: SendEmailAsync("inv_<Id>", subject, body, email, "", {pdf})
Com->>Com: validate email, apply OverrideRecipient (dev), append signature
alt mailer enabled
Com->>API: POST push_com {comType:"email", attachments:[base64 pdf]}
API-->>Com: success/failure
Com->>Com: MailerAttachmentPolicy.Validate(pdf)
Com->>API: POST /api/mailer/push_com (multipart: envelope{comType:"e", attachmentCount:1} + pdf part)
API-->>Com: 200 {comStackID, attachmentsProcessed} / 4xx/5xx
Com->>Com: attachmentsProcessed == 1 ? success : failure
else mailer disabled
Com-->>Com: no-op (logged)
end