atabey-shared 0.1.0-beta.0 → 0.1.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 (221) hide show
  1. package/README.md +63 -24
  2. package/dist/agent-identity.d.ts +1 -34
  3. package/dist/agent-identity.js +1 -76
  4. package/dist/agent-identity.js.map +1 -1
  5. package/dist/api-catalog.d.ts +1 -57
  6. package/dist/api-catalog.js +1 -253
  7. package/dist/api-catalog.js.map +1 -1
  8. package/dist/audit-chain.d.ts +1 -80
  9. package/dist/audit-chain.js +1 -261
  10. package/dist/audit-chain.js.map +1 -1
  11. package/dist/audit.d.ts +1 -121
  12. package/dist/audit.js +1 -321
  13. package/dist/audit.js.map +1 -1
  14. package/dist/constants.d.ts +1 -153
  15. package/dist/constants.js +1 -214
  16. package/dist/constants.js.map +1 -1
  17. package/dist/database.d.ts +1 -5
  18. package/dist/database.js +1 -12
  19. package/dist/database.js.map +1 -1
  20. package/dist/errors.d.ts +1 -46
  21. package/dist/errors.js +1 -68
  22. package/dist/errors.js.map +1 -1
  23. package/dist/file-lock.d.ts +1 -93
  24. package/dist/file-lock.js +1 -239
  25. package/dist/file-lock.js.map +1 -1
  26. package/dist/fs.d.ts +1 -9
  27. package/dist/fs.js +1 -53
  28. package/dist/fs.js.map +1 -1
  29. package/dist/index.d.ts +2 -31
  30. package/dist/index.js +2 -31
  31. package/dist/index.js.map +1 -1
  32. package/dist/job-queue.d.ts +1 -53
  33. package/dist/job-queue.js +1 -126
  34. package/dist/job-queue.js.map +1 -1
  35. package/dist/lock.d.ts +1 -82
  36. package/dist/lock.js +1 -158
  37. package/dist/lock.js.map +1 -1
  38. package/dist/logger.d.ts +1 -31
  39. package/dist/logger.js +1 -152
  40. package/dist/logger.js.map +1 -1
  41. package/dist/memory-prune.d.ts +1 -18
  42. package/dist/memory-prune.js +1 -47
  43. package/dist/memory-prune.js.map +1 -1
  44. package/dist/migrations.d.ts +1 -69
  45. package/dist/migrations.js +1 -374
  46. package/dist/migrations.js.map +1 -1
  47. package/dist/modules/agent/agent-identity.d.ts +34 -0
  48. package/dist/modules/agent/agent-identity.js +77 -0
  49. package/dist/modules/agent/agent-identity.js.map +1 -0
  50. package/dist/modules/agent/api-catalog.d.ts +57 -0
  51. package/dist/modules/agent/api-catalog.js +254 -0
  52. package/dist/modules/agent/api-catalog.js.map +1 -0
  53. package/dist/modules/agent/index.d.ts +3 -0
  54. package/dist/modules/agent/index.js +4 -0
  55. package/dist/modules/agent/index.js.map +1 -0
  56. package/dist/modules/agent/tokenizer.d.ts +54 -0
  57. package/dist/modules/agent/tokenizer.js +272 -0
  58. package/dist/modules/agent/tokenizer.js.map +1 -0
  59. package/dist/modules/concurrency/file-lock.d.ts +93 -0
  60. package/dist/modules/concurrency/file-lock.js +240 -0
  61. package/dist/modules/concurrency/file-lock.js.map +1 -0
  62. package/dist/modules/concurrency/index.d.ts +6 -0
  63. package/dist/modules/concurrency/index.js +7 -0
  64. package/dist/modules/concurrency/index.js.map +1 -0
  65. package/dist/modules/concurrency/job-queue.d.ts +76 -0
  66. package/dist/modules/concurrency/job-queue.js +200 -0
  67. package/dist/modules/concurrency/job-queue.js.map +1 -0
  68. package/dist/modules/concurrency/lock.d.ts +82 -0
  69. package/dist/modules/concurrency/lock.js +159 -0
  70. package/dist/modules/concurrency/lock.js.map +1 -0
  71. package/dist/modules/concurrency/resilience.d.ts +84 -0
  72. package/dist/modules/concurrency/resilience.js +217 -0
  73. package/dist/modules/concurrency/resilience.js.map +1 -0
  74. package/dist/modules/concurrency/worker-pool.d.ts +52 -0
  75. package/dist/modules/concurrency/worker-pool.js +229 -0
  76. package/dist/modules/concurrency/worker-pool.js.map +1 -0
  77. package/dist/modules/concurrency/worker-thread.d.ts +21 -0
  78. package/dist/modules/concurrency/worker-thread.js +67 -0
  79. package/dist/modules/concurrency/worker-thread.js.map +1 -0
  80. package/dist/modules/index.d.ts +14 -0
  81. package/dist/modules/index.js +15 -0
  82. package/dist/modules/index.js.map +1 -0
  83. package/dist/modules/observability/audit-chain.d.ts +80 -0
  84. package/dist/modules/observability/audit-chain.js +262 -0
  85. package/dist/modules/observability/audit-chain.js.map +1 -0
  86. package/dist/modules/observability/audit.d.ts +121 -0
  87. package/dist/modules/observability/audit.js +322 -0
  88. package/dist/modules/observability/audit.js.map +1 -0
  89. package/dist/modules/observability/index.d.ts +4 -0
  90. package/dist/modules/observability/index.js +5 -0
  91. package/dist/modules/observability/index.js.map +1 -0
  92. package/dist/modules/observability/logger.d.ts +31 -0
  93. package/dist/modules/observability/logger.js +153 -0
  94. package/dist/modules/observability/logger.js.map +1 -0
  95. package/dist/modules/observability/otel.d.ts +39 -0
  96. package/dist/modules/observability/otel.js +93 -0
  97. package/dist/modules/observability/otel.js.map +1 -0
  98. package/dist/modules/primitives/constants.d.ts +150 -0
  99. package/dist/modules/primitives/constants.js +212 -0
  100. package/dist/modules/primitives/constants.js.map +1 -0
  101. package/dist/modules/primitives/errors.d.ts +46 -0
  102. package/dist/modules/primitives/errors.js +69 -0
  103. package/dist/modules/primitives/errors.js.map +1 -0
  104. package/dist/modules/primitives/fs.d.ts +9 -0
  105. package/dist/modules/primitives/fs.js +54 -0
  106. package/dist/modules/primitives/fs.js.map +1 -0
  107. package/dist/modules/primitives/index.d.ts +7 -0
  108. package/dist/modules/primitives/index.js +8 -0
  109. package/dist/modules/primitives/index.js.map +1 -0
  110. package/dist/modules/primitives/outbound-http.d.ts +32 -0
  111. package/dist/modules/primitives/outbound-http.js +88 -0
  112. package/dist/modules/primitives/outbound-http.js.map +1 -0
  113. package/dist/modules/primitives/string.d.ts +1 -0
  114. package/dist/modules/primitives/string.js +30 -0
  115. package/dist/modules/primitives/string.js.map +1 -0
  116. package/dist/modules/primitives/time.d.ts +5 -0
  117. package/dist/modules/primitives/time.js +35 -0
  118. package/dist/modules/primitives/time.js.map +1 -0
  119. package/dist/modules/primitives/types.d.ts +27 -0
  120. package/dist/modules/primitives/types.js +17 -0
  121. package/dist/modules/primitives/types.js.map +1 -0
  122. package/dist/modules/sandbox/index.d.ts +3 -0
  123. package/dist/modules/sandbox/index.js +4 -0
  124. package/dist/modules/sandbox/index.js.map +1 -0
  125. package/dist/modules/sandbox/sandbox-fs.d.ts +28 -0
  126. package/dist/modules/sandbox/sandbox-fs.js +143 -0
  127. package/dist/modules/sandbox/sandbox-fs.js.map +1 -0
  128. package/dist/modules/sandbox/sandbox-runtime.d.ts +78 -0
  129. package/dist/modules/sandbox/sandbox-runtime.js +282 -0
  130. package/dist/modules/sandbox/sandbox-runtime.js.map +1 -0
  131. package/dist/modules/sandbox/sandbox.d.ts +54 -0
  132. package/dist/modules/sandbox/sandbox.js +179 -0
  133. package/dist/modules/sandbox/sandbox.js.map +1 -0
  134. package/dist/modules/security/index.d.ts +5 -0
  135. package/dist/modules/security/index.js +6 -0
  136. package/dist/modules/security/index.js.map +1 -0
  137. package/dist/modules/security/pii.d.ts +70 -0
  138. package/dist/modules/security/pii.js +276 -0
  139. package/dist/modules/security/pii.js.map +1 -0
  140. package/dist/modules/security/policy-gate.d.ts +42 -0
  141. package/dist/modules/security/policy-gate.js +172 -0
  142. package/dist/modules/security/policy-gate.js.map +1 -0
  143. package/dist/modules/security/retention.d.ts +68 -0
  144. package/dist/modules/security/retention.js +218 -0
  145. package/dist/modules/security/retention.js.map +1 -0
  146. package/dist/modules/security/secrets.d.ts +99 -0
  147. package/dist/modules/security/secrets.js +371 -0
  148. package/dist/modules/security/secrets.js.map +1 -0
  149. package/dist/modules/security/tls.d.ts +87 -0
  150. package/dist/modules/security/tls.js +154 -0
  151. package/dist/modules/security/tls.js.map +1 -0
  152. package/dist/modules/storage/database.d.ts +6 -0
  153. package/dist/modules/storage/database.js +16 -0
  154. package/dist/modules/storage/database.js.map +1 -0
  155. package/dist/modules/storage/index.d.ts +4 -0
  156. package/dist/modules/storage/index.js +5 -0
  157. package/dist/modules/storage/index.js.map +1 -0
  158. package/dist/modules/storage/memory-prune.d.ts +18 -0
  159. package/dist/modules/storage/memory-prune.js +48 -0
  160. package/dist/modules/storage/memory-prune.js.map +1 -0
  161. package/dist/modules/storage/migrations.d.ts +69 -0
  162. package/dist/modules/storage/migrations.js +394 -0
  163. package/dist/modules/storage/migrations.js.map +1 -0
  164. package/dist/modules/storage/storage.d.ts +341 -0
  165. package/dist/modules/storage/storage.js +1004 -0
  166. package/dist/modules/storage/storage.js.map +1 -0
  167. package/dist/otel.d.ts +1 -39
  168. package/dist/otel.js +1 -92
  169. package/dist/otel.js.map +1 -1
  170. package/dist/outbound-http.d.ts +1 -32
  171. package/dist/outbound-http.js +1 -87
  172. package/dist/outbound-http.js.map +1 -1
  173. package/dist/pii.d.ts +1 -70
  174. package/dist/pii.js +1 -275
  175. package/dist/pii.js.map +1 -1
  176. package/dist/policy-gate.d.ts +1 -42
  177. package/dist/policy-gate.js +1 -171
  178. package/dist/policy-gate.js.map +1 -1
  179. package/dist/resilience.d.ts +1 -84
  180. package/dist/resilience.js +1 -216
  181. package/dist/resilience.js.map +1 -1
  182. package/dist/retention.d.ts +1 -68
  183. package/dist/retention.js +1 -217
  184. package/dist/retention.js.map +1 -1
  185. package/dist/sandbox-fs.d.ts +1 -28
  186. package/dist/sandbox-fs.js +1 -142
  187. package/dist/sandbox-fs.js.map +1 -1
  188. package/dist/sandbox-runtime.d.ts +1 -78
  189. package/dist/sandbox-runtime.js +1 -281
  190. package/dist/sandbox-runtime.js.map +1 -1
  191. package/dist/sandbox.d.ts +1 -54
  192. package/dist/sandbox.js +1 -178
  193. package/dist/sandbox.js.map +1 -1
  194. package/dist/secrets.d.ts +1 -99
  195. package/dist/secrets.js +1 -370
  196. package/dist/secrets.js.map +1 -1
  197. package/dist/storage.d.ts +1 -341
  198. package/dist/storage.js +1 -1003
  199. package/dist/storage.js.map +1 -1
  200. package/dist/string.d.ts +1 -1
  201. package/dist/string.js +1 -29
  202. package/dist/string.js.map +1 -1
  203. package/dist/time.d.ts +1 -5
  204. package/dist/time.js +1 -34
  205. package/dist/time.js.map +1 -1
  206. package/dist/tls.d.ts +1 -87
  207. package/dist/tls.js +1 -153
  208. package/dist/tls.js.map +1 -1
  209. package/dist/tokenizer.d.ts +1 -54
  210. package/dist/tokenizer.js +1 -271
  211. package/dist/tokenizer.js.map +1 -1
  212. package/dist/types.d.ts +1 -27
  213. package/dist/types.js +1 -16
  214. package/dist/types.js.map +1 -1
  215. package/dist/worker-pool.d.ts +1 -52
  216. package/dist/worker-pool.js +1 -228
  217. package/dist/worker-pool.js.map +1 -1
  218. package/dist/worker-thread.d.ts +1 -21
  219. package/dist/worker-thread.js +1 -66
  220. package/dist/worker-thread.js.map +1 -1
  221. package/package.json +44 -34
