Commit Graph

23 Commits

Author SHA1 Message Date
cesnimda deed948183 feat(jobs): complete workspace draft parity
CI and Deploy / test (pull_request) Successful in 5m4s
CI and Deploy / deploy (pull_request) Has been skipped
2026-08-15 17:34:32 +02:00
cesnimda f0b9b222ff fix(career): preserve reviewed profile values
CI and Deploy / test (pull_request) Successful in 4m39s
CI and Deploy / deploy (pull_request) Has been skipped
Keep extraction heuristics out of manual save, version, and import paths so reviewed locations, URLs, dates, and languages round-trip unchanged.
2026-08-15 16:56:31 +02:00
cesnimda 5203ddea72 feat(cv): harden multi-page builder
CI and Deploy / test (pull_request) Failing after 3m0s
CI and Deploy / deploy (pull_request) Has been skipped
Wrap pathological content, paginate oversized entries, measure A4 and Letter previews correctly, unify section ordering, and gate stored-output actions on saved state.
2026-08-15 14:09:51 +02:00
cesnimda 89b9cdd92d docs(ai): record strategy queue evidence 2026-08-09 13:24:26 +02:00
cesnimda 5eb9b3cb96 feat(ai): enforce local-first routing
Keep external providers behind server consent, task, and prompt-cost gates while persisting actual provider provenance.
2026-08-09 12:30:11 +02:00
cesnimda c3f4a57195 feat/Update_Controllers_to_Allow_for_Premium_Membership 2026-08-03 09:17:28 +02:00
cesnimda 06518a7d52 fix: require verified production email
CI and Deploy / test (pull_request) Successful in 4m42s
CI and Deploy / deploy (pull_request) Has been skipped
CI and Deploy / test (push) Successful in 4m2s
CI and Deploy / deploy (push) Failing after 1m15s
Expose the existing email-verification setting through Compose and close the completed DataProtection rotation blocker.
2026-08-02 17:59:05 +02:00
cesnimda 955182b7c2 fix: close release preflight gaps
CI and Deploy / test (pull_request) Failing after 1m22s
CI and Deploy / deploy (pull_request) Has been skipped
Route public health checks to the API, backfill and synchronize job opportunities, stabilize SPA smoke tests, and document operator-only production steps.
2026-07-31 20:18:30 +02:00
cesnimda ce76046a29 feat: complete release readiness work
- consolidate API ownership and remove dead vendor code

- add Stripe billing, learning paths, and public CV hardening

- add migration, recovery, security, audit, and browser gates
2026-07-31 16:54:16 +02:00
cesnimda c08232b9d7 feat: meter AI usage
CI and Deploy / test (push) Failing after 58s
CI and Deploy / deploy (push) Has been skipped
2026-07-30 22:39:24 +02:00
cesnimda a3735299ec docs: complete application workspace phase
CI and Deploy / test (push) Failing after 1m7s
CI and Deploy / deploy (push) Has been skipped
Phase 5.6 — refinement and validation, no new features.

Audited the ownership rules mechanically across all six Phase 5 services rather
than asserting them in prose. None writes to CareerProfile or its children, none
writes CV variant content, and the two services that read the profile
(ApplicationChecklistService, ApplicationIntelligenceService) never save it. The
rules hold: JobEvent is the history source, the checklist is workflow guidance,
readiness is a projection of it, CareerProfile is the source of truth, CvVariant
is derived output, and AI only appends to AiInteraction.

Verified locally end to end: 379 backend tests in Release, 128 frontend tests
across 36 suites, TypeScript clean, frontend production build, both Docker
images, a fresh empty MariaDB 11 (42 tables, no exceptions), a restart against
the populated database (rows preserved), and the existing SQLite dev database.

The security review found one genuine gap, reported rather than silently
changed: authentication is enforced by a fallback policy gated on Auth:Require,
which defaults to false. docker-compose.yml hardcodes it true so every compose
deployment is protected, and every Phase 5 controller carries an explicit
Authorize attribute, but several pre-Phase-5 controllers do not — a deployment
that lost the flag would expose them. Adding explicit attributes changes local
development behaviour, so it is flagged for a deliberate decision instead of
applied unilaterally.

