Commit graph

348 commits

Author SHA1 Message Date
92bd82b4c9 fix(settings): address resume tab review issues
- add loadError ref (separated from empty-state path)
- add stable id to WorkEntry, use as v-for key
- move addExperience/removeExperience/addTag/removeTag to store actions
- strip id from save payload
- fix uploadError type handling in handleUpload
- add outer try/except to upload_resume endpoint
- gate syncFromProfile to non-loaded resume only
- add date_of_birth input to personal info section
- add loadError test
2026-03-21 03:04:29 -07:00
56857dc989 feat(settings): Resume Profile tab — store, view, API endpoints, identity sync 2026-03-21 02:57:49 -07:00
6093275549 fix(settings): final code quality fixes for My Profile tab
- add try/except to sync_identity endpoint
- strip id field from mission_preferences save body
- fix NDA v-for key to use company string (not index), add dedup guard
- move imports out of save_user_profile function body
2026-03-21 02:53:29 -07:00
3bcc08c080 fix(settings): spec compliance gaps in My Profile tab
- add POST /api/settings/resume/sync-identity endpoint (IdentitySyncPayload)
- fix loadError destructuring to use storeToRefs for reactivity
2026-03-21 02:40:17 -07:00
d3b4ed74bb fix(settings): address profile tab code quality issues
- add loadError ref to useProfileStore, rendered in MyProfileView
- replace raw fetch with useApiFetch in generateSummary/generateMissions
- remove await from sync-identity call (fire-and-forget)
- add stable id field to MissionPref, use as v-for key
- add test for load() error path
2026-03-21 02:37:53 -07:00
da7d305588 fix(settings): profile tests assert sync-identity; add load/save_user_profile helpers 2026-03-21 02:31:39 -07:00
1ef418ba00 feat(settings): My Profile tab — store, view, API endpoints
- Add useProfileStore (settings/profile) with load/save, all profile fields,
  loading/saving/saveError state, and graceful resume sync-identity call
- Add MyProfileView.vue: Identity, Mission & Values, NDA Companies, and
  Research Brief Preferences sections; autosave on NDA add/remove and
  debounced autosave (400ms) on research checkbox changes
- Add GET/PUT /api/settings/profile endpoints to dev-api.py with YAML
  field mapping (linkedin ↔ linkedin_url, candidate_*_focus ↔ *_focus,
  mission_preferences dict ↔ list of {industry, note})
- 3 new store tests pass; full suite 26/26 green
2026-03-21 02:28:14 -07:00
32a83d6ff4 fix(settings): async guard awaits config load, reactive devTierOverride, validate APP_TIER 2026-03-21 02:23:10 -07:00
05a737572e feat(settings): foundation — appConfig store, settings shell, nested router
- Add useAppConfigStore (isCloud, isDevMode, tier, contractedClient, inferenceProfile)
- Add GET /api/config/app endpoint to dev-api.py (reads env vars)
- Replace flat /settings route with nested children (9 tabs) + redirect to my-profile
- Add global router.beforeEach guard for system/fine-tune/developer tab access control
- Add SettingsView.vue shell: desktop sidebar with group labels, mobile chip bar, RouterView
- Tab visibility driven reactively by store state (cloud mode hides system, GPU profile gates fine-tune, devMode gates developer)
- Tests: 3 store tests + 3 component tests, all passing
2026-03-21 02:19:43 -07:00
4ac9cea5a6 chore: ignore .superpowers/, docs/superpowers/, pytest-output.txt; untrack plan/spec files 2026-03-21 00:55:17 -07:00
3bfce5e6ef feat(survey): show job picker when navigating to /survey with no id 2026-03-21 00:49:55 -07:00
80999b9e7b fix: SurveyView history reactivity, timer cleanup, accessibility
- Reassign expandedHistory.value to a new Set on toggle so Vue tracks
  the change and template expressions re-evaluate correctly
- Capture saveSuccess setTimeout in a module-level variable; clear it
  on unmount to prevent state mutation after component teardown
