riyadhafraa 6447908548 Task #195: Audit-log every service deletion, not only forced ones
Background
----------
`DELETE /api/services/:id` previously wrote an audit_logs row only when
hasDeps && force was true. A clean delete (no orders, or ?force=false on a
service with no dependents) left no trace, so admins reviewing the Audit
Log could not tell who removed a service or when, and the new
"Target: service #… · Name" line never appeared for routine deletions.

Implementation status (already in tree from prior work in this branch)
----------------------------------------------------------------------
- artifacts/api-server/src/routes/services.ts wraps the delete + audit
  insert in a single db.transaction:
  * hasDeps && force  -> service.force_delete with { nameEn, nameAr,
    orderCount } (unchanged on-the-wire shape, so existing forced-only
    filter and target-filter behavior is preserved).
  * otherwise (no deps, or force=true with no deps) -> new service.delete
    row with { nameEn, nameAr } and the actor.
- artifacts/tx-os/src/lib/audit-summary.ts already has a service.delete
  case rendering admin.audit.summary.service.delete (with name) or
  service.deleteId (id-only fallback) in both EN and AR.
- delete-force-warnings.test.mjs already covers the route-level no-deps
  and ?force=true-with-no-deps paths.

This commit
-----------
Adds the canonical audit-log coverage tests requested by the task to
artifacts/api-server/tests/audit-log-coverage.test.mjs:
- "DELETE /api/services/:id (no deps, no force)" -> exactly one
  service.delete row with nameEn + nameAr, no orderCount, and no
  service.force_delete companion.
- "DELETE /api/services/:id without force on a service with deps" ->
  409 + service still present + zero audit rows of either action.
- "DELETE /api/services/:id?force=true (with deps)" -> exactly one
  service.force_delete row with orderCount=2 and no plain service.delete
  companion.
Also adds an insertService helper, a createdServiceIds bucket, and a
service_orders/services teardown block to keep the suite self-cleaning.

Verification
------------
- node --test tests/audit-log-coverage.test.mjs -> 29/29 pass (3 new).
- node --test tests/delete-force-warnings.test.mjs tests/service-orders.test.mjs
  tests/audit-logs-forced-only-filter.test.mjs
  tests/audit-logs-target-filter.test.mjs -> 34/34 pass (no regressions).

Deviations
----------
None. Scope matches the task brief exactly.

Replit-Task-Id: b12a13e6-32dd-4707-8a46-ea7a4e6336d9
2026-05-01 14:23:19 +00:00
2026-04-21 12:16:59 +00:00
2026-04-18 02:00:09 +00:00
2026-04-18 02:00:09 +00:00
2026-04-18 02:00:09 +00:00
S
Description
No description provided
139 MiB
Languages
TypeScript 69.4%
JavaScript 29%
CSS 0.6%
Shell 0.6%
Dockerfile 0.2%
Other 0.2%