docs/phase-5-completion-report.md records the milestones, the architecture
decisions and their reasoning, the ownership audit, the verification matrix, and
four remaining risks: CI red for an environmental reason (a docs-only commit
fails identically), production behind and needing a backup before first deploy,
the authentication configuration gap, and prompt quality being unmeasured.

Phase 5 is feature-complete locally. It is not deployed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 17:17:56 +02:00
cesnimda 3d74baef78 feat(workspace): interview and follow-up workflow
CI and Deploy / test (push) Failing after 3m54s
CI and Deploy / deploy (push) Has been skipped
Phase 5.5. Completes the lifecycle after submission: prepare, communicate, chase.

Interview preparation gets a durable, user-owned store. There were already two
per-application AI stores, InterviewPrepNote and AiWorkspaceNote, but both are
caches that regenerate when their context signature changes — anything a user
typed into them would eventually be overwritten. InterviewPrepItem is the side
nothing regenerates, covering company research, technical notes, behavioural
answers, STAR examples and the user's own questions in one table, because those
categories differ only by label and adding one must not need a migration. Each
item records whether the user wrote it or accepted a suggestion, and an
IsPrepared flag makes the section double as the preparation checklist.

Generation stays in the existing AiWorkspaceService "interview" module, appended
to AiInteraction as before. A suggestion is history until the user adds it as a
prep item; opening the section generates nothing.

Follow-up reuses what exists rather than adding a tracker. The date is
JobApplication.FollowUpAt, the same field RulesEngine and the reminder hosted
service already act on, so reminders keep working with no new wiring. The task
stays an ApplicationChecklistItem in the follow-up category — the section counts
open tasks without owning them. The record is a FollowUpSet JobEvent, the same
type the rest of the app emits.

Communication is untouched: Correspondence already owns recruiter contacts,
history and notes, and the workspace already mounted it.

The timeline interpreter learned five more types — InterviewScheduled,
InterviewCompleted and OfferReceived as milestones, FollowUpCreated and
FollowUpCompleted as routine, deliberately outside the milestone spine so it
stays a summary of what actually happened. JobEvent remains the history source.

InterviewPrepItems is reconciler-owned with a no-op migration, guarded on
JobApplications, and verified on a fresh MariaDB 11: int AUTO_INCREMENT primary
key, varchar owner and title, tinyint flag, datetime(6), composite index inside
the key limit.

371 backend tests, 128 frontend tests, Release build and the production build all
pass locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 17:01:33 +02:00
cesnimda 02b38f7acb feat(workspace): application assets workflow
CI and Deploy / test (push) Failing after 1m11s
CI and Deploy / deploy (push) Has been skipped
Phase 5.4. Connects the career outputs a user already has to one job
application, without building a second copy of any of them.

The flow is strictly one-directional — CareerProfile -> CvVariant ->
application output — and nothing writes back up. No code path in this phase
touches CareerProfile or its children.

CV integration re-points rather than duplicates. GET/PUT /{id}/cv attaches one
variant to an application via CvVariant.JobApplicationId; replacing detaches the
previous variant instead of deleting it. Creating, duplicating, editing, theming,
previewing, exporting PDF and version history all stay in the existing CV
builder, which the section links into. There is no second CV system.

Tailoring composes the Phase 5.3 analysis and match into skills to highlight,
experience to prioritise, projects to emphasise, keywords to include and gaps to
address. Deterministic and advisory: it says what the user could emphasise and
the user edits the variant themselves. Nothing auto-applies.

Cover letters gain the history they were missing. JobApplication.CoverLetterText
stays the current text with its API contract unchanged; CoverLetterVersions
records what it used to be, so an AI rewrite is never destructive. Restore is
additive — the old text comes back as a new version, so what you restored from
still exists. Source and AiAction record whether the user wrote a version or
approved it from a suggestion, and an AI generation only becomes a version once
the user saves it.

Documents are untouched: the existing Attachment system already covers CV, cover
letter, certificates and portfolio files with a Purpose field, so the workspace
mounts that component rather than adding a second upload path.

