Files
jobtrackingapp/docs/architecture/ai-career-assistant.md
T
cesnimda fd9bd3f47a
CI and Deploy / test (push) Failing after 1m56s
CI and Deploy / deploy (push) Has been skipped
docs(architecture): document the AI Career Assistant (Phase 5)
ai-career-assistant.md (modules, prompt flow, provider abstraction, append-only
history model, extension points, security). Master guide + roadmap Phase 5
updated with the shipped workspace and the open provider-selection extension.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 15:26:04 +02:00

5.3 KiB

AI Career Assistant (Phase 5)

Phase 5 (2026-07-18). The per-application AI Workspace: modules, prompt flow, provider abstraction, history model, extension points. Companion to cv-builder.md, career-profile-model.md, and MASTER_IMPLEMENTATION_GUIDE.md (AI philosophy). Verified against code + a running container.

Principle

AI assists the application workflow — it never replaces the user. Every module is suggestion only: it returns markdown the user reviews and copies. Nothing is applied automatically to the master profile, a CV variant, or the application. Every prompt carries the guardrail "preserve every factual claim — never invent employers, titles, dates, qualifications, or metrics." Job tracking stays the core product; the assistant improves the application it hangs off.

Where it lives

Each job application gains an AI Workspace tab (AiWorkspacePanel) in the job details dialog. It is the central place for all AI on that application. Pre-existing per-tab AI (candidate-fit, focus-plan, interview-prep) is untouched — the workspace is the unified, history-backed home for the Phase 5 modules.

Modules

AiWorkspaceService.Modules, all via ISummarizerService.SummarizeSectionAsync:

Module Produces
job-analysis Company/role/skills/tech/experience/education/soft-skills/responsibilities/salary/benefits/work-model/visa/language + summary + likely interview topics + confidence
career-match Match % + reasoning, strengths, weaknesses, missing skills, most-relevant experience, suggested improvements
cover-letter A tailored letter in one of 6 tones (professional, friendly, short, detailed, modern, traditional)
interview Company research, likely/behavioural/technical questions, STAR answer outlines, prep checklist
application-review Overall strength (rating), missing info, weak areas, ATS issues, grammar/clarity, formatting

Tailored CV is not re-implemented here — it is the Phase 4 CV Builder (CvVariant linked to the job application). The workspace links to it rather than duplicating it.

Prompt flow

job (JobApplication + Company) ─┐
                                ├─► AiWorkspaceService builds { instruction + guardrail, source }
master profile text ────────────┘        │
                                          ▼
                        ISummarizerService.SummarizeSectionAsync  ──►  ai-service (active provider)
                                          │
                                          ▼
                        AiInteraction (append-only history)  ──►  markdown suggestion to the UI

source = the job context (BuildJobContext) plus the user's master profile text (ApplicationUser.ProfileCvText). No profile fields are written; the text is read-only input.

History model

AiInteraction (Models/AiInteraction.cs) is append-only — one row per generation, never 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.

API (AiWorkspaceController, /api/jobapplications/{id}/ai): GET modules (+ current provider), POST generate, GET history?module=, DELETE history/{id}.

Provider abstraction

Generation goes through the existing ISummarizerService → ai-service, which routes to the active provider (AI_PROVIDER: ollama | gemini | groq) — production can offload a weak local GPU to a cloud provider. Each AiInteraction records the resolved provider for transparency, and GET …/ai/modules returns the current provider so the UI can show it.

Per-request user-selectable providers (module 8's "users can choose provider") is a plumbing extension, not yet wired end-to-end: it needs (a) ai-service to accept a per-request provider override and (b) an API key configured for each selectable provider. Both are deployment/credential concerns (a live paid key per provider), so the code path is left as a documented extension point rather than shipped half-configured. The abstraction already isolates the change to one method.

Extension points

  • New module: add a key to AiWorkspaceService.Modules + a prompt builder + a switch arm. No new storage, controller, or UI wiring — the panel enumerates modules from AI_MODULES.
  • New cover-letter tone: add to CoverLetterModes + ModeGuidance.
  • Structured (JSON) results: swap a module's prompt for JSON and parse into ResultJson.meta; the UI already renders result.text as markdown and can read meta.
  • User-selectable provider: thread a provider param through ISummarizerService → ai-service; gate on the provider having a configured key (see above).

Security

Suggestion only; never overwrites user content; everything requires the user to copy it in. The ai-service stays backend-only (ai_internal network, X-Ai-Service-Token) — see current.md §16. Markdown renders React nodes (no dangerouslySetInnerHTML), so AI output has no HTML-injection path.