events.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #!/usr/bin/env node
  2. /**
  3. * CLI view of the audit trail — the offline equivalent of GET /admin/events.
  4. *
  5. * npm run events -- --limit 20
  6. * npm run events -- --conversation 1311
  7. * npm run events -- --jobs
  8. */
  9. import { db, disconnectDb } from '../src/store/db.js';
  10. function arg(name: string): string | undefined {
  11. const i = process.argv.indexOf(`--${name}`);
  12. return i >= 0 ? process.argv[i + 1] : undefined;
  13. }
  14. async function main(): Promise<void> {
  15. const limit = Number(arg('limit') ?? 30);
  16. const conversationId = arg('conversation') ? Number(arg('conversation')) : undefined;
  17. if (process.argv.includes('--jobs')) {
  18. const jobs = await db().job.findMany({ orderBy: { updatedAt: 'desc' }, take: limit });
  19. for (const j of jobs) {
  20. console.log(
  21. `${j.updatedAt.toISOString()} ${j.status.padEnd(10)} attempts=${j.attempts} ${j.type}` +
  22. (j.lastError ? `\n error: ${j.lastError}` : ''),
  23. );
  24. }
  25. return;
  26. }
  27. const events = await db().auditEvent.findMany({
  28. where: conversationId ? { conversationId } : undefined,
  29. orderBy: { createdAt: 'desc' },
  30. take: limit,
  31. });
  32. for (const e of events) {
  33. console.log(
  34. `${e.createdAt.toISOString()} conv=${e.conversationId ?? '-'} ${e.eventType.padEnd(22)} ${e.summary}`,
  35. );
  36. }
  37. console.log(`\n${events.length} event(s).`);
  38. }
  39. main()
  40. .catch((err: unknown) => {
  41. console.error(err instanceof Error ? err.message : String(err));
  42. process.exitCode = 1;
  43. })
  44. .finally(() => void disconnectDb());