@@ -0,0 +1,322 @@
1
+ /**
2
+ * [AUDIT] Structured Audit Log Service
3
+ *
4
+ * Records all critical operations in structured JSON format to SQLite.
5
+ * Queryable, filterable, and traceable.
6
+ *
7
+ * [KVKK/GDPR] GDPR and KVKK Art. 4, 5, 11, 12 compliant:
8
+ * - Sensitive data automatically masked (PII masking)
9
+ * - Data retention limited (TTL)
10
+ * - Data subject rights supported (erasure, query)
11
+ *
12
+ * Usage:
13
+ * Audit.log("user.create", "SUCCESS", { userId: "usr_123" });
14
+ * Audit.query({ action: "user.create", status: "FAILED" });
15
+ */
16
+ import { AUDIT_CHAIN_GENESIS, buildStructuredAuditChainPayload, chainDigest, readChainAnchor, writeChainAnchor, clearChainAnchor, verifyHashChain, } from "./audit-chain.js";
17
+ import { maskObject, maskText } from "../security/pii.js";
18
+ import { databaseHolder } from "../storage/database.js";
19
+ import { logger } from "./logger.js";
20
+ export class Audit {
21
+ static TABLE = "audit_log";
22
+ /** Out-of-DB anchor file name for the structured audit chain. */
23
+ static ANCHOR_NAME = "structured";
24
+ /** [KVKK] Default data retention period: 30 days */
25
+ static DEFAULT_RETENTION_DAYS = (() => {
26
+ const parsed = parseInt(process.env.ATABEY_DATA_RETENTION_DAYS || "30", 10);
27
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 30;
28
+ })();
29
+ /** [KVKK] Maximum retention for sensitive categories: 90 days */
30
+ static MAX_RETENTION_DAYS = 90;
31
+ static initialize() {
32
+ const db = databaseHolder.getDB();
33
+ db.exec(`
34
+ CREATE TABLE IF NOT EXISTS ${this.TABLE} (
35
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
36
+ timestamp TEXT NOT NULL,
37
+ action TEXT NOT NULL,
38
+ status TEXT NOT NULL,
39
+ agent TEXT NOT NULL,
40
+ traceId TEXT,
41
+ details TEXT,
42
+ errorMessage TEXT,
43
+ durationMs INTEGER,
44
+ dataCategory TEXT DEFAULT 'OPERATIONAL',
45
+ retentionDays INTEGER DEFAULT ${this.DEFAULT_RETENTION_DAYS},
46
+ prev_hash TEXT,
47
+ hash TEXT
48
+ )
49
+ `);
50
+ // Migrate older DBs
51
+ try {
52
+ const cols = db.prepare(`PRAGMA table_info(${this.TABLE})`).all().map((c) => c.name);
53
+ if (!cols.includes("prev_hash"))
54
+ db.exec(`ALTER TABLE ${this.TABLE} ADD COLUMN prev_hash TEXT`);
55
+ if (!cols.includes("hash"))
56
+ db.exec(`ALTER TABLE ${this.TABLE} ADD COLUMN hash TEXT`);
57
+ }
58
+ catch {
59
+ /* ignore */
60
+ }
61
+ // Indexes for performance
62
+ db.exec(`
63
+ CREATE INDEX IF NOT EXISTS idx_audit_action ON ${this.TABLE}(action);
64
+ CREATE INDEX IF NOT EXISTS idx_audit_status ON ${this.TABLE}(status);
65
+ CREATE INDEX IF NOT EXISTS idx_audit_trace ON ${this.TABLE}(traceId);
66
+ CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON ${this.TABLE}(timestamp);
67
+ CREATE INDEX IF NOT EXISTS idx_audit_category ON ${this.TABLE}(dataCategory);
68
+ `);
69
+ }
70
+ /**
71
+ * Refresh the out-of-DB chain anchor after a legitimate deletion
72
+ * (retention / right-to-erasure). Without this, legitimate deletions would
73
+ * be indistinguishable from tampering.
74
+ */
75
+ static refreshAnchor() {
76
+ try {
77
+ const db = databaseHolder.getDB();
78
+ const row = db.prepare(`SELECT hash FROM ${this.TABLE} WHERE hash IS NOT NULL ORDER BY id DESC LIMIT 1`).get();
79
+ const count = db.prepare(`SELECT COUNT(*) AS c FROM ${this.TABLE} WHERE hash IS NOT NULL`).get().c;
80
+ if (row?.hash && count > 0)
81
+ writeChainAnchor(this.ANCHOR_NAME, row.hash, count);
82
+ else
83
+ clearChainAnchor(this.ANCHOR_NAME);
84
+ }
85
+ catch {
86
+ /* ignore */
87
+ }
88
+ }
89
+ /**
90
+ * Logs a structured audit entry.
91
+ * [KVKK] Sensitive data is automatically masked.
92
+ */
93
+ static log(action, status, options = {}) {
94
+ const db = databaseHolder.getDB();
95
+ const requested = options.retentionDays ?? this.DEFAULT_RETENTION_DAYS;
96
+ const safeRequested = Number.isFinite(requested) && requested >= 0 ? requested : this.DEFAULT_RETENTION_DAYS;
97
+ const retentionDays = Math.min(safeRequested, this.MAX_RETENTION_DAYS);
98
+ // [KVKK] PII Masking — mask sensitive data in the details field
99
+ const maskedDetails = options.details
100
+ ? maskObject(options.details)
101
+ : undefined;
102
+ const maskedError = options.errorMessage
103
+ ? maskText(options.errorMessage)
104
+ : undefined;
105
+ const timestamp = new Date().toISOString();
106
+ const agent = options.agent || "@manager";
107
+ const detailsJson = maskedDetails ? JSON.stringify(maskedDetails) : "";
108
+ const errorMessage = maskedError || "";
109
+ const traceId = options.traceId || "";
110
+ const dataCategory = options.dataCategory || "OPERATIONAL";
111
+ // Append-only hash chain inside a transaction (Phase 1.4)
112
+ const insert = db.transaction(() => {
113
+ let prevHash = AUDIT_CHAIN_GENESIS;
114
+ try {
115
+ const last = db.prepare(`SELECT hash FROM ${this.TABLE} WHERE hash IS NOT NULL ORDER BY id DESC LIMIT 1`).get();
116
+ if (last?.hash)
117
+ prevHash = last.hash;
118
+ }
119
+ catch {
120
+ /* genesis */
121
+ }
122
+ const payload = buildStructuredAuditChainPayload({
123
+ prevHash,
124
+ agent,
125
+ action,
126
+ status,
127
+ traceId,
128
+ timestamp,
129
+ detailsJson,
130
+ errorMessage,
131
+ });
132
+ const hash = chainDigest(payload);
133
+ db.prepare(`
134
+ INSERT INTO ${this.TABLE}
135
+ (timestamp, action, status, agent, traceId, details, errorMessage, durationMs, dataCategory, retentionDays, prev_hash, hash)
136
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
137
+ `).run(timestamp, action, status, agent, options.traceId || null, detailsJson || null, errorMessage || null, options.durationMs || null, dataCategory, retentionDays, prevHash, hash);
138
+ // Refresh the out-of-DB anchor so tail truncation becomes detectable.
139
+ const count = db.prepare(`SELECT COUNT(*) AS c FROM ${this.TABLE} WHERE hash IS NOT NULL`).get().c;
140
+ writeChainAnchor(this.ANCHOR_NAME, hash, count);
141
+ });
142
+ insert();
143
+ }
144
+ /**
145
+ * Verify tamper-evident chain for structured audit_log table.
146
+ */
147
+ static verifyIntegrity() {
148
+ const db = databaseHolder.getDB();
149
+ try {
150
+ const rows = db.prepare(`SELECT id, prev_hash, hash, agent, action, status, traceId, timestamp, details, errorMessage
151
+ FROM ${this.TABLE} ORDER BY id ASC`).all();
152
+ // Skip unhashed legacy rows at the head; start chain at first hashed row
153
+ const hashed = rows.filter((r) => r.hash);
154
+ if (hashed.length === 0) {
155
+ return { valid: true, checked: 0, reason: "No hashed audit rows yet" };
156
+ }
157
+ const anchor = readChainAnchor(this.ANCHOR_NAME);
158
+ return verifyHashChain(hashed, (row, prevHash) => buildStructuredAuditChainPayload({
159
+ prevHash,
160
+ agent: row.agent,
161
+ action: row.action,
162
+ status: row.status,
163
+ traceId: row.traceId || "",
164
+ timestamp: row.timestamp,
165
+ detailsJson: row.details || "",
166
+ errorMessage: row.errorMessage || "",
167
+ }), {
168
+ expectedTip: anchor?.tip,
169
+ expectedCount: anchor?.count,
170
+ });
171
+ }
172
+ catch (err) {
173
+ return {
174
+ valid: false,
175
+ checked: 0,
176
+ reason: `Verification error: ${err.message}`,
177
+ };
178
+ }
179
+ }
180
+ /**
181
+ * Queries audit logs with filters.
182
+ */
183
+ static query(options = {}) {
184
+ const db = databaseHolder.getDB();
185
+ const conditions = [];
186
+ const params = [];
187
+ if (options.action) {
188
+ conditions.push("action = ?");
189
+ params.push(options.action);
190
+ }
191
+ if (options.status) {
192
+ conditions.push("status = ?");
193
+ params.push(options.status);
194
+ }
195
+ if (options.agent) {
196
+ conditions.push("agent = ?");
197
+ params.push(options.agent);
198
+ }
199
+ if (options.traceId) {
200
+ conditions.push("traceId = ?");
201
+ params.push(options.traceId);
202
+ }
203
+ if (options.dataCategory) {
204
+ conditions.push("dataCategory = ?");
205
+ params.push(options.dataCategory);
206
+ }
207
+ if (options.since) {
208
+ conditions.push("timestamp >= ?");
209
+ params.push(options.since);
210
+ }
211
+ if (options.until) {
212
+ conditions.push("timestamp <= ?");
213
+ params.push(options.until);
214
+ }
215
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
216
+ const limit = options.limit || 50;
217
+ const offset = options.offset || 0;
218
+ const rows = db.prepare(`SELECT * FROM ${this.TABLE} ${where} ORDER BY timestamp DESC LIMIT ? OFFSET ?`).all(...params, limit, offset);
219
+ return rows.map(row => ({
220
+ ...row,
221
+ details: row.details ? JSON.parse(row.details) : undefined,
222
+ }));
223
+ }
224
+ /**
225
+ * [KVKK Art. 11] Deletes records upon data subject request.
226
+ * Clears all records matching a given traceId or agent.
227
+ *
228
+ * @param filter Which records to delete
229
+ * @returns Number of deleted records
230
+ */
231
+ static deleteByFilter(filter) {
232
+ const db = databaseHolder.getDB();
233
+ const conditions = [];
234
+ const params = [];
235
+ if (filter.traceId) {
236
+ conditions.push("traceId = ?");
237
+ params.push(filter.traceId);
238
+ }
239
+ if (filter.agent) {
240
+ conditions.push("agent = ?");
241
+ params.push(filter.agent);
242
+ }
243
+ if (filter.action) {
244
+ conditions.push("action = ?");
245
+ params.push(filter.action);
246
+ }
247
+ if (filter.olderThanDays) {
248
+ conditions.push("timestamp < datetime('now', ? || ' days')");
249
+ params.push(`-${filter.olderThanDays}`);
250
+ }
251
+ if (conditions.length === 0)
252
+ return 0;
253
+ const result = db.prepare(`DELETE FROM ${this.TABLE} WHERE ${conditions.join(" AND ")}`).run(...params);
254
+ if (result.changes > 0)
255
+ this.refreshAnchor();
256
+ return result.changes;
257
+ }
258
+ /**
259
+ * [KVKK/GDPR] Cleans expired records.
260
+ * Operates based on each audit record's retentionDays field.
261
+ * Can be auto-triggered by cron job or each Audit.log() call.
262
+ *
263
+ * @returns Number of cleaned records
264
+ */
265
+ static cleanExpired() {
266
+ const db = databaseHolder.getDB();
267
+ const result = db.prepare(`
268
+ DELETE FROM ${this.TABLE}
269
+ WHERE retentionDays IS NOT NULL
270
+ AND strftime('%Y-%m-%d %H:%M:%S', timestamp) < datetime('now', '-' || retentionDays || ' days')
271
+ `).run();
272
+ if (result.changes > 0) {
273
+ this.refreshAnchor();
274
+ logger.info(`[AUDIT] Expired records cleaned: ${result.changes}`);
275
+ }
276
+ return result.changes;
277
+ }
278
+ /**
279
+ * Returns audit statistics.
280
+ */
281
+ static getStats() {
282
+ const db = databaseHolder.getDB();
283
+ this.cleanExpired();
284
+ const total = db.prepare(`SELECT COUNT(*) as count FROM ${this.TABLE}`).get().count;
285
+ const byStatusRows = db.prepare(`SELECT status, COUNT(*) as count FROM ${this.TABLE} GROUP BY status`).all();
286
+ const byActionRows = db.prepare(`SELECT action, COUNT(*) as count FROM ${this.TABLE} GROUP BY action ORDER BY count DESC LIMIT 10`).all();
287
+ const byCategoryRows = db.prepare(`SELECT dataCategory, COUNT(*) as count FROM ${this.TABLE} GROUP BY dataCategory`).all();
288
+ const errors = db.prepare(`SELECT * FROM ${this.TABLE} WHERE status IN ('FAILED', 'BLOCKED') ORDER BY timestamp DESC LIMIT 10`).all();
289
+ const expiredCount = db.prepare(`
290
+ SELECT COUNT(*) as count FROM ${this.TABLE}
291
+ WHERE retentionDays IS NOT NULL
292
+ AND strftime('%Y-%m-%d %H:%M:%S', timestamp) < datetime('now', '-' || retentionDays || ' days')
293
+ `).get().count;
294
+ return {
295
+ total,
296
+ byStatus: Object.fromEntries(byStatusRows.map(r => [r.status, r.count])),
297
+ byAction: Object.fromEntries(byActionRows.map(r => [r.action, r.count])),
298
+ byCategory: Object.fromEntries(byCategoryRows.map(r => [r.dataCategory, r.count])),
299
+ recentErrors: errors.map(row => ({
300
+ ...row,
301
+ details: row.details ? JSON.parse(row.details) : undefined,
302
+ })),
303
+ expiredCount,
304
+ };
305
+ }
306
+ /**
307
+ * [KVKK Art. 7] Clears all audit records.
308
+ * Used under the "Right to Erasure" provision.
309
+ * Only authorized users may call this.
310
+ */
311
+ static clearAll(confirmationCode) {
312
+ if (confirmationCode !== "KVKK-RIGHT-TO-ERASURE") {
313
+ throw new Error("[AUDIT] Invalid confirmation code for data erasure");
314
+ }
315
+ const db = databaseHolder.getDB();
316
+ const result = db.prepare(`DELETE FROM ${this.TABLE}`).run();
317
+ clearChainAnchor(this.ANCHOR_NAME);
318
+ logger.info(`[AUDIT] All records cleared (${result.changes} records). KVKK Article 7 compliance.`);
319
+ return result.changes;
320
+ }
321
+ }
322
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/modules/observability/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACH,mBAAmB,EACnB,gCAAgC,EAChC,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAElB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAwBrC,MAAM,OAAO,KAAK;IACN,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC;IACnC,iEAAiE;IACzD,MAAM,CAAC,WAAW,GAAG,YAAY,CAAC;IAC1C,oDAAoD;IAC5C,MAAM,CAAC,sBAAsB,GAAG,CAAC,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5E,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,CAAC,CAAC,EAAE,CAAC;IACL,iEAAiE;IACzD,MAAM,CAAC,kBAAkB,GAAG,EAAE,CAAC;IAEhC,MAAM,CAAC,UAAU;QACpB,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,EAAE,CAAC,IAAI,CAAC;yCACyB,IAAI,CAAC,KAAK;;;;;;;;;;;gDAWH,IAAI,CAAC,sBAAsB;;;;SAIlE,CAAC,CAAC;QACH,oBAAoB;QACpB,IAAI,CAAC;YACD,MAAM,IAAI,GAAI,EAAE,CAAC,OAAO,CAAC,qBAAqB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,EAA8B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAClH,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAAE,EAAE,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,KAAK,4BAA4B,CAAC,CAAC;YAChG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,EAAE,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,KAAK,uBAAuB,CAAC,CAAC;QAC1F,CAAC;QAAC,MAAM,CAAC;YACL,YAAY;QAChB,CAAC;QACD,0BAA0B;QAC1B,EAAE,CAAC,IAAI,CAAC;6DAC6C,IAAI,CAAC,KAAK;6DACV,IAAI,CAAC,KAAK;4DACX,IAAI,CAAC,KAAK;gEACN,IAAI,CAAC,KAAK;+DACX,IAAI,CAAC,KAAK;SAChE,CAAC,CAAC;IACP,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,aAAa;QACxB,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAClB,oBAAoB,IAAI,CAAC,KAAK,kDAAkD,CACnF,CAAC,GAAG,EAAkC,CAAC;YACxC,MAAM,KAAK,GAAI,EAAE,CAAC,OAAO,CACrB,6BAA6B,IAAI,CAAC,KAAK,yBAAyB,CACnE,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;YAC5B,IAAI,GAAG,EAAE,IAAI,IAAI,KAAK,GAAG,CAAC;gBAAE,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;;gBAC3E,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACL,YAAY;QAChB,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,GAAG,CACb,MAAc,EACd,MAAmB,EACnB,UASI,EAAE;QAEN,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACvE,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC;QAC7G,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAEvE,gEAAgE;QAChE,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO;YACjC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAA4B;YACxD,CAAC,CAAC,SAAS,CAAC;QAChB,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY;YACpC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC;YAChC,CAAC,CAAC,SAAS,CAAC;QAEhB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC;QAC1C,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,MAAM,YAAY,GAAG,WAAW,IAAI,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QACtC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,aAAa,CAAC;QAE3D,0DAA0D;QAC1D,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAC/B,IAAI,QAAQ,GAAG,mBAAmB,CAAC;YACnC,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACnB,oBAAoB,IAAI,CAAC,KAAK,kDAAkD,CACnF,CAAC,GAAG,EAAkC,CAAC;gBACxC,IAAI,IAAI,EAAE,IAAI;oBAAE,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACL,aAAa;YACjB,CAAC;YAED,MAAM,OAAO,GAAG,gCAAgC,CAAC;gBAC7C,QAAQ;gBACR,KAAK;gBACL,MAAM;gBACN,MAAM;gBACN,OAAO;gBACP,SAAS;gBACT,WAAW;gBACX,YAAY;aACf,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;YAElC,EAAE,CAAC,OAAO,CAAC;8BACO,IAAI,CAAC,KAAK;;;aAG3B,CAAC,CAAC,GAAG,CACF,SAAS,EACT,MAAM,EACN,MAAM,EACN,KAAK,EACL,OAAO,CAAC,OAAO,IAAI,IAAI,EACvB,WAAW,IAAI,IAAI,EACnB,YAAY,IAAI,IAAI,EACpB,OAAO,CAAC,UAAU,IAAI,IAAI,EAC1B,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,IAAI,CACP,CAAC;YAEF,sEAAsE;YACtE,MAAM,KAAK,GAAI,EAAE,CAAC,OAAO,CACrB,6BAA6B,IAAI,CAAC,KAAK,yBAAyB,CACnE,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;YAC5B,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QACH,MAAM,EAAE,CAAC;IACb,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,eAAe;QACzB,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACnB;wBACQ,IAAI,CAAC,KAAK,kBAAkB,CACvC,CAAC,GAAG,EAWH,CAAC;YAEH,yEAAyE;YACzE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAC;YAC3E,CAAC;YAED,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACjD,OAAO,eAAe,CAClB,MAAM,EACN,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,CACd,gCAAgC,CAAC;gBAC7B,QAAQ;gBACR,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE;gBAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,WAAW,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE;gBAC9B,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE;aACvC,CAAC,EACN;gBACI,WAAW,EAAE,MAAM,EAAE,GAAG;gBACxB,aAAa,EAAE,MAAM,EAAE,KAAK;aAC/B,CACJ,CAAC;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,OAAO;gBACH,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,CAAC;gBACV,MAAM,EAAE,uBAAwB,GAAa,CAAC,OAAO,EAAE;aAC1D,CAAC;QACN,CAAC;IACL,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,UAUhB,EAAE;QACF,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAAC,CAAC;QACnF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAAC,CAAC;QACnF,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QAChF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QACtF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAAC,CAAC;QACrG,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QACrF,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QAErF,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QAEnC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACnB,iBAAiB,IAAI,CAAC,KAAK,IAAI,KAAK,2CAA2C,CAClF,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,CAAmD,CAAC;QAElF,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpB,GAAG,GAAG;YACN,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;SAC7D,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;;;;;KAMC;IACM,MAAM,CAAC,cAAc,CAAC,MAK5B;QACG,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QACpF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAAC,CAAC;QACjF,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,UAAU,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;YAC7D,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAEtC,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CACrB,eAAe,IAAI,CAAC,KAAK,UAAU,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAChE,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;QAEjB,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC;YAAE,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7C,OAAO,MAAM,CAAC,OAAO,CAAC;IAC1B,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,YAAY;QACtB,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;0BACR,IAAI,CAAC,KAAK;;;SAG3B,CAAC,CAAC,GAAG,EAAE,CAAC;QACT,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,oCAAoC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,QAAQ;QAQlB,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,MAAM,KAAK,GAAI,EAAE,CAAC,OAAO,CAAC,iCAAiC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAwB,CAAC,KAAK,CAAC;QAE3G,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAC3B,yCAAyC,IAAI,CAAC,KAAK,kBAAkB,CACxE,CAAC,GAAG,EAA8C,CAAC;QAEpD,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAC3B,yCAAyC,IAAI,CAAC,KAAK,+CAA+C,CACrG,CAAC,GAAG,EAA8C,CAAC;QAEpD,MAAM,cAAc,GAAG,EAAE,CAAC,OAAO,CAC7B,+CAA+C,IAAI,CAAC,KAAK,wBAAwB,CACpF,CAAC,GAAG,EAAoD,CAAC;QAE1D,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CACrB,iBAAiB,IAAI,CAAC,KAAK,yEAAyE,CACvG,CAAC,GAAG,EAAoD,CAAC;QAE1D,MAAM,YAAY,GACd,EAAE,CAAC,OAAO,CAAC;gDACyB,IAAI,CAAC,KAAK;;;aAG7C,CAAC,CAAC,GAAG,EACT,CAAC,KAAK,CAAC;QAER,OAAO;YACH,KAAK;YACL,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACxE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACxE,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YAClF,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC7B,GAAG,GAAG;gBACN,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;aAC7D,CAAC,CAAC;YACH,YAAY;SACf,CAAC;IACN,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,QAAQ,CAAC,gBAAwB;QAC3C,IAAI,gBAAgB,KAAK,uBAAuB,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QAC7D,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,gCAAgC,MAAM,CAAC,OAAO,uCAAuC,CAAC,CAAC;QACnG,OAAO,MAAM,CAAC,OAAO,CAAC;IAC1B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./logger.js";
2
+ export * from "./otel.js";
3
+ export * from "./audit.js";
4
+ export * from "./audit-chain.js";
@@ -0,0 +1,5 @@
1
+ export * from "./logger.js";
2
+ export * from "./otel.js";
3
+ export * from "./audit.js";
4
+ export * from "./audit-chain.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/observability/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,31 @@
1
+ export declare enum LogLevel {
2
+ DEBUG = 0,
3
+ INFO = 1,
4
+ WARN = 2,
5
+ ERROR = 3,
6
+ FATAL = 4
7
+ }
8
+ export interface LoggerConfig {
9
+ minLevel: LogLevel;
10
+ enableColors: boolean;
11
+ jsonFormat: boolean;
12
+ logFile?: string;
13
+ enablePiiMasking: boolean;
14
+ piiWarning: boolean;
15
+ useStderr?: boolean;
16
+ }
17
+ export declare class EnterpriseLogger {
18
+ private config;
19
+ private static instance;
20
+ private constructor();
21
+ static getInstance(): EnterpriseLogger;
22
+ configure(config: Partial<LoggerConfig>): void;
23
+ private formatMessage;
24
+ private log;
25
+ debug(message: string, meta?: unknown): void;
26
+ info(message: string, meta?: unknown): void;
27
+ warn(message: string, meta?: unknown): void;
28
+ error(message: string, meta?: unknown): void;
29
+ fatal(message: string, meta?: unknown): void;
30
+ }
31
+ export declare const logger: EnterpriseLogger;
@@ -0,0 +1,153 @@
1
+ import chalk from "chalk";
2
+ import path from "path";
3
+ import { appendFile, ensureDir } from "../primitives/fs.js";
4
+ import { containsPII, maskObject, maskText } from "../security/pii.js";
5
+ /** JSON.stringify that tolerates circular references instead of throwing. */
6
+ function safeStringify(value) {
7
+ const seen = new WeakSet();
8
+ try {
9
+ return JSON.stringify(value, (_key, v) => {
10
+ if (typeof v === "object" && v !== null) {
11
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(v))
12
+ return `<Buffer ${v.length} bytes>`;
13
+ if (v instanceof Uint8Array)
14
+ return `<bytes ${v.length}>`;
15
+ if (seen.has(v))
16
+ return "[Circular]";
17
+ seen.add(v);
18
+ }
19
+ return v;
20
+ });
21
+ }
22
+ catch {
23
+ return "[Unserializable]";
24
+ }
25
+ }
26
+ export var LogLevel;
27
+ (function (LogLevel) {
28
+ LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
29
+ LogLevel[LogLevel["INFO"] = 1] = "INFO";
30
+ LogLevel[LogLevel["WARN"] = 2] = "WARN";
31
+ LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
32
+ LogLevel[LogLevel["FATAL"] = 4] = "FATAL";
33
+ })(LogLevel || (LogLevel = {}));
34
+ export class EnterpriseLogger {
35
+ config;
36
+ static instance;
37
+ constructor() {
38
+ const isProd = process.env.NODE_ENV === "production";
39
+ const isStdio = process.env.MCP_TRANSPORT === "stdio";
40
+ this.config = {
41
+ minLevel: isProd ? LogLevel.INFO : LogLevel.DEBUG,
42
+ enableColors: !isProd && !isStdio,
43
+ jsonFormat: isProd,
44
+ enablePiiMasking: true, // KVKK: PII masking ON by default
45
+ piiWarning: true,
46
+ useStderr: isStdio,
47
+ };
48
+ }
49
+ static getInstance() {
50
+ if (!EnterpriseLogger.instance) {
51
+ EnterpriseLogger.instance = new EnterpriseLogger();
52
+ }
53
+ return EnterpriseLogger.instance;
54
+ }
55
+ configure(config) {
56
+ this.config = { ...this.config, ...config };
57
+ if (this.config.logFile) {
58
+ try {
59
+ ensureDir(path.dirname(this.config.logFile));
60
+ }
61
+ catch (err) {
62
+ // Directly write to stderr — using console here would be circular
63
+ process.stderr.write(`[Logger] Failed to create log directory: ${err}\n`);
64
+ }
65
+ }
66
+ }
67
+ formatMessage(level, message, meta) {
68
+ const timestamp = new Date().toISOString();
69
+ const pid = process.pid;
70
+ // [KVKK] PII masking — mask sensitive data before logging
71
+ const safeMessage = this.config.enablePiiMasking ? maskText(message) : message;
72
+ const safeMeta = this.config.enablePiiMasking && meta ? maskObject(meta) : meta;
73
+ // [KVKK] Warn if PII detected in production (safe against circular meta)
74
+ if (this.config.piiWarning && (containsPII(message) || (meta !== undefined && containsPII(safeStringify(meta))))) {
75
+ // Only pollute stderr in non-JSON mode so structured streams stay clean.
76
+ if (!this.config.jsonFormat) {
77
+ process.stderr.write(`[PII WARNING] Potential PII detected in log at ${timestamp}\n`);
78
+ }
79
+ }
80
+ if (this.config.jsonFormat) {
81
+ return safeStringify({
82
+ timestamp,
83
+ level: LogLevel[level],
84
+ pid,
85
+ message: safeMessage,
86
+ meta: safeMeta,
87
+ });
88
+ }
89
+ const levelName = LogLevel[level].padEnd(5);
90
+ let coloredLevel = levelName;
91
+ if (this.config.enableColors) {
92
+ switch (level) {
93
+ case LogLevel.DEBUG:
94
+ coloredLevel = chalk.blue(levelName);
95
+ break;
96
+ case LogLevel.INFO:
97
+ coloredLevel = chalk.green(levelName);
98
+ break;
99
+ case LogLevel.WARN:
100
+ coloredLevel = chalk.yellow(levelName);
101
+ break;
102
+ case LogLevel.ERROR:
103
+ coloredLevel = chalk.red(levelName);
104
+ break;
105
+ case LogLevel.FATAL:
106
+ coloredLevel = chalk.bgRed.white.bold(levelName);
107
+ break;
108
+ }
109
+ }
110
+ const metaStr = safeMeta ? ` | Meta: ${JSON.stringify(safeMeta)}` : "";
111
+ return `[${timestamp}] [PID:${pid}] [${coloredLevel}]: ${safeMessage}${metaStr}`;
112
+ }
113
+ log(level, message, meta) {
114
+ if (level < this.config.minLevel)
115
+ return;
116
+ const formatted = this.formatMessage(level, message, meta);
117
+ // Route to stderr for ERROR/FATAL, or when useStderr / MCP stdio transport is active.
118
+ // Using process.write directly here is intentional — this IS the logger.
119
+ if (this.config.useStderr || process.env.MCP_TRANSPORT === "stdio" || level >= LogLevel.ERROR) {
120
+ process.stderr.write(formatted + "\n");
121
+ }
122
+ else {
123
+ process.stdout.write(formatted + "\n");
124
+ }
125
+ // Output to file if configured
126
+ if (this.config.logFile) {
127
+ try {
128
+ appendFile(this.config.logFile, formatted + "\n");
129
+ }
130
+ catch (err) {
131
+ // Directly write to stderr — using console here would be circular
132
+ process.stderr.write(`[Logger] Failed to write to log file: ${err}\n`);
133
+ }
134
+ }
135
+ }
136
+ debug(message, meta) {
137
+ this.log(LogLevel.DEBUG, message, meta);
138
+ }
139
+ info(message, meta) {
140
+ this.log(LogLevel.INFO, message, meta);
141
+ }
142
+ warn(message, meta) {
143
+ this.log(LogLevel.WARN, message, meta);
144
+ }
145
+ error(message, meta) {
146
+ this.log(LogLevel.ERROR, message, meta);
147
+ }
148
+ fatal(message, meta) {
149
+ this.log(LogLevel.FATAL, message, meta);
150
+ }
151
+ }
152
+ export const logger = EnterpriseLogger.getInstance();
153
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/modules/observability/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * OpenTelemetry-compatible tracing without an SDK dependency.
3
+ *
4
+ * Produces W3C Trace Context ids and OTLP-shaped span records, written as
5
+ * JSON Lines to `.atabey/telemetry/otel.jsonl` (and optionally pushed to an
6
+ * OTLP/HTTP collector via OTEL_EXPORTER_OTLP_ENDPOINT). This lets enterprise
7
+ * teams ship Atabey's tool spans to Datadog/Jaeger/Grafana/ELK without Atabey
8
+ * taking a hard dependency on the OTel SDK.
9
+ */
10
+ export interface SpanAttributes {
11
+ [key: string]: string | number | boolean | undefined;
12
+ }
13
+ export interface SpanRecord {
14
+ traceId: string;
15
+ spanId: string;
16
+ parentSpanId?: string;
17
+ name: string;
18
+ startTimeUnixNano: string;
19
+ endTimeUnixNano: string;
20
+ attributes: Record<string, string | number | boolean>;
21
+ status: "OK" | "ERROR";
22
+ }
23
+ export declare function newTraceId(): string;
24
+ export declare function newSpanId(): string;
25
+ /** W3C traceparent header for the given ids. */
26
+ export declare function formatTraceparent(traceId: string, spanId: string, sampled?: boolean): string;
27
+ /**
28
+ * Emit a span record. Best-effort: telemetry must never break tool execution.
29
+ */
30
+ export declare function emitSpan(projectRoot: string, span: {
31
+ name: string;
32
+ traceId: string;
33
+ spanId: string;
34
+ parentSpanId?: string;
35
+ startMs: number;
36
+ endMs: number;
37
+ attributes?: SpanAttributes;
38
+ status?: "OK" | "ERROR";
39
+ }): SpanRecord;