SRV-07 — Platform services — audit, numbering, settings, files, PDF
Audit journal writer, sequential business numbers, typed settings service, S3 pre-signed uploads with thumbnails, PDF rendering base for invoices and delivery notes.
| Field | Details |
|---|---|
| Task code | SRV-07 |
| Phase | P0 — Foundations (cadrage, UX/UI, architecture & contract) |
| Product scope | V1 |
| Status | Done (Mon 19 Oct 2026) |
| Start | Mon 19 Oct 2026 |
| Due | Mon 19 Oct 2026 |
| Responsible | Anis — Full-stack developer |
| Co-responsible | — |
| Effort | 1 person-day(s) planned · 5 from scratch · size S |
| Area · app | Server · server |
| Depends on | SRV-04 |
| Unblocks | SRV-08, SRV-11 |
| Milestones | — |
Summary
Audit journal writer, sequential business numbers, typed settings service, S3 pre-signed uploads with thumbnails, PDF rendering base for invoices and delivery notes.
Description
Several cross-cutting services are needed by almost every module and must exist before them (AUD-01, ADM-03, ADM-04, INT-05, SEC-04): an audit journal writer, sequential business numbers, a typed settings service, file storage and a PDF rendering base. The audit writer records actor, client app, IP, request id, entity, action (AuditAction) and a before/after diff; the numbering service allocates gap-free numbers per key and year (REV-000123, CMD-2026-000158, FAC-…, BL-…, PAY-…, TRN-…, VIS-…, TKT-…, RET-…, plus the credit-note sequence) inside the caller's transaction; the settings service exposes each Setting key with a Zod schema, a default and a Redis cache, and audits changes. Files follow AUTHORING §3: files.createUpload (pre-signed PUT, 10 min, per FilePurpose size/type limits), files.completeUpload (existence check, thumbnails in the worker), files.downloadUrl (signed GET, 5 min, access check by purpose and owner); product images, brand logos and banners are public through the CDN bucket. Out of scope: the invoice/delivery-note layouts themselves (SRV-16, SRV-18 with DQA-09).
Subtasks
| # | Subtask | Owner |
|---|---|---|
| 1 | AuditLog writer (actor, clientApp, ip, requestId, entity, entityId, AuditAction, before/after diff) callable inside transactions | Anis |
| 2 | NumberSequence service: atomic UPDATE … RETURNING per key + year, formats REV, CMD, FAC, BL, PAY, TRN, VIS, TKT, RET and credit notes | Anis |
| 3 | Typed settings registry (key, Zod schema, default, scope) with Redis cache, change audit and admin.settings.get/update | Anis |
| 4 | files.createUpload with FilePurpose rules (mime types, max size, public vs private bucket) and pre-signed PUT URLs | Anis |
| 5 | files.completeUpload: object HEAD check, checksum, File row finalisation; worker job generating WebP thumbnails (sharp) | Anis |
| 6 | files.downloadUrl with per-purpose access checks (owner, scope, permission) and 5-minute signed GET | Anis |
| 7 | PDF rendering base in the worker (@react-pdf/renderer) with HOCO header/footer, fonts with Arabic glyphs, storage as GENERATED_DOCUMENT | Anis |
| 8 | Orphan upload cleanup job (uploads never completed after 24 h) | Anis |
Deliverables
- apps/server/src/modules/audit/{audit.service.ts,audit.router.ts}
- apps/server/src/modules/settings/{registry.ts,settings.service.ts,settings.router.ts}
- apps/server/src/modules/files/{files.router.ts,storage.ts,thumbnails.job.ts}
- apps/server/src/platform/{numbering.ts,pdf/}
Acceptance criteria
- Two hundred concurrent order-number allocations produce 200 distinct consecutive numbers with no gap (ADM-04)
- Changing a setting writes an AuditLog UPDATE entry with old and new values and is visible to every process within 5 seconds
- An upload of a 30 MB file or a disallowed mime type for STORE_DOCUMENT is refused with 422 FILE_NOT_ALLOWED
- A reseller cannot obtain a download URL for another reseller's document (403 OUT_OF_SCOPE); signed URLs expire after 5 minutes (SEC-04)
- Product images are served from the public bucket with a thumbnail generated after completion
Requirements covered
| Requirement | Title | Release |
|---|---|---|
| AUD-01 | Activity journal: logins, creations, modifications, validations, exports, deletions with user, time and context | V1 |
| ADM-03 | Business parameters: order minimums, reservation status, GPS tolerance and frequency, credit policy, stacking, payment methods, delivery fees, return and after-sales windows | V1 |
| ADM-04 | Unique human-readable numbers for resellers, orders, invoices, tours, visits, tickets and returns | V1 |
| INT-05 | S3-compatible file storage for photos, invoices and documents | V1 |
| SEC-04 | Protected documents and uploaded files (private storage, signed URLs, access checks) | V1 |
API surface
| Endpoint group | Operations |
|---|---|
| File uploads & downloads | 3 |
Test measures
- DB concurrency test for number allocation against real Postgres
- Integration test with MinIO: create upload, PUT, complete, download URL, expiry
- Snapshot test of the PDF base layout
Risks
- Gap-free numbering rolls back with failed transactions and leaves holes — allocate inside the same transaction as the business row so a rollback also rolls back the number
KPI
- Delivered by Mon 19 Oct 2026 within 1 person-day(s).
- Every acceptance criterion above demonstrated before hand-off; linked requirements' acceptance criteria pass.
- Zero open critical defects, permission gaps or data-integrity regressions at sign-off.
Generated from content/plan/tasks.json by scripts/generate-team-tasks.mjs. Dates are computed by the scheduler (Sunday–Thursday weeks, holidays excluded) — change the plan, not this page.
SRV-06 — RBAC & data scopes
Role and permission catalogue (module × action), permission guard on every procedure, delegate zone scope and reseller ownership scope as reusable query filters.
SRV-08 — Jobs & notifications infrastructure
BullMQ queues and scheduler, transactional outbox, notification service (inbox, FCM push, SMS, email adapters with dev simulators), templates and the event → channel matrix.