@inso_web/els-mcp 0.1.0 → 0.2.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 (121) hide show
  1. package/README.md +42 -37
  2. package/dist/audit/prisma.d.ts +9 -2
  3. package/dist/audit/prisma.d.ts.map +1 -1
  4. package/dist/audit/prisma.js +2 -2
  5. package/dist/audit/prisma.js.map +1 -1
  6. package/dist/audit/service.d.ts.map +1 -1
  7. package/dist/audit/service.js +4 -3
  8. package/dist/audit/service.js.map +1 -1
  9. package/dist/audit/verify.d.ts +55 -0
  10. package/dist/audit/verify.d.ts.map +1 -0
  11. package/dist/audit/verify.js +131 -0
  12. package/dist/audit/verify.js.map +1 -0
  13. package/dist/billing/limits.d.ts +14 -3
  14. package/dist/billing/limits.d.ts.map +1 -1
  15. package/dist/billing/limits.js +30 -3
  16. package/dist/billing/limits.js.map +1 -1
  17. package/dist/billing/tracker.d.ts +11 -3
  18. package/dist/billing/tracker.d.ts.map +1 -1
  19. package/dist/billing/tracker.js +38 -4
  20. package/dist/billing/tracker.js.map +1 -1
  21. package/dist/cache/types.d.ts +8 -8
  22. package/dist/cache/types.d.ts.map +1 -1
  23. package/dist/cache/types.js +7 -7
  24. package/dist/cache/wrapper.js +1 -1
  25. package/dist/cli.js +52 -7
  26. package/dist/cli.js.map +1 -1
  27. package/dist/config.d.ts +19 -4
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +26 -12
  30. package/dist/config.js.map +1 -1
  31. package/dist/elsClient.js +6 -6
  32. package/dist/elsClient.js.map +1 -1
  33. package/dist/http/app.d.ts +5 -2
  34. package/dist/http/app.d.ts.map +1 -1
  35. package/dist/http/app.js +12 -7
  36. package/dist/http/app.js.map +1 -1
  37. package/dist/http/lkResolver.d.ts +60 -0
  38. package/dist/http/lkResolver.d.ts.map +1 -0
  39. package/dist/http/lkResolver.js +194 -0
  40. package/dist/http/lkResolver.js.map +1 -0
  41. package/dist/http/middleware/auth.d.ts +3 -0
  42. package/dist/http/middleware/auth.d.ts.map +1 -1
  43. package/dist/http/middleware/auth.js +28 -12
  44. package/dist/http/middleware/auth.js.map +1 -1
  45. package/dist/http/middleware/dcrRateLimit.d.ts +2 -2
  46. package/dist/http/middleware/errorHandler.d.ts +1 -1
  47. package/dist/http/middleware/errorHandler.js +1 -1
  48. package/dist/http/middleware/originGuard.d.ts +1 -1
  49. package/dist/http/middleware/requestId.d.ts +1 -1
  50. package/dist/http/routes/health.js +1 -1
  51. package/dist/http/routes/health.js.map +1 -1
  52. package/dist/http/routes/metrics.d.ts +2 -4
  53. package/dist/http/routes/metrics.d.ts.map +1 -1
  54. package/dist/http/routes/metrics.js +2 -4
  55. package/dist/http/routes/metrics.js.map +1 -1
  56. package/dist/http/types.d.ts +9 -3
  57. package/dist/http/types.d.ts.map +1 -1
  58. package/dist/instrumentation.d.ts +3 -3
  59. package/dist/instrumentation.js +3 -3
  60. package/dist/lib/cursor.d.ts +1 -1
  61. package/dist/lib/cursor.js +3 -3
  62. package/dist/lib/errors.d.ts +5 -3
  63. package/dist/lib/errors.d.ts.map +1 -1
  64. package/dist/lib/errors.js.map +1 -1
  65. package/dist/middleware/withMiddleware.d.ts +11 -9
  66. package/dist/middleware/withMiddleware.d.ts.map +1 -1
  67. package/dist/middleware/withMiddleware.js +64 -11
  68. package/dist/middleware/withMiddleware.js.map +1 -1
  69. package/dist/observability/health.d.ts +2 -2
  70. package/dist/observability/logger.d.ts +1 -1
  71. package/dist/observability/tracing.d.ts +2 -2
  72. package/dist/prompts/index.d.ts +2 -2
  73. package/dist/prompts/index.js +1 -1
  74. package/dist/redaction/promptInjection.d.ts +2 -5
  75. package/dist/redaction/promptInjection.d.ts.map +1 -1
  76. package/dist/redaction/promptInjection.js +3 -6
  77. package/dist/redaction/promptInjection.js.map +1 -1
  78. package/dist/redaction/userAgent.d.ts +1 -1
  79. package/dist/redaction/userAgent.js +1 -1
  80. package/dist/resources/index.d.ts +3 -3
  81. package/dist/resources/index.js +4 -4
  82. package/dist/resources/index.js.map +1 -1
  83. package/dist/server.d.ts +5 -5
  84. package/dist/server.d.ts.map +1 -1
  85. package/dist/server.js +1 -1
  86. package/dist/server.js.map +1 -1
  87. package/dist/tools/errorHeatmap.js +1 -1
  88. package/dist/tools/errorHeatmap.js.map +1 -1
  89. package/dist/tools/errorStatsBreakdown.d.ts +5 -4
  90. package/dist/tools/errorStatsBreakdown.d.ts.map +1 -1
  91. package/dist/tools/errorStatsBreakdown.js +7 -6
  92. package/dist/tools/errorStatsBreakdown.js.map +1 -1
  93. package/dist/tools/errorsInSession.d.ts +1 -1
  94. package/dist/tools/errorsInSession.js +1 -1
  95. package/dist/tools/explainError.d.ts +5 -5
  96. package/dist/tools/explainError.js +9 -9
  97. package/dist/tools/explainError.js.map +1 -1
  98. package/dist/tools/groupedErrors.d.ts +2 -2
  99. package/dist/tools/groupedErrors.js +2 -2
  100. package/dist/tools/impactAnalysis.d.ts +1 -1
  101. package/dist/tools/impactAnalysis.js +1 -1
  102. package/dist/tools/index.d.ts +5 -5
  103. package/dist/tools/index.d.ts.map +1 -1
  104. package/dist/tools/index.js +4 -4
  105. package/dist/tools/index.js.map +1 -1
  106. package/dist/tools/listApps.d.ts +4 -4
  107. package/dist/tools/listApps.js +4 -4
  108. package/dist/tools/searchLogs.js +2 -2
  109. package/dist/transports/http-server.d.ts +2 -1
  110. package/dist/transports/http-server.d.ts.map +1 -1
  111. package/dist/transports/http-server.js +42 -2
  112. package/dist/transports/http-server.js.map +1 -1
  113. package/dist/transports/http.d.ts +8 -4
  114. package/dist/transports/http.d.ts.map +1 -1
  115. package/dist/transports/http.js +13 -9
  116. package/dist/transports/http.js.map +1 -1
  117. package/dist/transports/stdio.d.ts +1 -1
  118. package/dist/transports/stdio.js +1 -1
  119. package/dist/types.d.ts +8 -9
  120. package/dist/types.d.ts.map +1 -1
  121. package/package.json +2 -1
