feat: meter AI usage
CI and Deploy / test (push) Failing after 58s
CI and Deploy / deploy (push) Has been skipped

This commit is contained in:
cesnimda
2026-07-30 22:39:24 +02:00
parent f8466c2ebc
commit c08232b9d7
15 changed files with 2482 additions and 11 deletions
+5 -2
View File
@@ -55,10 +55,13 @@ master profile text ────────────┘ │
overwritten. This is deliberately distinct from `AiWorkspaceNote` (a one-row-per-type *cache* for
candidate-fit/focus-plan). History gives the user restore/reuse (re-surface a past result), compare
(view two side by side), copy, and delete. `ResultJson` is `{ text, meta? }`; `Provider` records which
provider produced it. Tenant-scoped (owner query filter), cascades with the application.
provider produced it. Each row also stores input/output character counts and a conservative estimated
token count (characters ÷ 4); the estimate is provider-neutral because the sidecar currently returns
text rather than provider billing metadata. Tenant-scoped (owner query filter), cascades with the application.
API (`AiWorkspaceController`, `/api/jobapplications/{id}/ai`): `GET modules` (+ current provider),
`POST generate`, `GET history?module=`, `DELETE history/{id}`.
`POST generate`, `GET history?module=`, `DELETE history/{id}`. `GET /api/ai/usage` returns current-month
and all-time totals; the workspace displays the monthly calls and estimated tokens.
## Provider abstraction
+1 -1
View File
@@ -391,7 +391,7 @@ No structured sink (Seq/OTLP), no in-app log rotation, no ProblemDetails standar
|---|---|---|
| Medium | DataProtection keys recoverable from git history (`519c32e`, `955cae6`) | **Open — rotation required, needs an operator** |
| Medium | **CORS: `Cors:Origins="*"` triggers `SetIsOriginAllowed(_ => true)` + `AllowCredentials()`** (`Program.cs:96-102`) — reflected-origin with cookies = session theft from any site. Not currently active (compose never sets `Cors__Origins`, so it defaults to `localhost:3000`), but it is one config value away. | **Open — landmine** |
| Medium | No AI cost ceiling (no quota, no metering, unthrottled) | Open |
| Medium | AI cost ceiling | Metering shipped in Phase 5; enforce quotas before open registration (Phase 7). |
| Low | No CAPTCHA (rate limiting only) | Open — blocks public signup |
| Low | Unbounded storage: attachments, CV artifacts, extraction runs, base64 avatars | Open |
| Low | Backup / DPAPI is Windows-oriented — verify behaviour on Linux prod | Unverified |