@agentlensai/server 0.3.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/dist/db/embedding-store.d.ts +74 -0
  2. package/dist/db/embedding-store.d.ts.map +1 -0
  3. package/dist/db/embedding-store.js +177 -0
  4. package/dist/db/embedding-store.js.map +1 -0
  5. package/dist/db/health-snapshot-store.d.ts +33 -0
  6. package/dist/db/health-snapshot-store.d.ts.map +1 -0
  7. package/dist/db/health-snapshot-store.js +112 -0
  8. package/dist/db/health-snapshot-store.js.map +1 -0
  9. package/dist/db/lesson-store.d.ts +57 -0
  10. package/dist/db/lesson-store.d.ts.map +1 -0
  11. package/dist/db/lesson-store.js +217 -0
  12. package/dist/db/lesson-store.js.map +1 -0
  13. package/dist/db/migrate.d.ts.map +1 -1
  14. package/dist/db/migrate.js +256 -8
  15. package/dist/db/migrate.js.map +1 -1
  16. package/dist/db/schema.sqlite.d.ts +822 -47
  17. package/dist/db/schema.sqlite.d.ts.map +1 -1
  18. package/dist/db/schema.sqlite.js +79 -4
  19. package/dist/db/schema.sqlite.js.map +1 -1
  20. package/dist/db/session-summary-store.d.ts +45 -0
  21. package/dist/db/session-summary-store.d.ts.map +1 -0
  22. package/dist/db/session-summary-store.js +112 -0
  23. package/dist/db/session-summary-store.js.map +1 -0
  24. package/dist/db/sqlite-store.d.ts +19 -12
  25. package/dist/db/sqlite-store.d.ts.map +1 -1
  26. package/dist/db/sqlite-store.js +145 -44
  27. package/dist/db/sqlite-store.js.map +1 -1
  28. package/dist/db/tenant-scoped-store.d.ts +61 -0
  29. package/dist/db/tenant-scoped-store.d.ts.map +1 -0
  30. package/dist/db/tenant-scoped-store.js +94 -0
  31. package/dist/db/tenant-scoped-store.js.map +1 -0
  32. package/dist/index.d.ts +18 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +78 -5
  35. package/dist/index.js.map +1 -1
  36. package/dist/lib/alert-engine.d.ts +11 -0
  37. package/dist/lib/alert-engine.d.ts.map +1 -1
  38. package/dist/lib/alert-engine.js +65 -24
  39. package/dist/lib/alert-engine.js.map +1 -1
  40. package/dist/lib/analysis/cost-analysis.d.ts +20 -0
  41. package/dist/lib/analysis/cost-analysis.d.ts.map +1 -0
  42. package/dist/lib/analysis/cost-analysis.js +161 -0
  43. package/dist/lib/analysis/cost-analysis.js.map +1 -0
  44. package/dist/lib/analysis/error-patterns.d.ts +26 -0
  45. package/dist/lib/analysis/error-patterns.d.ts.map +1 -0
  46. package/dist/lib/analysis/error-patterns.js +158 -0
  47. package/dist/lib/analysis/error-patterns.js.map +1 -0
  48. package/dist/lib/analysis/index.d.ts +23 -0
  49. package/dist/lib/analysis/index.d.ts.map +1 -0
  50. package/dist/lib/analysis/index.js +144 -0
  51. package/dist/lib/analysis/index.js.map +1 -0
  52. package/dist/lib/analysis/performance-trends.d.ts +19 -0
  53. package/dist/lib/analysis/performance-trends.d.ts.map +1 -0
  54. package/dist/lib/analysis/performance-trends.js +121 -0
  55. package/dist/lib/analysis/performance-trends.js.map +1 -0
  56. package/dist/lib/analysis/tool-sequences.d.ts +19 -0
  57. package/dist/lib/analysis/tool-sequences.d.ts.map +1 -0
  58. package/dist/lib/analysis/tool-sequences.js +148 -0
  59. package/dist/lib/analysis/tool-sequences.js.map +1 -0
  60. package/dist/lib/context/index.d.ts +5 -0
  61. package/dist/lib/context/index.d.ts.map +1 -0
  62. package/dist/lib/context/index.js +5 -0
  63. package/dist/lib/context/index.js.map +1 -0
  64. package/dist/lib/context/retrieval.d.ts +60 -0
  65. package/dist/lib/context/retrieval.d.ts.map +1 -0
  66. package/dist/lib/context/retrieval.js +233 -0
  67. package/dist/lib/context/retrieval.js.map +1 -0
  68. package/dist/lib/embeddings/index.d.ts +31 -0
  69. package/dist/lib/embeddings/index.d.ts.map +1 -0
  70. package/dist/lib/embeddings/index.js +31 -0
  71. package/dist/lib/embeddings/index.js.map +1 -0
  72. package/dist/lib/embeddings/local.d.ts +15 -0
  73. package/dist/lib/embeddings/local.d.ts.map +1 -0
  74. package/dist/lib/embeddings/local.js +65 -0
  75. package/dist/lib/embeddings/local.js.map +1 -0
  76. package/dist/lib/embeddings/math.d.ts +13 -0
  77. package/dist/lib/embeddings/math.d.ts.map +1 -0
  78. package/dist/lib/embeddings/math.js +35 -0
  79. package/dist/lib/embeddings/math.js.map +1 -0
  80. package/dist/lib/embeddings/openai.d.ts +15 -0
  81. package/dist/lib/embeddings/openai.d.ts.map +1 -0
  82. package/dist/lib/embeddings/openai.js +58 -0
  83. package/dist/lib/embeddings/openai.js.map +1 -0
  84. package/dist/lib/embeddings/summarizer.d.ts +26 -0
  85. package/dist/lib/embeddings/summarizer.d.ts.map +1 -0
  86. package/dist/lib/embeddings/summarizer.js +181 -0
  87. package/dist/lib/embeddings/summarizer.js.map +1 -0
  88. package/dist/lib/embeddings/types.d.ts +17 -0
  89. package/dist/lib/embeddings/types.d.ts.map +1 -0
  90. package/dist/lib/embeddings/types.js +5 -0
  91. package/dist/lib/embeddings/types.js.map +1 -0
  92. package/dist/lib/embeddings/worker.d.ts +56 -0
  93. package/dist/lib/embeddings/worker.d.ts.map +1 -0
  94. package/dist/lib/embeddings/worker.js +109 -0
  95. package/dist/lib/embeddings/worker.js.map +1 -0
  96. package/dist/lib/health/computer.d.ts +28 -0
  97. package/dist/lib/health/computer.d.ts.map +1 -0
  98. package/dist/lib/health/computer.js +270 -0
  99. package/dist/lib/health/computer.js.map +1 -0
  100. package/dist/lib/optimization/classifier.d.ts +34 -0
  101. package/dist/lib/optimization/classifier.d.ts.map +1 -0
  102. package/dist/lib/optimization/classifier.js +108 -0
  103. package/dist/lib/optimization/classifier.js.map +1 -0
  104. package/dist/lib/optimization/engine.d.ts +24 -0
  105. package/dist/lib/optimization/engine.d.ts.map +1 -0
  106. package/dist/lib/optimization/engine.js +202 -0
  107. package/dist/lib/optimization/engine.js.map +1 -0
  108. package/dist/lib/optimization/index.d.ts +10 -0
  109. package/dist/lib/optimization/index.d.ts.map +1 -0
  110. package/dist/lib/optimization/index.js +9 -0
  111. package/dist/lib/optimization/index.js.map +1 -0
  112. package/dist/lib/sse.d.ts +1 -0
  113. package/dist/lib/sse.d.ts.map +1 -1
  114. package/dist/lib/sse.js +8 -1
  115. package/dist/lib/sse.js.map +1 -1
  116. package/dist/middleware/auth.d.ts +1 -0
  117. package/dist/middleware/auth.d.ts.map +1 -1
  118. package/dist/middleware/auth.js +2 -1
  119. package/dist/middleware/auth.js.map +1 -1
  120. package/dist/routes/agents.d.ts.map +1 -1
  121. package/dist/routes/agents.js +6 -3
  122. package/dist/routes/agents.js.map +1 -1
  123. package/dist/routes/alerts.d.ts.map +1 -1
  124. package/dist/routes/alerts.js +15 -7
  125. package/dist/routes/alerts.js.map +1 -1
  126. package/dist/routes/analytics.d.ts.map +1 -1
  127. package/dist/routes/analytics.js +16 -2
  128. package/dist/routes/analytics.js.map +1 -1
  129. package/dist/routes/api-keys.d.ts.map +1 -1
  130. package/dist/routes/api-keys.js +30 -5
  131. package/dist/routes/api-keys.js.map +1 -1
  132. package/dist/routes/context.d.ts +23 -0
  133. package/dist/routes/context.d.ts.map +1 -0
  134. package/dist/routes/context.js +52 -0
  135. package/dist/routes/context.js.map +1 -0
  136. package/dist/routes/events.d.ts +6 -1
  137. package/dist/routes/events.d.ts.map +1 -1
  138. package/dist/routes/events.js +61 -6
  139. package/dist/routes/events.js.map +1 -1
  140. package/dist/routes/health.d.ts +21 -0
  141. package/dist/routes/health.d.ts.map +1 -0
  142. package/dist/routes/health.js +142 -0
  143. package/dist/routes/health.js.map +1 -0
  144. package/dist/routes/ingest.d.ts +6 -0
  145. package/dist/routes/ingest.d.ts.map +1 -1
  146. package/dist/routes/ingest.js +23 -4
  147. package/dist/routes/ingest.js.map +1 -1
  148. package/dist/routes/lessons.d.ts +19 -0
  149. package/dist/routes/lessons.d.ts.map +1 -0
  150. package/dist/routes/lessons.js +164 -0
  151. package/dist/routes/lessons.js.map +1 -0
  152. package/dist/routes/optimize.d.ts +15 -0
  153. package/dist/routes/optimize.d.ts.map +1 -0
  154. package/dist/routes/optimize.js +55 -0
  155. package/dist/routes/optimize.js.map +1 -0
  156. package/dist/routes/recall.d.ts +22 -0
  157. package/dist/routes/recall.d.ts.map +1 -0
  158. package/dist/routes/recall.js +91 -0
  159. package/dist/routes/recall.js.map +1 -0
  160. package/dist/routes/reflect.d.ts +15 -0
  161. package/dist/routes/reflect.d.ts.map +1 -0
  162. package/dist/routes/reflect.js +54 -0
  163. package/dist/routes/reflect.js.map +1 -0
  164. package/dist/routes/sessions.d.ts.map +1 -1
  165. package/dist/routes/sessions.js +8 -6
  166. package/dist/routes/sessions.js.map +1 -1
  167. package/dist/routes/stats.d.ts.map +1 -1
  168. package/dist/routes/stats.js +3 -1
  169. package/dist/routes/stats.js.map +1 -1
  170. package/dist/routes/stream.d.ts +9 -2
  171. package/dist/routes/stream.d.ts.map +1 -1
  172. package/dist/routes/stream.js +55 -2
  173. package/dist/routes/stream.js.map +1 -1
  174. package/dist/routes/tenant-helper.d.ts +20 -0
  175. package/dist/routes/tenant-helper.d.ts.map +1 -0
  176. package/dist/routes/tenant-helper.js +35 -0
  177. package/dist/routes/tenant-helper.js.map +1 -0
  178. package/package.json +11 -11
  179. package/LICENSE +0 -21
  180. package/dist/__tests__/agents-stats.test.d.ts +0 -5
  181. package/dist/__tests__/agents-stats.test.d.ts.map +0 -1
  182. package/dist/__tests__/agents-stats.test.js +0 -134
  183. package/dist/__tests__/agents-stats.test.js.map +0 -1
  184. package/dist/__tests__/alerts.test.d.ts +0 -5
  185. package/dist/__tests__/alerts.test.d.ts.map +0 -1
  186. package/dist/__tests__/alerts.test.js +0 -245
  187. package/dist/__tests__/alerts.test.js.map +0 -1
  188. package/dist/__tests__/analytics.test.d.ts +0 -5
  189. package/dist/__tests__/analytics.test.d.ts.map +0 -1
  190. package/dist/__tests__/analytics.test.js +0 -218
  191. package/dist/__tests__/analytics.test.js.map +0 -1
  192. package/dist/__tests__/api-keys.test.d.ts +0 -5
  193. package/dist/__tests__/api-keys.test.d.ts.map +0 -1
  194. package/dist/__tests__/api-keys.test.js +0 -118
  195. package/dist/__tests__/api-keys.test.js.map +0 -1
  196. package/dist/__tests__/auth-no-db.test.d.ts +0 -2
  197. package/dist/__tests__/auth-no-db.test.d.ts.map +0 -1
  198. package/dist/__tests__/auth-no-db.test.js +0 -43
  199. package/dist/__tests__/auth-no-db.test.js.map +0 -1
  200. package/dist/__tests__/auth.test.d.ts +0 -5
  201. package/dist/__tests__/auth.test.d.ts.map +0 -1
  202. package/dist/__tests__/auth.test.js +0 -86
  203. package/dist/__tests__/auth.test.js.map +0 -1
  204. package/dist/__tests__/config.test.d.ts +0 -2
  205. package/dist/__tests__/config.test.d.ts.map +0 -1
  206. package/dist/__tests__/config.test.js +0 -37
  207. package/dist/__tests__/config.test.js.map +0 -1
  208. package/dist/__tests__/events-ingest.test.d.ts +0 -5
  209. package/dist/__tests__/events-ingest.test.d.ts.map +0 -1
  210. package/dist/__tests__/events-ingest.test.js +0 -248
  211. package/dist/__tests__/events-ingest.test.js.map +0 -1
  212. package/dist/__tests__/events-query.test.d.ts +0 -5
  213. package/dist/__tests__/events-query.test.d.ts.map +0 -1
  214. package/dist/__tests__/events-query.test.js +0 -205
  215. package/dist/__tests__/events-query.test.js.map +0 -1
  216. package/dist/__tests__/health.test.d.ts +0 -5
  217. package/dist/__tests__/health.test.d.ts.map +0 -1
  218. package/dist/__tests__/health.test.js +0 -40
  219. package/dist/__tests__/health.test.js.map +0 -1
  220. package/dist/__tests__/ingest.test.d.ts +0 -8
  221. package/dist/__tests__/ingest.test.d.ts.map +0 -1
  222. package/dist/__tests__/ingest.test.js +0 -469
  223. package/dist/__tests__/ingest.test.js.map +0 -1
  224. package/dist/__tests__/llm-tracking.test.d.ts +0 -10
  225. package/dist/__tests__/llm-tracking.test.d.ts.map +0 -1
  226. package/dist/__tests__/llm-tracking.test.js +0 -602
  227. package/dist/__tests__/llm-tracking.test.js.map +0 -1
  228. package/dist/__tests__/sessions.test.d.ts +0 -5
  229. package/dist/__tests__/sessions.test.d.ts.map +0 -1
  230. package/dist/__tests__/sessions.test.js +0 -176
  231. package/dist/__tests__/sessions.test.js.map +0 -1
  232. package/dist/__tests__/stream.test.d.ts +0 -5
  233. package/dist/__tests__/stream.test.d.ts.map +0 -1
  234. package/dist/__tests__/stream.test.js +0 -352
  235. package/dist/__tests__/stream.test.js.map +0 -1
  236. package/dist/__tests__/test-helpers.d.ts +0 -24
  237. package/dist/__tests__/test-helpers.d.ts.map +0 -1
  238. package/dist/__tests__/test-helpers.js +0 -45
  239. package/dist/__tests__/test-helpers.js.map +0 -1
  240. package/dist/db/__tests__/init.test.d.ts +0 -2
  241. package/dist/db/__tests__/init.test.d.ts.map +0 -1
  242. package/dist/db/__tests__/init.test.js +0 -73
  243. package/dist/db/__tests__/init.test.js.map +0 -1
  244. package/dist/db/__tests__/sqlite-store-read.test.d.ts +0 -2
  245. package/dist/db/__tests__/sqlite-store-read.test.d.ts.map +0 -1
  246. package/dist/db/__tests__/sqlite-store-read.test.js +0 -749
  247. package/dist/db/__tests__/sqlite-store-read.test.js.map +0 -1
  248. package/dist/db/__tests__/sqlite-store-write.test.d.ts +0 -2
  249. package/dist/db/__tests__/sqlite-store-write.test.d.ts.map +0 -1
  250. package/dist/db/__tests__/sqlite-store-write.test.js +0 -418
  251. package/dist/db/__tests__/sqlite-store-write.test.js.map +0 -1
  252. package/dist/lib/__tests__/alert-engine.test.d.ts +0 -5
  253. package/dist/lib/__tests__/alert-engine.test.d.ts.map +0 -1
  254. package/dist/lib/__tests__/alert-engine.test.js +0 -211
  255. package/dist/lib/__tests__/alert-engine.test.js.map +0 -1
  256. package/dist/lib/__tests__/retention.test.d.ts +0 -2
  257. package/dist/lib/__tests__/retention.test.d.ts.map +0 -1
  258. package/dist/lib/__tests__/retention.test.js +0 -238
  259. package/dist/lib/__tests__/retention.test.js.map +0 -1
