Task #243: Admin audit log — focused readability + actor-filter subset
Landed a tight subset of the 13-item umbrella, mirroring the proven narrow-then-defer pattern from #242: - #195 — Plain DELETE /api/services/:id now writes a `service.delete` audit row carrying nameEn + nameAr (force-with-deps still uses the dedicated `service.force_delete`). Added matching `service.delete` formatter case + EN/AR i18n keys, and surfaced nameAr on the existing `service.force_delete` summary. - #197 — `actorUserId` filter for `/admin/audit-logs` and CSV export. openapi.yaml updated, codegen regenerated, server filter wired through parseFilters/buildWhere with 400-on-invalid handling, AuditLogPanel UI got an actor dropdown wired into params + export URL + reset, and a new audit-logs-actor-filter API test (4 cases) covers list narrowing, exclusion, invalid input, and CSV export. - #178 — Formatter unit tests for user.delete (id-only, EN/AR display name resolution, force flag, force + name) and the new service.delete (id-only, EN/AR), 11 new cases (33/33 pass). Skipped #194 — already implemented; users.ts DELETE persists displayName fields and audit-summary already renders user.deleteWithName/forceDeleteWithName. Deferred via follow-ups (no duplicate of existing #182/#183/#184): - F1: #196 recent-activity endpoint + 5 admin panels - F2: #205+#206+#208 permission history CSV/name resolution/timeline - F3: #209+#210 cascade/bulk audit rows + e2e UI spec for History tabs Validation: tx-os typecheck clean; pre-existing executive-meetings.ts errors not regressed; all targeted server tests pass (delete-force-warnings 10, audit-logs target-filter 7, forced-only 6, audit-log-coverage 27, new actor-filter 4, broader audit/services sweep 40); e2e test verified actor dropdown rendering, filter behavior, readable Arabic service.delete summary, and CSV export honoring the filter.
This commit is contained in:
@@ -2726,6 +2726,7 @@ Filter by action (exact match) and/or a date range (inclusive).
|
||||
* @summary List audit log entries (admin)
|
||||
*/
|
||||
export const listAuditLogsQueryForcedOnlyDefault = false;
|
||||
|
||||
export const listAuditLogsQueryLimitDefault = 50;
|
||||
export const listAuditLogsQueryLimitMax = 200;
|
||||
|
||||
@@ -2761,6 +2762,13 @@ export const ListAuditLogsQueryParams = zod.object({
|
||||
.describe(
|
||||
"Restrict results to entries whose `target_id` exactly matches.\nTypically used together with `targetType` to focus on the history\nof a single entity.\n",
|
||||
),
|
||||
actorUserId: zod.coerce
|
||||
.number()
|
||||
.min(1)
|
||||
.optional()
|
||||
.describe(
|
||||
"Restrict results to entries written by a specific acting user\n(matches `actor_user_id`). Combines with the other filters.\n",
|
||||
),
|
||||
limit: zod.coerce
|
||||
.number()
|
||||
.min(1)
|
||||
@@ -2844,4 +2852,11 @@ export const ExportAuditLogsCsvQueryParams = zod.object({
|
||||
.describe(
|
||||
"Restrict the export to entries whose `target_id` exactly matches.\n",
|
||||
),
|
||||
actorUserId: zod.coerce
|
||||
.number()
|
||||
.min(1)
|
||||
.optional()
|
||||
.describe(
|
||||
"Restrict the export to entries written by a specific acting user.\n",
|
||||
),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user