- Add role="region" + aria-label to screenshot drop zone div
- Add box-sizing: border-box to .save-input to match .survey-textarea
2026-03-21 00:31:31 -07:00
4bea0899db feat(survey): implement SurveyView with navigation wiring 2026-03-21 00:27:57 -07:00
ea23845c23 fix: survey store quality issues — loading in fetchFor, source guard, saveResponse failure test 2026-03-21 00:21:21 -07:00
80ed7a470a feat(survey): add survey Pinia store with tests
Setup-store pattern (setup function style) with fetchFor, analyze,
saveResponse, and clear. analysis ref stores mode + rawInput so
saveResponse can build the full POST body without re-passing them.
6/6 unit tests pass; full suite 15/15.
2026-03-21 00:17:13 -07:00
595035e02d fix(survey): validate mode input and handle malformed base64 in save endpoint 2026-03-21 00:14:39 -07:00
75163b8e48 feat(survey): add 4 backend survey endpoints with tests
Add GET /api/vision/health, POST /api/jobs/{id}/survey/analyze,
POST /api/jobs/{id}/survey/responses, and GET /api/jobs/{id}/survey/responses
to dev-api.py. All 10 TDD tests pass; 549 total suite tests pass (0 regressions).
2026-03-21 00:09:02 -07:00
b1a32ab207 fix: contacts fetch error degrades partially, not full panel blank
Contacts 5xx no longer early-returns from fetchFor, leaving the entire
right panel blank. A new contactsError ref surfaces the failure message
in the Email tab only; JD tab, Cover Letter tab, and match score all
render normally. Adds test asserting partial degradation behavior.
2026-03-20 19:16:03 -07:00
8479f79701 fix: aria-label binding, dead import, guardAndLoad network error handling
- Fix 1: Add missing `:` binding prefix to aria-label on score badge
  (was emitting literal backtick template string to DOM)
- Fix 2: Remove unused `watch` import from InterviewPrepView.vue
- Fix 3: guardAndLoad now checks interviewsStore.error after fetchAll;
  shows pageError banner instead of silently redirecting to /interviews
  on network failure; job is now a ref set explicitly in the guard
- Fix 4: Remove unconditional research-badge from InterviewCard.vue
  (added in this branch; card has no access to prep store so badge
  always showed regardless of whether research exists)
2026-03-20 18:57:41 -07:00
1cee73e233 fix: hide Prep button on hired stage cards 2026-03-20 18:51:18 -07:00
e6385b4c7e feat: implement interview prep view with two-column layout
Two-column desktop layout (40/60 split, sticky left panel):
- Left: job header with stage badge, interview countdown chip, research
  controls (generate/spinner/refresh/retry), and research sections
  (talking points, company, leadership, tech, funding, red flags, A11y)
- Right: tabbed panel (JD + match score/keyword gaps, email history,
  cover letter) plus locally-persisted call notes via @vueuse/core
- Mobile (≤1023px): single-column, left content first
- Routing guard: redirects to /interviews if no id, job not found, or
  wrong status; calls prepStore.fetchFor on mount, clear on unmount
2026-03-20 18:48:38 -07:00
7693abf79d fix: guard generateResearch against POST failure, surface partial fetch errors
- Check error from POST /research/generate; only start pollTask on success to prevent unresolvable polling intervals
- Surface contacts and fullJob fetch errors in fetchFor; silently ignore research 404 (expected when no research yet)
- Remove redundant type assertions (as Contact[], as TaskStatus, as FullJobDetail)
- Add @internal JSDoc to pollTask
- Remove redundant vi.runAllTimersAsync() after vi.advanceTimersByTimeAsync(3000) in test
2026-03-20 18:44:11 -07:00
ff0dd8b3cd refactor: use existing useApi composable in prep store, remove duplicate
Delete useApiFetch.ts wrapper (returned T|null) and update prep.ts and
prep.test.ts to import useApiFetch from useApi.ts directly, destructuring
{ data, error } to match the established pattern used by all other stores.
2026-03-20 18:40:33 -07:00
de69140386 feat: add prep store with research polling
Adds usePrepStore (Pinia) for interview prep data: parallel fetch of
research brief, contacts, task status, and full job detail; setInterval-
based polling that stops on completion and re-fetches; clear() cancels
the interval and resets all state. Also adds useApiFetch composable
wrapper (returns T|null directly) used by the store.
2026-03-20 18:36:19 -07:00
71480d630a refactor: use _get_db() pattern in get_research_brief, fix HTTPException style
- Replace lazy import + scripts.db.get_research with inline SQL via _get_db(),
  matching the pattern used by research_task_status and get_job_contacts
