feat: meter AI usage
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -146,14 +146,14 @@ Goal: polish. This is the healthiest area — grounding in the structured profil
|
||||
> `ISummarizerService`/ai-service provider abstraction and stored as **append-only history**
|
||||
> (`AiInteraction`) with reuse / compare / copy / delete. Suggestion-only throughout; nothing
|
||||
> auto-applies; `Markdown` renders React nodes (no HTML-injection surface). See
|
||||
> `docs/architecture/ai-career-assistant.md`. **Still open:** per-request user-selectable providers
|
||||
> (needs an ai-service per-request override + a configured key per provider — deployment/credential
|
||||
> work, documented as an extension point); 5.2 AI usage metering (Phase 7 blocker) remains.
|
||||
> `docs/architecture/ai-career-assistant.md`. **Phase 5 completed 2026-07-30:** provider-neutral usage
|
||||
> metering and visible monthly totals now close the Phase 7 cost-control prerequisite. Per-request
|
||||
> provider choice remains deliberately deferred by ADR-004.
|
||||
|
||||
| # | Task | Priority | Difficulty | Dependencies | Expected value |
|
||||
|---|---|---|---|---|---|
|
||||
| 5.1 | ✅ **DONE (2026-07-30)** — fixed `docs/00-ai-context.md` to match the code. **Decided 2026-07-17: do NOT build the abstraction.** | **P1** | **S** | none | The doc describes a provider interface over OpenAI/Gemini/Claude/Ollama with admin control and per-user choice. Reality: one `AI_PROVIDER` env var over Ollama/Gemini/Groq. Multi-provider cloud AI also undermines the privacy moat (see `docs/research/competitors.md` §4). Revisit only if a customer asks. `docs/architecture/current.md` §9 already records the truth. |
|
||||
| 5.2 | **AI usage metering** | **P1** | **M** | 1.5 | No quota, no tracking, no ceiling. Hard blocker for Phase 7; a cost risk today with `AI_PROVIDER=gemini`. |
|
||||
| 5.2 | ✅ **DONE (2026-07-30)** — AI usage metering | **P1** | **M** | 1.5 | No quota, no tracking, no ceiling. Hard blocker for Phase 7; a cost risk today with `AI_PROVIDER=gemini`. |
|
||||
| 5.3 | ✅ **DONE (2026-07-30)** — surfaced optional CV generation inside the add-job wizard | **P2** | **S** | 1.4 | The target workflow says "Generate CV if needed" at step 3. `POST /generate-tailored-cv-draft` exists but only post-save. |
|
||||
| 5.4 | ✅ **DONE** — keyword-gap analysis on match score | **P2** | **M** | none | `JobCvMatchService` + `/match-score` exist. Gap analysis is the specific thing people pay Jobscan $49.95/mo for. |
|
||||
| 5.5 | ✅ **DONE (2026-07-30)** — wrote ADR-004 (AI provider system) | **P2** | **S** | 5.1 | 0-byte file naming a real decision. |
|
||||
|
||||
Reference in New Issue
Block a user