Global admins couldn't see the app's event log (no read endpoint or UI existed for it) and had no way to clean up old entries or re-run a scheduled job without touching the database or server directly. Backend: - LoggingService.findLogs() + admin-only LogsController (GET admin/logs) with level/event/date-range/search filtering and pagination, mirroring AdminUsersService.findPlayers(). - LogRetentionScheduler deletes log entries older than LOG_RETENTION_DAYS (default 365, via app.config.ts), following the existing @Cron scheduler pattern. - Admin-only POST admin/run endpoints on CashboxExportController and RecurringTransactionsController that invoke the existing schedulers' public run methods on demand - both are safe to re-run since their "due" queries advance nextRunDate only after a successful run. Frontend: - New /logs page (global-admin gated, same pattern as /users): AG-Grid infinite-scroll table with level/event/date-range/search filters, plus buttons to trigger the two jobs now and see the result land in the grid immediately. - LogsApi, and triggerRunNow() added to the existing CashboxExportApi and RecurringTransactionApi. - Discoverability link from /users to /logs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
30 lines
517 B
TypeScript
30 lines
517 B
TypeScript
export type LogLevel = 'FATAL' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'TRACE';
|
|
|
|
export interface LogEntry {
|
|
id: number;
|
|
level: LogLevel;
|
|
event: string;
|
|
details: string;
|
|
userId: number;
|
|
duration?: number;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface LogQuery {
|
|
page: number;
|
|
limit: number;
|
|
level?: LogLevel;
|
|
event?: string;
|
|
from?: string;
|
|
to?: string;
|
|
search?: string;
|
|
}
|
|
|
|
export interface LogPage {
|
|
data: LogEntry[];
|
|
page: number;
|
|
limit: number;
|
|
total: number;
|
|
hasNextPage: boolean;
|
|
}
|