- Exclude raw_output from SELECT instead of post-fetch pop
- Change HTTPException in generate_research to positional-arg style
- Update test_get_research_found/not_found to patch dev_api._get_db
2026-03-20 18:32:02 -07:00
a29cc7b7d3 feat: add research and contacts endpoints for interview prep 2026-03-20 18:18:39 -07:00
347c171e26 fix: prefer HTML body in imap_sync, strip head/style/script, remove 4000-char truncation
- _parse_message now prefers text/html over text/plain so digest emails
  retain href attribute values needed for link extraction
- Strip <head>, <style>, <script> blocks before storing to remove CSS/JS
  garbage while keeping anchor tags intact
- Remove [:4000] truncation — digest emails need full body for URL regex
- Update test: large body should NOT be truncated (assert len == 10_000)
2026-03-20 13:35:30 -07:00
51f5b3f0a0 fix: bootstrap digest store on app mount for correct badge count on load 2026-03-20 10:27:13 -07:00
5621140a72 fix: add error feedback and keyboard accessibility to DigestView 2026-03-20 10:16:24 -07:00
8302b58b20 feat: add DigestView with expand/extract/queue UI 2026-03-20 10:12:45 -07:00
247f807e02 fix: bind aria-label on nav badge span (was static string, not template expression) 2026-03-20 10:10:10 -07:00
165811c420 feat: add Digest tab to nav and router 2026-03-20 10:07:12 -07:00
154f691334 style: use void instead of .catch on fire-and-forget digest-queue call 2026-03-20 10:06:04 -07:00
4246e71061 feat: fire digest-queue add call from digest chip handler 2026-03-20 09:58:16 -07:00
9bf14fbc75 fix: add error rollback and error state hygiene in digest store 2026-03-20 09:56:22 -07:00
4c2a08057c feat: add digest Pinia store 2026-03-20 09:52:52 -07:00
f3e7f89e2e style: pass Path(DB_PATH) to insert_job for type consistency 2026-03-20 09:51:35 -07:00
1b2643675d feat: add queue-jobs and delete digest endpoints 2026-03-20 07:44:19 -07:00
5bb3674fea fix: guard extract_digest_links db.close(), remove domain-in-path false positive, add hint assertion 2026-03-20 07:04:24 -07:00
182ab789df feat: add /extract-links endpoint with URL scoring 2026-03-20 06:59:26 -07:00
7993984af9 fix: guard db.close() in add_to_digest_queue with try/finally 2026-03-20 06:54:50 -07:00
a503ecde3b feat: add GET/POST /api/digest-queue endpoints 2026-03-20 02:51:17 -07:00
0590a3a12e fix: fix indentation and add try/finally in digest startup 2026-03-20 02:36:23 -07:00
6a1ee3ed28 feat: add digest_queue table to schema and dev-api startup 2026-03-20 02:34:41 -07:00
c6f810fb30 feat(signals): add Unrelated and Digest reclassify chips to InterviewsView 2026-03-19 20:01:08 -07:00
87aae6eefc feat(signals): add Unrelated and Digest reclassify chips to InterviewCard 2026-03-19 20:00:27 -07:00
34494db8d8 feat(signals): strip HTML and normalize whitespace from email bodies 2026-03-19 19:59:59 -07:00
909fe60908 feat(interviews): paginate applied list (10 per page) 2026-03-19 19:45:59 -07:00
e487942eeb fix(signals): add .stop modifiers and aria-labels to pre-list signal banner buttons 2026-03-19 19:35:15 -07:00
9de51d6b4a feat(signals): expandable body + reclassify chips in InterviewsView pre-list 2026-03-19 19:31:23 -07:00