CoverLetterVersions is the only new table — reconciler-owned, no-op migration,
guarded on JobApplications, and verified on a fresh MariaDB 11: int
AUTO_INCREMENT primary key, varchar(255) owner, datetime(6), composite index
inside the key limit.

360 backend tests, 115 frontend tests, type check, Release build and the
production build all pass locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:36:27 +02:00
cesnimda a7cecce13d feat(workspace): add application intelligence
CI and Deploy / test (push) Failing after 1m11s
CI and Deploy / deploy (push) Has been skipped
Phase 5.3. Three read-only reads that answer "how suitable is this job", "how
does my experience match", "what am I missing", "what happened previously".

Timeline (GET /{id}/timeline) is an interpretation layer over JobEvent, which
stays the source of historical truth. Each row gains a readable summary, a
category and a milestone flag; events group by day. Milestones are returned
unfiltered, because narrowing the detail must not hide what actually happened.

Job analysis (GET /{id}/analysis) extracts role, company, location, employment
type, seniority, salary, technologies, skills, responsibilities and keywords
from the advert, reusing the existing SkillTagger so the vocabulary matches the
job importer. It also reports what the advert does NOT say, which is usually the
more useful half.

Career matching (GET /{id}/match) feeds the master CareerProfile into the same
JobCvMatchService the CV builder uses, so one application scores identically
whichever surface asks. It returns the score, matched and missing skills, and
which experience and project entries are the evidence for each match.

All three are deterministic and own no data — no new table, no new column, and
nothing writes to the CareerProfile, a CvVariant, or the JobApplication. The AI
narrative stays where it already was, in AiWorkspaceService's job-analysis and
career-match modules, generated only when the user asks and versioned by the
append-only AiInteraction history. Opening a section costs nothing and changes
nothing.

Frontend adds Timeline, Analysis and Match sections to the workspace, sharing
one loader so loading, empty and error states are consistent. The deterministic
answer renders first, with the AI panel below it.

345 backend tests, 104 frontend tests, type check, production build all pass
locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 13:52:37 +02:00
cesnimda 3a906b881e feat(workspace): unified application checklist (Phase 5 milestone 2)
CI and Deploy / test (push) Failing after 1m8s
CI and Deploy / deploy (push) Has been skipped
Evolve the existing readiness workflow into one persisted, user-controlled
checklist rather than adding a second tracker.

ApplicationChecklistItem records only completion state and user intent. Each
default system item carries a stable SystemKey and an AutoSignal — the same
signal /readiness already computed — and re-syncs on every read: a satisfied
signal auto-completes the item, a reverted signal reopens it, and a manual tick
always wins. Users can add, reorder, dismiss and delete.

Readiness is refactored into a projection of the checklist (score = completion
percentage, completed/missing = live items by status). Its DTO shape and the
workflowSignal/reminders health view are unchanged, so no API contract breaks.

The workspace's next recommended action now comes from the first pending
checklist item in category priority order (preparation, submission, follow-up,
interview, custom), replacing the parallel ruleset — so the overview can never
recommend something already ticked off, and a user's own task can be next.

The table follows the established MariaDB-safe path: the scaffolded migration is
a no-op and the idempotent reconciler owns the DDL for both providers. Verified
on MariaDB 11 — auto_increment PK, varchar/datetime(6)/tinyint(1) columns, both
indexes inside the key limit, cascade delete, unique system key per application,
and NULL system keys not colliding for custom items.

329 backend tests, 94 frontend tests, type check, production build and both
Docker builds pass locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 11:15:46 +02:00
cesnimda e55a6e86b7 feat(workspace): Application Workspace foundation (Phase 5 milestone 1)
CI and Deploy / test (push) Failing after 1m13s
CI and Deploy / deploy (push) Has been skipped
Every JobApplication gets a dedicated workspace at /applications/{id} — a
surface, not a new data store. It owns no data and duplicates none: CV comes
from the Phase 4 CvVariant lens, analysis/match/interview from the existing
AiWorkspacePanel, documents from Attachments, communication from
Correspondence, activity from JobEvent, stage semantics from JobPipeline. No
career data is copied and nothing here writes.