package/README.md CHANGED
@@ -1,13 +1,12 @@
1
- # @inso/els-mcp
1
+ # @inso_web/els-mcp
2
2
 
3
- MCP-сервер поверх INSO Error Logs Service (ELS). Даёт LLM-агентам (Claude
4
- Desktop, mcp-inspector, любой MCP-клиент) read-only доступ к логам ошибок и
5
- аналитическим эндпоинтам — для триажа, поиска паттернов и анализа трендов.
3
+ MCP-сервер поверх INSO Error Logs Service (ELS). Даёт LLM-агентам
4
+ (Claude Desktop, mcp-inspector, любой MCP-клиент) read-only доступ к логам
5
+ ошибок и аналитическим эндпоинтам — для триажа, поиска паттернов и анализа
6
+ трендов.
6
7
 
7
- > **Phase 1+3 готовы.** stdio + Streamable HTTP transport, 8 базовых read-only
8
- > tools, OIDC через INSO Auth, RFC 9728 resource metadata.
9
- > Полный roadmap (resources, prompts, cache, AI) —
10
- > в `/todo/error-logs-service/mcp/` (см. `12-migration-rollout.md`).
8
+ > stdio + Streamable HTTP transport, 18 read-only tools, OIDC через INSO Auth,
9
+ > RFC 9728 resource metadata, PII redaction, audit log, tier-based quotas.
11
10
 
12
11
  ## TL;DR
13
12
 
@@ -81,9 +80,9 @@ npm run typecheck
81
80
  }