@@ -1,211 +0,0 @@
1
- /**
2
- * Tests for Alert Evaluation Engine (Story 12.2)
3
- */
4
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
5
- import { ulid } from 'ulid';
6
- import { createTestDb } from '../../db/index.js';
7
- import { runMigrations } from '../../db/migrate.js';
8
- import { SqliteEventStore } from '../../db/sqlite-store.js';
9
- import { AlertEngine } from '../alert-engine.js';
10
- import { eventBus } from '../event-bus.js';
11
- import { computeEventHash } from '@agentlensai/core';
12
- let db;
13
- let store;
14
- let engine;
15
- function makeEvent(overrides, prevHash = null) {
16
- const id = ulid();
17
- const base = {
18
- id,
19
- timestamp: new Date().toISOString(),
20
- sessionId: overrides.sessionId,
21
- agentId: overrides.agentId,
22
- eventType: overrides.eventType ?? 'tool_call',
23
- severity: overrides.severity ?? 'info',
24
- payload: overrides.payload ?? { toolName: 'test', callId: id, arguments: {} },
25
- metadata: overrides.metadata ?? {},
26
- prevHash,
27
- hash: '',
28
- };
29
- base.hash = computeEventHash({
30
- id: base.id,
31
- timestamp: base.timestamp,
32
- sessionId: base.sessionId,
33
- agentId: base.agentId,
34
- eventType: base.eventType,
35
- severity: base.severity,
36
- payload: base.payload,
37
- metadata: base.metadata,
38
- prevHash: base.prevHash,
39
- });
40
- return base;
41
- }
42
- beforeEach(() => {
43
- db = createTestDb();
44
- runMigrations(db);
45
- store = new SqliteEventStore(db);
46
- engine = new AlertEngine(store, { checkIntervalMs: 60_000 });
47
- });
48
- afterEach(() => {
49
- engine.stop();
50
- eventBus.removeAllListeners();
51
- });
52
- describe('AlertEngine.evaluate()', () => {
53
- it('returns empty when no rules exist', async () => {
54
- const triggered = await engine.evaluate();
55
- expect(triggered).toEqual([]);
56
- });
57
- it('returns empty when rules are disabled', async () => {
58
- const now = new Date().toISOString();
59
- await store.createAlertRule({
60
- id: ulid(),
61
- name: 'Disabled Rule',
62
- enabled: false,
63
- condition: 'error_rate_exceeds',
64
- threshold: 0.01,
65
- windowMinutes: 60,
66
- scope: {},
67
- notifyChannels: [],
68
- createdAt: now,
69
- updatedAt: now,
70
- });
71
- const triggered = await engine.evaluate();
72
- expect(triggered).toEqual([]);
73
- });
74
- it('triggers when error rate exceeds threshold', async () => {
75
- const now = new Date().toISOString();
76
- // Create rule
77
- await store.createAlertRule({
78
- id: ulid(),
79
- name: 'Error Rate Alert',
80
- enabled: true,
81
- condition: 'error_rate_exceeds',
82
- threshold: 0.1, // 10%
83
- windowMinutes: 60,
84
- scope: {},
85
- notifyChannels: [],
86
- createdAt: now,
87
- updatedAt: now,
88
- });
89
- // Insert events as a single batch: 1 start + 8 normal + 2 errors = ~18% error rate
90
- const sessionId = 'test-session';
91
- const agentId = 'test-agent';
92
- const batch = [];
93
- const startEvent = makeEvent({ sessionId, agentId, eventType: 'session_started', payload: { agentName: 'test' } }, null);
94
- batch.push(startEvent);
95
- let prevHash = startEvent.hash;
96
- for (let i = 0; i < 8; i++) {
97
- const ev = makeEvent({ sessionId, agentId }, prevHash);
98
- batch.push(ev);
99
- prevHash = ev.hash;
100
- }
101
- // Error events
102
- for (let i = 0; i < 2; i++) {
103
- const ev = makeEvent({ sessionId, agentId, eventType: 'tool_error', severity: 'error', payload: { toolName: 'test', callId: ulid(), error: 'fail', durationMs: 100 } }, prevHash);
104
- batch.push(ev);
105
- prevHash = ev.hash;
106
- }
107
- await store.insertEvents(batch);
108
- // Track EventBus emission
109
- const emitted = [];
110
- eventBus.on('alert_triggered', (ev) => emitted.push(ev));
111
- const triggered = await engine.evaluate();
112
- expect(triggered).toHaveLength(1);
113
- expect(triggered[0].message).toContain('Error rate');
114
- expect(emitted).toHaveLength(1);
115
- // Verify it was persisted in history
116
- const history = await store.listAlertHistory();
117
- expect(history.entries).toHaveLength(1);
118
- });
119
- it('does not trigger when below threshold', async () => {
120
- const now = new Date().toISOString();
121
- await store.createAlertRule({
122
- id: ulid(),
123
- name: 'Error Rate Alert',
124
- enabled: true,
125
- condition: 'error_rate_exceeds',
126
- threshold: 0.5, // 50% — very high
127
- windowMinutes: 60,
128
- scope: {},
129
- notifyChannels: [],
130
- createdAt: now,
131
- updatedAt: now,
132
- });
133
- // Insert events as a single batch to avoid hash chain issues
134
- const sessionId = 'test-session';
135
- const agentId = 'test-agent';
136
- const batch = [];
137
- const startEvent = makeEvent({ sessionId, agentId, eventType: 'session_started', payload: { agentName: 'test' } }, null);
138
- batch.push(startEvent);
139
- let prevHash = startEvent.hash;
140
- for (let i = 0; i < 9; i++) {
141
- const ev = makeEvent({ sessionId, agentId }, prevHash);
142
- batch.push(ev);
143
- prevHash = ev.hash;
144
- }
145
- const errEv = makeEvent({ sessionId, agentId, eventType: 'tool_error', severity: 'error', payload: { toolName: 'test', callId: ulid(), error: 'fail', durationMs: 100 } }, prevHash);
146
- batch.push(errEv);
147
- await store.insertEvents(batch);
148
- const triggered = await engine.evaluate();
149
- expect(triggered).toEqual([]);
150
- });
151
- it('triggers event_count_exceeds rule', async () => {
152
- const now = new Date().toISOString();
153
- await store.createAlertRule({
154
- id: ulid(),
155
- name: 'Event Count Alert',
156
- enabled: true,
157
- condition: 'event_count_exceeds',
158
- threshold: 3,
159
- windowMinutes: 60,
160
- scope: {},
161
- notifyChannels: [],
162
- createdAt: now,
163
- updatedAt: now,
164
- });
165
- // Insert 5 events as a batch (>3 threshold)
166
- const sessionId = 'test-session';
167
- const agentId = 'test-agent';
168
- const batch = [];
169
- const startEvent = makeEvent({ sessionId, agentId, eventType: 'session_started', payload: { agentName: 'test' } }, null);
170
- batch.push(startEvent);
171
- let prevHash = startEvent.hash;
172
- for (let i = 0; i < 4; i++) {
173
- const ev = makeEvent({ sessionId, agentId }, prevHash);
174
- batch.push(ev);
175
- prevHash = ev.hash;
176
- }
177
- await store.insertEvents(batch);
178
- const triggered = await engine.evaluate();
179
- expect(triggered).toHaveLength(1);
180
- expect(triggered[0].message).toContain('Event count');
181
- });
182
- it('triggers no_events_for when no events exist', async () => {
183
- const now = new Date().toISOString();
184
- await store.createAlertRule({
185
- id: ulid(),
186
- name: 'No Events Alert',
187
- enabled: true,
188
- condition: 'no_events_for',
189
- threshold: 0,
190
- windowMinutes: 5,
191
- scope: {},
192
- notifyChannels: [],
193
- createdAt: now,
194
- updatedAt: now,
195
- });
196
- // No events inserted
197
- const triggered = await engine.evaluate();
198
- expect(triggered).toHaveLength(1);
199
- expect(triggered[0].message).toContain('No events');
200
- });
201
- });
202
- describe('AlertEngine lifecycle', () => {
203
- it('can start and stop', () => {
204
- engine.start();
205
- // Starting twice is a no-op
206
- engine.start();
207
- engine.stop();
208
- engine.stop(); // Stopping twice is safe
209
- });
210
- });
211
- //# sourceMappingURL=alert-engine.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"alert-engine.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/alert-engine.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,IAAI,EAAY,CAAC;AACjB,IAAI,KAAuB,CAAC;AAC5B,IAAI,MAAmB,CAAC;AAExB,SAAS,SAAS,CAChB,SAA2E,EAC3E,WAA0B,IAAI;IAE9B,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC;IAClB,MAAM,IAAI,GAAG;QACX,EAAE;QACF,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,SAAS,EAAE,SAAS,CAAC,SAAS,IAAK,WAAqB;QACxD,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAK,MAAgB;QACjD,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC7E,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,EAAE;QAClC,QAAQ;QACR,IAAI,EAAE,EAAE;KACT,CAAC;IAEF,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IAEH,OAAO,IAAsB,CAAC;AAChC,CAAC;AAED,UAAU,CAAC,GAAG,EAAE;IACd,EAAE,GAAG,YAAY,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,CAAC;IAClB,KAAK,GAAG,IAAI,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,QAAQ,CAAC,kBAAkB,EAAE,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,KAAK,CAAC,eAAe,CAAC;YAC1B,EAAE,EAAE,IAAI,EAAE;YACV,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,oBAAoB;YAC/B,SAAS,EAAE,IAAI;YACf,aAAa,EAAE,EAAE;YACjB,KAAK,EAAE,EAAE;YACT,cAAc,EAAE,EAAE;YAClB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,cAAc;QACd,MAAM,KAAK,CAAC,eAAe,CAAC;YAC1B,EAAE,EAAE,IAAI,EAAE;YACV,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,oBAAoB;YAC/B,SAAS,EAAE,GAAG,EAAE,MAAM;YACtB,aAAa,EAAE,EAAE;YACjB,KAAK,EAAE,EAAE;YACT,cAAc,EAAE,EAAE;YAClB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QAEH,mFAAmF;QACnF,MAAM,SAAS,GAAG,cAAc,CAAC;QACjC,MAAM,OAAO,GAAG,YAAY,CAAC;QAC7B,MAAM,KAAK,GAAqB,EAAE,CAAC;QAEnC,MAAM,UAAU,GAAG,SAAS,CAC1B,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EACpF,IAAI,CACL,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvB,IAAI,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;QAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,eAAe;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,SAAS,CAClB,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,EACjJ,QAAQ,CACT,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAEhC,0BAA0B;QAC1B,MAAM,OAAO,GAAc,EAAE,CAAC;QAC9B,QAAQ,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAEzD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAEhC,qCAAqC;QACrC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC/C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,MAAM,KAAK,CAAC,eAAe,CAAC;YAC1B,EAAE,EAAE,IAAI,EAAE;YACV,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,oBAAoB;YAC/B,SAAS,EAAE,GAAG,EAAE,kBAAkB;YAClC,aAAa,EAAE,EAAE;YACjB,KAAK,EAAE,EAAE;YACT,cAAc,EAAE,EAAE;YAClB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QAEH,6DAA6D;QAC7D,MAAM,SAAS,GAAG,cAAc,CAAC;QACjC,MAAM,OAAO,GAAG,YAAY,CAAC;QAC7B,MAAM,KAAK,GAAqB,EAAE,CAAC;QAEnC,MAAM,UAAU,GAAG,SAAS,CAC1B,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EACpF,IAAI,CACL,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvB,IAAI,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;QAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,CACrB,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,EACjJ,QAAQ,CACT,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAElB,MAAM,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAEhC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,MAAM,KAAK,CAAC,eAAe,CAAC;YAC1B,EAAE,EAAE,IAAI,EAAE;YACV,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,qBAAqB;YAChC,SAAS,EAAE,CAAC;YACZ,aAAa,EAAE,EAAE;YACjB,KAAK,EAAE,EAAE;YACT,cAAc,EAAE,EAAE;YAClB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QAEH,4CAA4C;QAC5C,MAAM,SAAS,GAAG,cAAc,CAAC;QACjC,MAAM,OAAO,GAAG,YAAY,CAAC;QAC7B,MAAM,KAAK,GAAqB,EAAE,CAAC;QAEnC,MAAM,UAAU,GAAG,SAAS,CAC1B,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EACpF,IAAI,CACL,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvB,IAAI,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;QAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAEhC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,MAAM,KAAK,CAAC,eAAe,CAAC;YAC1B,EAAE,EAAE,IAAI,EAAE;YACV,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,eAAe;YAC1B,SAAS,EAAE,CAAC;YACZ,aAAa,EAAE,CAAC;YAChB,KAAK,EAAE,EAAE;YACT,cAAc,EAAE,EAAE;YAClB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QAEH,qBAAqB;QACrB,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,4BAA4B;QAC5B,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,yBAAyB;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=retention.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"retention.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/retention.test.ts"],"names":[],"mappings":""}
@@ -1,238 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { computeEventHash } from '@agentlensai/core';
3
- import { createTestDb } from '../../db/index.js';
4
- import { runMigrations } from '../../db/migrate.js';
5
- import { SqliteEventStore } from '../../db/sqlite-store.js';
6
- import { applyRetention } from '../retention.js';
7
- let counter = 0;
8
- function makeEvent(overrides = {}) {
9
- counter++;
10
- const id = overrides.id ?? `evt_${String(counter).padStart(6, '0')}`;
11
- const base = {
12
- id,
13
- timestamp: overrides.timestamp ?? new Date().toISOString(),
14
- sessionId: overrides.sessionId ?? 'sess_001',
15
- agentId: overrides.agentId ?? 'agent_001',
16
- eventType: overrides.eventType ?? 'custom',
17
- severity: overrides.severity ?? 'info',
18
- payload: overrides.payload ?? { type: 'test', data: {} },
19
- metadata: overrides.metadata ?? {},
20
- prevHash: overrides.prevHash ?? null,
21
- };
22
- const hash = computeEventHash({
23
- id: base.id,
24
- timestamp: base.timestamp,
25
- sessionId: base.sessionId,
26
- agentId: base.agentId,
27
- eventType: base.eventType,
28
- severity: base.severity,
29
- payload: base.payload,
30
- metadata: base.metadata,
31
- prevHash: base.prevHash,
32
- });
33
- return { ...base, hash };
34
- }
35
- function makeChain(overridesList) {
36
- const chain = [];
37
- let prevHash = null;
38
- for (const overrides of overridesList) {
39
- const event = makeEvent({ ...overrides, prevHash });
40
- chain.push(event);
41
- prevHash = event.hash;
42
- }
43
- return chain;
44
- }
45
- function daysAgo(days) {
46
- const d = new Date();
47
- d.setDate(d.getDate() - days);
48
- return d.toISOString();
49
- }
50
- describe('Retention Policy Engine (Story 3.6)', () => {
51
- let db;
52
- let store;
53
- beforeEach(() => {
54
- counter = 0;
55
- db = createTestDb();
56
- runMigrations(db);
57
- store = new SqliteEventStore(db);
58
- });
59
- describe('applyRetention()', () => {
60
- it('should delete events older than configured retention days', async () => {
61
- // Old session chain
62
- const oldChain = makeChain([
63
- {
64
- id: 'old_1',
65
- sessionId: 'sess_old',
66
- timestamp: daysAgo(100),
67
- eventType: 'session_started',
68
- payload: { tags: [] },
69
- },
70
- {
71
- id: 'old_2',
72
- sessionId: 'sess_old',
73
- timestamp: daysAgo(95),
74
- },
75
- ]);
76
- // Recent session chain
77
- const recentChain = makeChain([
78
- {
79
- id: 'recent_1',
80
- sessionId: 'sess_new',
81
- timestamp: daysAgo(10),
82
- eventType: 'session_started',
83
- payload: { tags: [] },
84
- },
85
- {
86
- id: 'recent_2',
87
- sessionId: 'sess_new',
88
- timestamp: daysAgo(5),
89
- },
90
- ]);
91
- await store.insertEvents(oldChain);
92
- await store.insertEvents(recentChain);
93
- const result = await applyRetention(store, { retentionDays: 90 });
94
- expect(result.deletedCount).toBe(2);
95
- expect(result.skipped).toBe(false);
96
- const old1 = await store.getEvent('old_1');
97
- expect(old1).toBeNull();
98
- const old2 = await store.getEvent('old_2');
99
- expect(old2).toBeNull();
100
- const recent1 = await store.getEvent('recent_1');
101
- expect(recent1).not.toBeNull();
102
- const recent2 = await store.getEvent('recent_2');
103
- expect(recent2).not.toBeNull();
104
- });
105
- it('should clean up sessions with no remaining events', async () => {
106
- const oldChain = makeChain([
107
- {
108
- id: 'old_evt',
109
- sessionId: 'sess_old',
110
- timestamp: daysAgo(100),
111
- eventType: 'session_started',
112
- payload: { tags: [] },
113
- },
114
- ]);
115
- const newChain = makeChain([
116
- {
117
- id: 'new_evt',
118
- sessionId: 'sess_new',
119
- timestamp: daysAgo(5),
120
- eventType: 'session_started',
121
- payload: { tags: [] },
122
- },
123
- ]);
124
- await store.insertEvents(oldChain);
125
- await store.insertEvents(newChain);
126
- const beforeStats = await store.getStats();
127
- expect(beforeStats.totalSessions).toBe(2);
128
- await applyRetention(store, { retentionDays: 90 });
129
- const afterStats = await store.getStats();
130
- expect(afterStats.totalSessions).toBe(1);
131
- const oldSession = await store.getSession('sess_old');
132
- expect(oldSession).toBeNull();
133
- const newSession = await store.getSession('sess_new');
134
- expect(newSession).not.toBeNull();
135
- });
136
- it('should return deletedCount of 0 when no events are old enough', async () => {
137
- const chain = makeChain([
138
- {
139
- timestamp: daysAgo(10),
140
- eventType: 'session_started',
141
- payload: { tags: [] },
142
- },
143
- { timestamp: daysAgo(5) },
144
- ]);
145
- await store.insertEvents(chain);
146
- const result = await applyRetention(store, { retentionDays: 90 });
147
- expect(result.deletedCount).toBe(0);
148
- expect(result.skipped).toBe(false);
149
- const stats = await store.getStats();
150
- expect(stats.totalEvents).toBe(2);
151
- });
152
- it('should skip deletion when RETENTION_DAYS=0 (keep forever)', async () => {
153
- const chain = makeChain([
154
- {
155
- timestamp: daysAgo(365),
156
- eventType: 'session_started',
157
- payload: { tags: [] },
158
- },
159
- { timestamp: daysAgo(300) },
160
- ]);
161
- await store.insertEvents(chain);
162
- const result = await applyRetention(store, { retentionDays: 0 });
163
- expect(result.deletedCount).toBe(0);
164
- expect(result.skipped).toBe(true);
165
- const stats = await store.getStats();
166
- expect(stats.totalEvents).toBe(2);
167
- });
168
- it('should skip deletion when retentionDays is negative', async () => {
169
- await store.insertEvents([
170
- makeEvent({
171
- timestamp: daysAgo(365),
172
- eventType: 'session_started',
173
- payload: { tags: [] },
174
- }),
175
- ]);
176
- const result = await applyRetention(store, { retentionDays: -1 });
177
- expect(result.deletedCount).toBe(0);
178
- expect(result.skipped).toBe(true);
179
- });
180
- it('should handle mixed-age events correctly (partial deletion)', async () => {
181
- const chain = makeChain([
182
- { id: 'e1', sessionId: 'sA', timestamp: daysAgo(200), eventType: 'session_started', payload: { tags: [] } },
183
- { id: 'e2', sessionId: 'sA', timestamp: daysAgo(150) },
184
- { id: 'e3', sessionId: 'sA', timestamp: daysAgo(100) },
185
- { id: 'e4', sessionId: 'sA', timestamp: daysAgo(30) },
186
- { id: 'e5', sessionId: 'sA', timestamp: daysAgo(1) },
187
- ]);
188
- await store.insertEvents(chain);
189
- const result = await applyRetention(store, { retentionDays: 90 });
190
- expect(result.deletedCount).toBe(3);
191
- const stats = await store.getStats();
192
- expect(stats.totalEvents).toBe(2);
193
- expect(stats.totalSessions).toBe(1);
194
- });
195
- it('should work with the IEventStore.applyRetention() directly', async () => {
196
- const chain = makeChain([
197
- {
198
- id: 'old',
199
- sessionId: 'sess_direct',
200
- timestamp: '2020-01-01T00:00:00Z',
201
- eventType: 'session_started',
202
- payload: { tags: [] },
203
- },
204
- {
205
- id: 'new',
206
- sessionId: 'sess_direct',
207
- timestamp: new Date().toISOString(),
208
- },
209
- ]);
210
- await store.insertEvents(chain);
211
- const result = await store.applyRetention('2023-01-01T00:00:00Z');
212
- expect(result.deletedCount).toBe(1);
213
- });
214
- it('should handle empty database without error', async () => {
215
- const result = await applyRetention(store, { retentionDays: 90 });
216
- expect(result.deletedCount).toBe(0);
217
- expect(result.skipped).toBe(false);
218
- });
219
- it('should delete all events when all are old enough', async () => {
220
- // Each session is its own chain
221
- const chain1 = makeChain([
222
- { id: 'e1', sessionId: 's1', timestamp: daysAgo(365), eventType: 'session_started', payload: { tags: [] } },
223
- { id: 'e2', sessionId: 's1', timestamp: daysAgo(200) },
224
- ]);
225
- const chain2 = makeChain([
226
- { id: 'e3', sessionId: 's2', timestamp: daysAgo(100), eventType: 'session_started', payload: { tags: [] } },
227
- ]);
228
- await store.insertEvents(chain1);
229
- await store.insertEvents(chain2);
230
- const result = await applyRetention(store, { retentionDays: 90 });
231
- expect(result.deletedCount).toBe(3);
232
- const stats = await store.getStats();
233
- expect(stats.totalEvents).toBe(0);
234
- expect(stats.totalSessions).toBe(0);
235
- });
236
- });
237
- });
238
- //# sourceMappingURL=retention.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"retention.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/retention.test.ts"],"names":[],"mappings":"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"}