- GET /api/jobapplications/{id}/workspace: one aggregate read (role, company,
  stage, dates, attached CV variant, cover letter, documents, AI history,
  recent activity) replacing the page fanning out across endpoints
- Next recommended action: ordered rules answering "what do I do next?", the
  core product principle for this phase
- ApplicationWorkspacePage: left nav + linkable ?section=, reusing the existing
  component for each domain; later-milestone sections say so rather than faking
- Entry point from the job dialog via an optional onOpenWorkspace callback —
  the dialog must not depend on router context (it is mounted without a
  <Router> in several suites), so the caller owns navigation
- 8 backend tests (aggregate, CV variant surfacing, counts, activity ordering,
  next-step rules, tenant scoping)

Local: 314 backend, 88/88 frontend (31 suites), tsc clean, production build ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 23:57:24 +02:00
cesnimda fd9bd3f47a docs(architecture): document the AI Career Assistant (Phase 5)
CI and Deploy / test (push) Failing after 1m56s
CI and Deploy / deploy (push) Has been skipped
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
cesnimda 074c78a7ef docs(architecture): record Phase 4.5 builder polish
CI and Deploy / test (push) Failing after 2m4s
CI and Deploy / deploy (push) Has been skipped
cv-builder.md (outline-driven Content tab, DnD, rich text, preview page nav,
public-CV routing fix + deployment note), cv-theme-engine.md (rich text/ATS/
print), roadmap Phase 4.5 shipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 14:48:33 +02:00
cesnimda 17edf19f89 docs(architecture): document CV builder, theme engine, Phase 4 status
CI and Deploy / test (push) Failing after 1m53s
CI and Deploy / deploy (push) Has been skipped
cv-builder.md (variant model, rendering pipeline, API, builder workflow,
extension points, known deep-link limitation) + cv-theme-engine.md (how a
theme is data and how to add one). Roadmap Phase 4 marked foundation-shipped
with the remaining polish itemised.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 10:07:43 +02:00
cesnimda 707d8c59d2 docs(architecture): mark Phase 3 career foundation shipped
CI and Deploy / test (push) Failing after 1m51s
CI and Deploy / deploy (push) Has been skipped
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 01:03:40 +02:00
cesnimda 9c8644e9f9 docs(architecture): document career profile model
CI and Deploy / test (push) Failing after 1m54s
CI and Deploy / deploy (push) Has been skipped
Phase 3 foundation: entities, relationships, ownership, source-of-truth, and
snapshot rules for the structured career profile. Relational children
(Experience/Education/Skill/Project/Certification/Language) under CareerProfile;
long tail as JSON; blob (ProfileCvStructureJson) becomes a derived projection for
legacy read paths; lazy non-destructive backfill.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 00:25:02 +02:00
cesnimda cf8b2fa014 docs(architecture): document profile and career ownership
CI and Deploy / test (push) Failing after 1m50s
CI and Deploy / deploy (push) Has been skipped
Add section 4a to docs/architecture/current.md: request flow, data ownership,
API responsibilities, and future extension points for the /profile vs /career
separation completed in Phase 2/2.2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 00:13:06 +02:00
cesnimda b176a44627 docs: reorganize tree, restore architecture + research from archive, add Phase 0 reports
Active docs/ was stub scaffolding while the real docs sat in docs/_archive/.
Restore and correct them, and record the Phase 0 work.

- docs/architecture/current.md: verified system map (from archived SYSTEM_OVERVIEW,
  9 corrections against code).
- docs/research/competitors.md: sourced competitor analysis (from archived
  PRODUCT_RESEARCH, feature matrix corrected).
- docs/decisions/ADR-002-job-application-model.md: the Job/JobApplication split.
- docs/application-discovery-report.md, docs/implementation-roadmap.md,
  docs/phase-0-foundation-report.md, docs/career-workspace-branch-assessment.md.
- Remove 10 zero-byte placeholder files that advertised content that never existed.

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