82
81
  ```
83
82
 
84
- Перезапустите Claude Desktop — в списке инструментов появятся 8 ELS-tools.
83
+ Перезапустите Claude Desktop — в списке инструментов появятся ELS-tools.
85
84
 
86
- ## Доступные tools (Phase 1)
85
+ ## Доступные tools
87
86
 
88
87
  | Tool | ELS endpoint | Описание |
89
88
  |------|---|---|
@@ -115,9 +114,9 @@ Listing-tools используют opaque `cursor` (НЕ `page`/`offset`). Вн
115
114
  зашит `filtersHash` — если клиент сменил фильтры между страницами,
116
115
  сервер вернёт `INVALID_ARGS` с предложением начать с первой страницы.
117
116
 
118
- > Phase 1 cursor transitional: внутри хранятся `page`/`limit` (ELS пока
119
- > offset-based). Phase 4 переключится на настоящий seek `(receivedAt, id)`
120
- > формат cursor останется тот же.
117
+ > Cursortransitional wrapper: внутри хранятся `page`/`limit` (ELS пока
118
+ > offset-based). При переходе ELS на настоящий seek `(receivedAt, id)` формат
119
+ > cursor останется тот же.
121
120
 
122
121
  ## Error shape
123
122
 
@@ -144,7 +143,7 @@ Listing-tools используют opaque `cursor` (НЕ `page`/`offset`). Вн
144
143
  | `MCP_DISABLE_TOOLS` | — | CSV с именами tools для отключения. |
145
144
  | `MCP_UPSTREAM_TIMEOUT_MS` | `30000` | Таймаут одного ELS-запроса. |
146
145
 
147
- ## HTTP transport (Phase 3)
146
+ ## HTTP transport
148
147
 
149
148
  В дополнение к stdio сервер поддерживает Streamable HTTP transport через
150
149
  `MCP_TRANSPORT=http`. Используется для hosted endpoint'а
@@ -222,12 +221,14 @@ resource_metadata="https://mcp.insoweb.ru/els/.well-known/oauth-protected-resour
222
221
  ### Sessions
223
222
 
224
223
  `Mcp-Session-Id` header возвращается на первый `initialize`-запрос и должен
225
- передаваться во все последующие. TTL — 30 мин idle. В Phase 3 хранение
226
- in-memory (Map); Phase 4 переедет в Redis.
224
+ передаваться во все последующие. TTL — 30 мин idle. Хранение in-memory (Map),
225
+ будет переведено в Redis в следующих релизах.
227
226
 
228
- > **Phase 3 workaround:** OIDC `sub → appSlug` resolver пока не подключён к
229
- > LK API все OIDC-юзеры мапятся на один app через `MCP_OIDC_DEMO_APP_SLUG`.
230
- > TODO: реализовать настоящий resolver в Phase 4.
227
+ > **OIDC sub → appSlug resolver.** При наличии LK API эндпоинта
228
+ > `GET /api/internal/users/{sub}/apps` сервис резолвит доступные пользователю
229
+ > apps и кэширует результат в Redis 5 минут. Если эндпоинт недоступен —
230
+ > graceful fallback на `MCP_OIDC_DEMO_APP_SLUG`. Если у пользователя несколько
231
+ > apps, tool принимает optional `appSlug` параметр; иначе берётся первый.
231
232
 
232
233
  ### ENV-переменные транспорта
233
234
 
@@ -239,10 +240,10 @@ in-memory (Map); Phase 4 переедет в Redis.
239
240
  | `MCP_OIDC_ISSUER` | `https://auth.insoweb.ru` | OIDC issuer |
240
241
  | `MCP_OIDC_JWKS_URL` | derived | JWKS endpoint |
241
242
  | `MCP_OIDC_AUDIENCE` | `els-mcp` | Expected `aud` claim |
242
- | `MCP_OIDC_DEMO_APP_SLUG` | — | Phase 3 workaround для всех OIDC-юзеров |
243
+ | `MCP_OIDC_DEMO_APP_SLUG` | — | Fallback appSlug при недоступности LK resolver |
243
244
  | `MCP_CORS_ORIGINS` | `https://claude.ai,https://chat.openai.com` | CSV allowed origins (в dev добавляется localhost) |
244
245
 
245
- ## Security: PII redaction (Phase 5)
246
+ ## Security: PII redaction
246
247
 
247
248
  По умолчанию все ответы tools проходят через redaction pipeline до отдачи
248
249
  LLM. Применяемые правила:
@@ -276,7 +277,7 @@ instructions`, `system:`, `jailbreak`, …) в `_meta.suspiciousContentBlocked
276
277
  | `MCP_REDACTION_ENABLED` | `true` | Включена ли редакция целиком |
277
278
  | `MCP_REDACTION_FIELDS` | — | CSV whitelist полей (пусто → редактим все) |
278
279
 
279
- ## Billing / quotas (Phase 5)
280
+ ## Billing / quotas
280
281
 
281
282
  Tier-matrix (см. также
282
283
  `todo/error-logs-service/mcp/08-billing-integration.md` §1):
@@ -328,7 +329,7 @@ npm run prisma:generate
328
329
  psql $MCP_DATABASE_URL -f prisma/migrations/init/migration.sql
329
330
  ```
330
331
 
331
- ## Cache & Observability (Phase 4)
332
+ ## Cache & Observability
332
333
 
333
334
  ### Redis cache
334
335
 
@@ -452,10 +453,9 @@ Auto-instrumentation: HTTP, undici (ELS calls), ioredis, Express.
452
453
  - `GET /els/healthz` — liveness (всегда 200 если процесс жив).
453
454
  - `GET /els/readyz` — readiness: проверяет Redis ping + ELS upstream
454
455
  reachability. Возвращает 503 если хотя бы одна зависимость не отвечает.
455
- Готовые handler'ы — `src/http/routes/metrics.ts` (подключаются
456
- Phase 3 transport-роутером).
456
+ Готовые handler'ы — `src/http/routes/metrics.ts`.
457
457
 
458
- ### ENV-переменные (Phase 4)
458
+ ### ENV-переменные (cache & observability)
459
459
 
460
460
  | ENV | Default | Описание |
461
461
  |---|---|---|
@@ -466,17 +466,22 @@ Auto-instrumentation: HTTP, undici (ELS calls), ioredis, Express.
466
466
  | `OTEL_EXPORTER_OTLP_ENDPOINT` | — | OTLP traces; если не задан → no-op |
467
467
  | `MCP_LOG_PRETTY` | `true` в dev | Pretty-print pino |
468
468
 
469
- ## Что дальше (roadmap)
470
-
471
- Полная дорожная карта `/todo/error-logs-service/mcp/12-migration-rollout.md`:
472
-
473
- - **Phase 2** оставшиеся 10 tools + Resources (5 URI) + Prompts (4 templates) ✓
474
- - **Phase 3** — Streamable HTTP transport + OIDC через INSO Auth ✓
475
- - **Phase 4** Redis cache + observability (Prometheus, OTel) + LK resolver для OIDC sub ✓
476
- - **Phase 5** PII redaction + audit log + billing tracking ✓
477
- - **Phase 6** Security hardening (deny-list, STRIDE), Mistral `explain_error`
478
- - **Phase 7** Packaging (npm, Docker, Helm)
469
+ ## Limitations / TODO
470
+
471
+ - **DCR (Dynamic Client Registration).** Rate-limit middleware готов
472
+ (`src/http/middleware/dcrRateLimit.ts`), но `/oauth/register` endpoint
473
+ планируется в v2. Сейчас используется OIDC discovery без runtime
474
+ регистрации клиентов.
475
+ - **Mistral AI summary в `explain_error`.** Сейчас tool возвращает контекст
476
+ ошибки без AI-обёртки (`aiAvailable=false`); LLM-клиент сам синтезирует
477
+ объяснение из переданных данных. Планируется в следующих релизах.
478
+ - **OIDC sub apps resolver через LK API.** Эндпоинт
479
+ `GET /api/internal/users/{sub}/apps` ожидается на LK backend; до его
480
+ появления используется fallback на `MCP_OIDC_DEMO_APP_SLUG`.
481
+ - **Tier resolver через LK API.** Эндпоинт
482
+ `GET /api/internal/apps/{appSlug}/billing/tier` ожидается на LK backend;
483
+ до его появления используется `MCP_DEFAULT_TIER`.
479
484
 
480
485
  ## License
481
486
 
482
- Internal INSO project. Not for public distribution.
487
+ MIT
@@ -5,8 +5,8 @@
5
5
  * - Импорт `@prisma/client` (path: ../../node_modules/.prisma/mcp) делается
6
6
  * лениво и в try/catch — если пакет не сгенерирован, audit/billing
7
7
  * модули переходят в no-op режим.
8
- * - В Phase 5 мы НЕ требуем live Postgres для тестов / dev — все
9
- * `prisma.*`-операции в тестах подменяются через `vi.mock`.
8
+ * - Не требуем live Postgres для тестов / dev — все `prisma.*`-операции
9
+ * в тестах подменяются через `vi.mock`.
10
10
  *
11
11
  * Контракт:
12
12
  * - `getPrisma()` возвращает либо живой client, либо null (если MCP_DATABASE_URL
@@ -29,6 +29,13 @@ export interface McpPrismaClient {
29
29
  }): Promise<{
30
30
  rowHash: string;
31
31
  } | null>;
32
+ findMany(args: {
33
+ where?: Record<string, unknown>;
34
+ orderBy?: Record<string, 'asc' | 'desc'>;
35
+ select?: Record<string, boolean>;
36
+ take?: number;
37
+ skip?: number;
38
+ }): Promise<Array<Record<string, unknown>>>;
32
39
  create(args: {
33
40
  data: Record<string, unknown>;
34
41
  }): Promise<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/audit/prisma.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrE,WAAW,EAAE;QACX,SAAS,CAAC,IAAI,EAAE;YACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;YACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAClC,GAAG,OAAO,CAAC;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KACnE,CAAC;IACF,aAAa,EAAE;QACb,MAAM,CAAC,IAAI,EAAE;YACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACjC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACrB,SAAS,CAAC,IAAI,EAAE;YACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/B,IAAI,EAAE;gBAAE,KAAK,EAAE,IAAI,CAAA;aAAE,CAAC;SACvB,GAAG,OAAO,CAAC;YAAE,IAAI,EAAE;gBAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;aAAE,CAAA;SAAE,CAAC,CAAC;KACjD,CAAC;CACH;AAKD,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAoC7F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI,CAGtE;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C"}
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/audit/prisma.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrE,WAAW,EAAE;QACX,SAAS,CAAC,IAAI,EAAE;YACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;YACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAClC,GAAG,OAAO,CAAC;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC,CAAC;QACxC,QAAQ,CAAC,IAAI,EAAE;YACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;YACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACjC,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,IAAI,CAAC,EAAE,MAAM,CAAC;SACf,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KACnE,CAAC;IACF,aAAa,EAAE;QACb,MAAM,CAAC,IAAI,EAAE;YACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACjC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACrB,SAAS,CAAC,IAAI,EAAE;YACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/B,IAAI,EAAE;gBAAE,KAAK,EAAE,IAAI,CAAA;aAAE,CAAC;SACvB,GAAG,OAAO,CAAC;YAAE,IAAI,EAAE;gBAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;aAAE,CAAA;SAAE,CAAC,CAAC;KACjD,CAAC;CACH;AAKD,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAoC7F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI,CAGtE;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C"}
@@ -5,8 +5,8 @@
5
5
  * - Импорт `@prisma/client` (path: ../../node_modules/.prisma/mcp) делается
6
6
  * лениво и в try/catch — если пакет не сгенерирован, audit/billing
7
7
  * модули переходят в no-op режим.
8
- * - В Phase 5 мы НЕ требуем live Postgres для тестов / dev — все
9
- * `prisma.*`-операции в тестах подменяются через `vi.mock`.
8
+ * - Не требуем live Postgres для тестов / dev — все `prisma.*`-операции
9
+ * в тестах подменяются через `vi.mock`.
10
10
  *
11
11
  * Контракт:
12
12
  * - `getPrisma()` возвращает либо живой client, либо null (если MCP_DATABASE_URL
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/audit/prisma.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgCH,IAAI,YAAY,GAA2B,IAAI,CAAC;AAChD,IAAI,SAAS,GAAG,KAAK,CAAC;AAOtB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAA0B,EAAE;IAC1D,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC3B,SAAS,GAAG,IAAI,CAAC;IAEjB,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,uDAAuD,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,wEAAwE;QACxE,mEAAmE;QACnE,uEAAuE;QACvE,qDAAqD;QACrD,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QAC5E,MAAM,OAAO,GAAW,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAE/D,CAAC;QAET,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YACnD,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CACd,oHAAoH,CACrH,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,YAAY,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC;YAClC,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE;SAC/C,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,+BAA+B,CAAC,CAAC;QAClD,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,0DAA0D,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA8B;IAC9D,YAAY,GAAG,MAAM,CAAC;IACtB,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,YAAY,GAAG,IAAI,CAAC;IACpB,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/audit/prisma.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAuCH,IAAI,YAAY,GAA2B,IAAI,CAAC;AAChD,IAAI,SAAS,GAAG,KAAK,CAAC;AAOtB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAA0B,EAAE;IAC1D,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC3B,SAAS,GAAG,IAAI,CAAC;IAEjB,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,uDAAuD,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,wEAAwE;QACxE,mEAAmE;QACnE,uEAAuE;QACvE,qDAAqD;QACrD,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QAC5E,MAAM,OAAO,GAAW,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAE/D,CAAC;QAET,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YACnD,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CACd,oHAAoH,CACrH,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,YAAY,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC;YAClC,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE;SAC/C,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,+BAA+B,CAAC,CAAC;QAClD,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,0DAA0D,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA8B;IAC9D,YAAY,GAAG,MAAM,CAAC;IACtB,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,YAAY,GAAG,IAAI,CAAC;IACpB,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/audit/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,cAAc,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,MAAM,CAeT;AAWD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,kCAAkC;IAClC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAwE/E;AAID,wBAAgB,eAAe,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAG5E;AAED,kBAAkB;AAClB,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAEtE"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/audit/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,cAAc,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,MAAM,CAeT;AAWD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,kCAAkC;IAClC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAyE/E;AAID,wBAAgB,eAAe,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAG5E;AAED,kBAAkB;AAClB,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAEtE"}
@@ -114,12 +114,13 @@ export function createAuditService(opts = {}) {
114
114
  }
115
115
  },
116
116
  async verifyChain(appId) {
117
- // Используется в тестах. Phase 5: проходим в порядке createdAt asc и
118
- // пересчитываем hash. Для production-job можно вынести в отдельный модуль.
117
+ // Lightweight wrapper, использующийся для smoke / health-checks.
118
+ // Полноценная верификация цепочки отдельный модуль `audit/verify.ts`
119
+ // (доступен через `npm run audit:verify` или CLI команду
120
+ // `els-mcp verify-audit`).
119
121
  const client = await getClient();
120
122
  if (!client)
121
123
  return { ok: true };
122
- // Phase 5: для упрощения возвращаем ok, реальная проверка — Phase 6 cron.
123
124
  return { ok: true, ...(appId ? {} : {}) };
124
125
  },
125
126
  };
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/audit/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/audit/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Audit chain verification.
3
+ *
4
+ * Проходит по строкам `mcp_audit.audit_log` в порядке `createdAt ASC` для
5
+ * заданного `appId` (и опционального диапазона дат) и проверяет, что
6
+ * `rowHash = sha256(prevRowHash + content)` совпадает со stored значением.
7
+ *
8
+ * Используется:
9
+ * - в CLI команде `els-mcp verify-audit --app=X --from=Y --to=Z`
10
+ * (см. `src/cli.ts`)
11
+ * - в smoke / health-check скриптах
12
+ *
13
+ * Поведение при отсутствии Prisma client — корректно возвращает пустой
14
+ * результат с `prismaAvailable=false`.
15
+ */
16
+ import type { Logger } from 'pino';
17
+ import { type McpPrismaClient } from './prisma.js';
18
+ export interface VerifyChainOptions {
19
+ appId: string;
20
+ /** ISO-дата (inclusive). Если не задана — с начала. */
21
+ from?: string | Date;
22
+ /** ISO-дата (exclusive). Если не задана — до конца. */
23
+ to?: string | Date;
24
+ /** Batch size для пагинации. Default 1000. */
25
+ batchSize?: number;
26
+ databaseUrl?: string;
27
+ log?: Logger;
28
+ prismaOverride?: McpPrismaClient | null;
29
+ }
30
+ export interface VerifyBreakInfo {
31
+ /** Row id (или string-представление), на котором сломалась chain. */
32
+ id: string;
33
+ /** ISO-timestamp проблемной строки. */
34
+ createdAt: string;
35
+ /** Ожидаемый rowHash (пересчитанный). */
36
+ expectedHash: string;
37
+ /** Stored rowHash. */
38
+ actualHash: string;
39
+ }
40
+ export interface VerifyChainResult {
41
+ totalChecked: number;
42
+ prismaAvailable: boolean;
43
+ /** null если цепочка корректна. Иначе — детали первого разрыва. */
44
+ breakAt: VerifyBreakInfo | null;
45
+ }
46
+ /**
47
+ * Verifies the audit hash-chain integrity for `appId`.
48
+ * Не модифицирует БД, читает в batch'ах для крупных таблиц.
49
+ */
50
+ export declare function verifyChain(opts: VerifyChainOptions): Promise<VerifyChainResult>;
51
+ /**
52
+ * Pretty-printer для CLI: возвращает многострочный отчёт.
53
+ */
54
+ export declare function formatVerifyResult(result: VerifyChainResult): string;
55
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/audit/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;CACjC;AAiCD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiFtF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAgBpE"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Audit chain verification.
3
+ *
4
+ * Проходит по строкам `mcp_audit.audit_log` в порядке `createdAt ASC` для
5
+ * заданного `appId` (и опционального диапазона дат) и проверяет, что
6
+ * `rowHash = sha256(prevRowHash + content)` совпадает со stored значением.
7
+ *
8
+ * Используется:
9
+ * - в CLI команде `els-mcp verify-audit --app=X --from=Y --to=Z`
10
+ * (см. `src/cli.ts`)
11
+ * - в smoke / health-check скриптах
12
+ *
13
+ * Поведение при отсутствии Prisma client — корректно возвращает пустой
14
+ * результат с `prismaAvailable=false`.
15
+ */
16
+ import { getPrisma } from './prisma.js';
17
+ import { rowContent, sha256Hex } from './service.js';
18
+ function toIso(d) {
19
+ if (d === undefined)
20
+ return undefined;
21
+ return typeof d === 'string' ? d : d.toISOString();
22
+ }
23
+ function pickIso(v) {
24
+ if (v instanceof Date)
25
+ return v.toISOString();
26
+ if (typeof v === 'string')
27
+ return v;
28
+ return String(v);
29
+ }
30
+ function pickRowId(v) {
31
+ return v === undefined || v === null ? '<unknown>' : String(v);
32
+ }
33
+ /**
34
+ * Verifies the audit hash-chain integrity for `appId`.
35
+ * Не модифицирует БД, читает в batch'ах для крупных таблиц.
36
+ */
37
+ export async function verifyChain(opts) {
38
+ const batchSize = Math.max(1, opts.batchSize ?? 1000);
39
+ const fromIso = toIso(opts.from);
40
+ const toIsoStr = toIso(opts.to);
41
+ const client = opts.prismaOverride !== undefined
42
+ ? opts.prismaOverride
43
+ : await getPrisma({
44
+ ...(opts.databaseUrl ? { databaseUrl: opts.databaseUrl } : {}),
45
+ ...(opts.log ? { log: opts.log } : {}),
46
+ });
47
+ if (!client) {
48
+ return { totalChecked: 0, prismaAvailable: false, breakAt: null };
49
+ }
50
+ const where = { appId: opts.appId };
51
+ if (fromIso || toIsoStr) {
52
+ const createdAt = {};
53
+ if (fromIso)
54
+ createdAt.gte = fromIso;
55
+ if (toIsoStr)
56
+ createdAt.lt = toIsoStr;
57
+ where.createdAt = createdAt;
58
+ }
59
+ let prevHash = null;
60
+ let totalChecked = 0;
61
+ let skip = 0;
62
+ for (;;) {
63
+ const rows = (await client.mcpAuditLog.findMany({
64
+ where,
65
+ orderBy: { createdAt: 'asc' },
66
+ take: batchSize,
67
+ skip,
68
+ }));
69
+ if (rows.length === 0)
70
+ break;
71
+ for (const row of rows) {
72
+ const args = (typeof row.args === 'object' && row.args !== null
73
+ ? row.args
74
+ : {});
75
+ const createdAtIso = pickIso(row.createdAt);
76
+ const content = rowContent({
77
+ appId: row.appId,
78
+ keyId: row.keyId,
79
+ tool: row.tool,
80
+ args,
81
+ resultBytes: row.resultBytes,
82
+ latencyMs: row.latencyMs,
83
+ cacheHit: row.cacheHit === true,
84
+ statusCode: row.statusCode,
85
+ error: row.error ?? null,
86
+ createdAt: createdAtIso,
87
+ prevHash,
88
+ });
89
+ const expectedHash = sha256Hex((prevHash ?? '') + content);
90
+ if (expectedHash !== row.rowHash) {
91
+ return {
92
+ totalChecked: totalChecked + 1,
93
+ prismaAvailable: true,
94
+ breakAt: {
95
+ id: pickRowId(row.id),
96
+ createdAt: createdAtIso,
97
+ expectedHash,
98
+ actualHash: row.rowHash,
99
+ },
100
+ };
101
+ }
102
+ prevHash = row.rowHash;
103
+ totalChecked += 1;
104
+ }
105
+ if (rows.length < batchSize)
106
+ break;
107
+ skip += batchSize;
108
+ }
109
+ return { totalChecked, prismaAvailable: true, breakAt: null };
110
+ }
111
+ /**
112
+ * Pretty-printer для CLI: возвращает многострочный отчёт.
113
+ */
114
+ export function formatVerifyResult(result) {
115
+ if (!result.prismaAvailable) {
116
+ return [
117
+ 'Audit verification skipped: Prisma client not available.',
118
+ 'Ensure MCP_DATABASE_URL is set and `npm run prisma:generate` has been run.',
119
+ ].join('\n');
120
+ }
121
+ if (result.breakAt) {
122
+ return [
123
+ `Audit chain BROKEN after ${result.totalChecked} rows.`,
124
+ ` break at id=${result.breakAt.id}, createdAt=${result.breakAt.createdAt}`,
125
+ ` expected rowHash=${result.breakAt.expectedHash}`,
126
+ ` stored rowHash=${result.breakAt.actualHash}`,
127
+ ].join('\n');
128
+ }
129
+ return `Audit chain OK: ${result.totalChecked} rows verified.`;
130
+ }
131
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/audit/verify.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Tier matrix MCP — single source of truth (см. 08-billing-integration.md §1).
2
+ * Tier matrix MCP — single source of truth.
3
3
  *
4
4
  * Поля:
5
5
  * - reqPerDay — основной cut-off limit для tool-calls
6
- * - concurrentSse — SSE-сессий per app (Phase 4)
7
- * - aiPerDay — лимит на AI-explain (Phase 4)
6
+ * - concurrentSse — SSE-сессий per app
7
+ * - aiPerDay — лимит на AI-explain (отдельный counter)
8
8
  * - graceFraction — 10 % grace выше дневного лимита перед hard cut-off
9
9
  */
10
10
  export type Tier = 'FREE' | 'STANDARD' | 'PREMIUM' | 'UNLIMITED';
@@ -31,4 +31,15 @@ export interface QuotaDecision {
31
31
  export declare function secondsUntilUtcMidnight(now?: Date): number;
32
32
  /** Чистое решение: принимает текущий счётчик и tier, возвращает decision. */
33
33
  export declare function decideQuota(currentUsed: number, tier: Tier): QuotaDecision;
34
+ /**
35
+ * Чистое решение для AI-quota: принимает текущий AI-счётчик и tier.
36
+ * Используется только для tools, помеченных как AI (например, `explain_error`).
37
+ *
38
+ * Семантика отличается от `decideQuota`: AI-quota — hard cut-off без grace
39
+ * (генерация дорогая, нет смысла превышать).
40
+ */
41
+ export declare function decideAiQuota(currentUsed: number, tier: Tier): QuotaDecision;
42
+ /** Список tool-имён, считающихся AI (используют отдельную AI-квоту). */
43
+ export declare const AI_TOOL_NAMES: ReadonlySet<string>;
44
+ export declare function isAiTool(toolName: string): boolean;
34
45
  //# sourceMappingURL=limits.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/billing/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CAUhD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,yCAAyC;AACzC,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM,CAWtE;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,aAAa,CAuB1E"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/billing/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CAUhD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,yCAAyC;AACzC,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM,CAWtE;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,aAAa,CAuB1E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,aAAa,CAc5E;AAED,wEAAwE;AACxE,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAA8B,CAAC;AAE7E,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAElD"}
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Tier matrix MCP — single source of truth (см. 08-billing-integration.md §1).
2
+ * Tier matrix MCP — single source of truth.
3
3
  *
4
4
  * Поля:
5
5
  * - reqPerDay — основной cut-off limit для tool-calls
6
- * - concurrentSse — SSE-сессий per app (Phase 4)
7
- * - aiPerDay — лимит на AI-explain (Phase 4)
6
+ * - concurrentSse — SSE-сессий per app
7
+ * - aiPerDay — лимит на AI-explain (отдельный counter)
8
8
  * - graceFraction — 10 % grace выше дневного лимита перед hard cut-off
9
9
  */
10
10
  export const TIER_LIMITS = {
@@ -48,4 +48,31 @@ export function decideQuota(currentUsed, tier) {
48
48
  tier,
49
49
  };
50
50
  }
51
+ /**
52
+ * Чистое решение для AI-quota: принимает текущий AI-счётчик и tier.
53
+ * Используется только для tools, помеченных как AI (например, `explain_error`).
54
+ *
55
+ * Семантика отличается от `decideQuota`: AI-quota — hard cut-off без grace
56
+ * (генерация дорогая, нет смысла превышать).
57
+ */
58
+ export function decideAiQuota(currentUsed, tier) {
59
+ const limits = TIER_LIMITS[tier];
60
+ if (!Number.isFinite(limits.aiPerDay)) {
61
+ return { allowed: true, remaining: Number.POSITIVE_INFINITY, tier };
62
+ }
63
+ if (currentUsed < limits.aiPerDay) {
64
+ return { allowed: true, remaining: limits.aiPerDay - currentUsed, tier };
65
+ }
66
+ return {
67
+ allowed: false,
68
+ remaining: 0,
69
+ retryAfter: secondsUntilUtcMidnight(),
70
+ tier,
71
+ };
72
+ }
73
+ /** Список tool-имён, считающихся AI (используют отдельную AI-квоту). */
74
+ export const AI_TOOL_NAMES = new Set(['explain_error']);
75
+ export function isAiTool(toolName) {
76
+ return AI_TOOL_NAMES.has(toolName);
77
+ }
51
78
  //# sourceMappingURL=limits.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/billing/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,MAAM,CAAC,MAAM,WAAW,GAA6B;IACnD,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE;IAC9E,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE;IACrF,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE;IACxF,SAAS,EAAE;QACT,SAAS,EAAE,MAAM,CAAC,iBAAiB;QACnC,aAAa,EAAE,GAAG;QAClB,QAAQ,EAAE,MAAM,CAAC,iBAAiB;QAClC,aAAa,EAAE,CAAC;KACjB;CACF,CAAC;AAeF,yCAAyC;AACzC,MAAM,UAAU,uBAAuB,CAAC,MAAY,IAAI,IAAI,EAAE;IAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB,GAAG,CAAC,cAAc,EAAE,EACpB,GAAG,CAAC,WAAW,EAAE,EACjB,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,EACpB,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,CACF,CAAC;IACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,WAAmB,EAAE,IAAU;IACzD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC;IACtE,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;IACzE,IAAI,WAAW,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,WAAW,EAAE,IAAI,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,WAAW,GAAG,MAAM,EAAE,CAAC;QACzB,OAAO;YACL,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,IAAI;YACb,IAAI;SACL,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,uBAAuB,EAAE;QACrC,IAAI;KACL,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/billing/limits.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,15 @@
1
1
  /**
2
- * Phase 5 usage tracker.
2
+ * Usage tracker.
3
3
  *
4
4
  * Пишет напрямую в Postgres `mcp_billing.usage_daily` (UPSERT per app+date+tool).
5
- * В Phase 4 заменим на Redis INCR + hourly flush — интерфейс останется тем же,
6
- * так что вызывающий код не нужно будет править.
5
+ * Со временем будет заменён на Redis INCR + hourly flush — интерфейс останется
6
+ * тем же, так что вызывающий код не нужно будет править.
7
7
  *
8
8
  * Поведение:
9
9
  * - Silent fail при ошибке БД (как и audit) — usage tracking не блокирует tool-call.
10
10
  * - Fire-and-forget: caller вызывает через `void trackUsage(...)`.
11
+ * - AI-tools (см. `isAiTool` из `./limits.ts`) дополнительно учитываются в
12
+ * отдельной AI-квоте через `aiTodayUsage` + `checkAiQuota`.
11
13
  */
12
14
  import type { Logger } from 'pino';
13
15
  import { type McpPrismaClient } from '../audit/prisma.js';
@@ -32,6 +34,12 @@ export interface UsageTracker {
32
34
  */
33
35
  todayUsage(appId: string, now?: Date): Promise<number>;
34
36
  checkQuota(appId: string, tier: Tier, now?: Date): Promise<QuotaDecision>;
37
+ /**
38
+ * Возвращает текущее число AI-tool вызовов за сегодня UTC (sum по
39
+ * tools, отвечающим `isAiTool`).
40
+ */
41
+ aiTodayUsage(appId: string, now?: Date): Promise<number>;
42
+ checkAiQuota(appId: string, tier: Tier, now?: Date): Promise<QuotaDecision>;
35
43
  }
36
44
  export declare function createUsageTracker(opts?: UsageTrackerOptions): UsageTracker;
37
45
  export declare function getUsageTracker(opts?: UsageTrackerOptions): UsageTracker;
@@ -1 +1 @@
1
- {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/billing/tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAe,KAAK,aAAa,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC;AAMD,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD;;;OAGG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC3E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CA+D/E;AAID,wBAAgB,eAAe,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAG5E;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAEpE"}
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/billing/tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAwC,KAAK,aAAa,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAElG,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC;AAMD,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD;;;OAGG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC1E;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC7E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CA2F/E;AAOD,wBAAgB,eAAe,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CAG5E;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAEpE"}