Commit graph

31 commits

Author SHA1 Message Date
hermes
aa858bd2c1 Screenshot pipeline + fixes found under real render (CORS, batch state stomp, prompt-aware cv_tailor mock)
Some checks failed
CI / api-tests (push) Failing after 32s
CI / package-tests (push) Failing after 38s
CI / web-tests (push) Failing after 36s
- scripts/screenshots.py + scripts/Dockerfile.shots: playwright-in-compose
  runner, 7 demo shots against the seeded stack (DinD-safe, output volume)
- docker-compose.yml: api + web services (nginx SPA + /api proxy-less via
  build-arg VITE_API_BASE), shots service with volume output
- apps/api: add CORSMiddleware (SPA origin web:80 could not read api:8000),
  batch scoring now refuses to rewrite applications beyond
  discovered/scored (kanban page load previously reset sent/interviewing
  to scored), prompt-aware cv_tailor mock so demo passes hallucination
  guard, hallucination-guard tests repointed to monkeypatched run_task
- apps/web: Applications kanban batches only unscored applications, red
  flag display falls back to stored rationale
- 159 api tests + 14 web tests green after fixes
2026-07-30 21:40:14 +00:00
hermes
9be1fd991b WS1: fix date parsing in seed counts (integration lead commit after worker iteration limit) 2026-07-30 21:15:11 +00:00
hermes
ba51a00f2b WS1: Add 8 extended seed-demo tests (cluster, deadlines, red flags, suggestions, notifications, telemetry, artifacts) 2026-07-30 21:10:30 +00:00
hermes
71a16d35ed WS1: Extend seed-demo with agency cluster, deadlines, red flags, artifacts, telemetry, suggestions, notifications 2026-07-30 21:10:18 +00:00
hermes
641f70b68c WB2: append v1.1 section to user guide (email radar, dedupe, tailor CV)
Some checks failed
CI / api-tests (push) Failing after 25s
CI / package-tests (push) Failing after 38s
CI / web-tests (push) Failing after 39s
2026-07-30 21:02:46 +00:00
hermes
62b8af2ab8 WB2: fix TodayView type for getToday returning TodayResponseV11 (deadlines field) 2026-07-30 21:02:42 +00:00
hermes
d8967f29f0 WB1: add >=20 tests for cluster, tailor-cv, deadline integration
Some checks failed
CI / api-tests (push) Failing after 26s
CI / package-tests (push) Failing after 42s
CI / web-tests (push) Failing after 43s
2026-07-30 20:53:21 +00:00
hermes
b3a1f588ef WB1: migration 004, cluster assignment, GET /clusters, tailor-cv endpoint, deadline integration, Dockerfile.test matching install 2026-07-30 20:52:25 +00:00
hermes
59ea645125 v1.1 wave B dispatch cards (dedupe+tailor+deadline api, web v1.1 UI)
Some checks failed
CI / api-tests (push) Failing after 30s
CI / package-tests (push) Failing after 38s
CI / web-tests (push) Failing after 33s
2026-07-30 20:47:07 +00:00
hermes
7bd9e5bfc6 Merge remote-tracking branch 'origin/feat/WA1-email-notify'
Some checks failed
CI / api-tests (push) Has been cancelled
CI / package-tests (push) Has been cancelled
CI / web-tests (push) Has been cancelled
2026-07-30 20:46:13 +00:00
hermes
8dceedca2b WA2: llm-gateway deterministic mocks for email_classify (CHEAP), cv_tailor (STRONG), deadline_extract (CHEAP) + 9 tests 2026-07-30 20:45:11 +00:00
hermes
31a3509bd3 WA2: packages/matching - similarity, dedupe cluster, keywords extract+coverage, 65 tests with agency-repost fixture triples 2026-07-30 20:43:28 +00:00
hermes
069ac454e5 WA2: packages/matching - similarity, dedupe cluster, keywords extract+coverage, 65 tests with agency-repost fixture triples 2026-07-30 20:42:39 +00:00
hermes
05ba99cb4b WA1: add 35 tests for email watch, notifications, suggestions, digest 2026-07-30 20:41:27 +00:00
hermes
6c38de5fed WA1: migration 003, imap_watch, notify, scheduler jobs, suggestions+notifications endpoints, email_classify mock 2026-07-30 20:40:03 +00:00
hermes
5e539ba713 ADR-0003 v1.1 scope + wave A dispatch cards (feel-alive: email watch, notify, dedupe, tailor, deadlines)
Some checks failed
CI / api-tests (push) Failing after 31s
CI / package-tests (push) Failing after 25s
CI / web-tests (push) Failing after 35s
2026-07-30 20:36:02 +00:00
hermes
c69fb128bd W3: add Forgejo CI workflow, user guide, README screenshots placeholder section
Some checks failed
CI / api-tests (push) Failing after 30s
CI / package-tests (push) Failing after 58s
CI / web-tests (push) Failing after 37s
2026-07-30 18:36:51 +00:00
hermes
1e55c11dc9 W3: add 3 new vitest tests (wizard routing, nudge badge render, red flag tooltip); update existing test mocks for new API functions 2026-07-30 18:36:22 +00:00
hermes
f43ede9e07 W3: add red-flag badges + nudge dots to kanban, interview-prep modal to detail, fetch form + scam column to Research 2026-07-30 18:34:42 +00:00
hermes
e9b3b37e0d W3: add TodayView, Welcome wizard, CostDisplay, InterviewPrepModal; update router and App nav 2026-07-30 18:33:36 +00:00
hermes
115fea39f2 W3: add v2 API types and client functions (cv import, postings fetch, batch scoring, today, interview prep, telemetry, demo seed) 2026-07-30 18:32:18 +00:00
hermes
9ee5449acb Merge branch 'feat/W2-api-v1' 2026-07-30 18:29:18 +00:00
hermes
3035e4eac9 W2: api v1 features (CV import, AF fetch, batch scoring, today/nudges, interview prep, SMTP+clipboard transports, scheduler, 90 tests)
Implements docs/api-contract-v2.md. Migration 002 adds follow-up fields.
EchoTransport replaced by SMTP->Clipboard selection behind unchanged approval gate.
Scheduler (APScheduler) daily 07:00 fetch+score, env-gated, default off.
Test image installs workspace packages; build context moved to repo root.
Recovered and committed by integration lead after W2 worker hit iteration limit.
2026-07-30 18:29:17 +00:00
hermes
0e13ee5d51 feat(W1): packages/connectors - AF API, generic URL, dedupe, normalizer
- Connector protocol with fetch(query: SearchQuery) -> list[RawPosting]
- ArbetsformedlingenConnector: official Platsbanken API, field mapping
  (headline->title, employer.name->company, webpage_url->url,
  description.text->description, id->external_id), region mapping,
  polite User-Agent
- GenericUrlConnector: readability extraction (prefers main/article,
  strips nav/footer/script/style), title/company guess, Cloudflare
  challenge detection -> UnsupportedSite
- dedupe helper: (source, url) + external_id keying
- normalizer: RawPosting -> JobPosting (job_posting table shape)
- 37 tests, all passing, recorded fixtures (no live network)
- README with usage and mock examples
2026-07-30 18:23:24 +00:00
hermes
d1753bb70a v1.0 design: perspective review + ADR-0002 scope + worker dispatch cards 2026-07-30 18:20:45 +00:00
hermes
7560bdb4c9 Docs: DinD-safe quick start (compose test runner + in-network API smoke) 2026-07-30 18:12:05 +00:00
hermes
17759ef564 T1: FastAPI backend core (models, state machine, approval gate) + compose test runner
- apps/api: psycopg v3 repositories, schema.sql + migration runner, state machine
  implementing the data-model transition table, approval gate with sha256 hash
  match + 24h expiry enforced at send time, EchoTransport pluggable sender,
  LLM calls routed through packages.llm-gateway with mock mode, 47 pytest tests green
- apps/api/Dockerfile.test: python 3.13-slim test image (DinD-safe: migrations
  copied as directory)
- docker-compose.yml: add api-test service on compose network (host port
  publishing is broken in this sandbox; container-to-container networking used)
- Fix: replace masked placeholder password in config.py/conftest.py defaults
2026-07-30 18:10:59 +00:00
hermes
8eb8400bad Merge branch 'feat/T3-web' 2026-07-30 18:05:31 +00:00
hermes
bc81cb2398 T3: apps/web frontend shell (Vue 3 + Vite + TypeScript + Pinia + vue-router + Tailwind)
Implements the four views per the task card:

1. CV Editor (/cv):
   - Profile form (name/email/phone/location/headline/summary) with save
   - Section list editor: add/edit/delete sections with kind select,
     title/org/dates, bullet list editor with per-bullet AI-assist
     button calling POST /profile/sections/{id}/ai-assist, suggestions
     shown with accept/dismiss
   - Render CV button -> POST /profile/render-cv, shows URL link

2. Research (/research):
   - Table of postings (GET /postings) with company/title/location/
     source/fetched_at
   - Add by URL input -> POST /postings
   - Score button per row -> shows score result

3. Applications (/applications):
   - Kanban board grouped by state (10 columns per data-model states)
   - Cards show company/title/score
   - HTML5 drag-and-drop between columns -> POST /applications/{id}/transition
   - Optimistic update, revert on 409 with toast showing reason
   - Click card to navigate to detail view

4. Application detail (/applications/:id):
   - Posting info, state, score
   - Artifacts list
   - Cover-letter editor (textarea) -> save calls POST /applications/{id}/artifacts/
     cover-letter, critique rendered as cards with severity color coding
   - Approval widget: select artifact + action -> request approval ->
     I confirm button -> Send button (disabled until confirmed; shows
     409 errors as toasts)

Tech stack:
- Vue 3 + Vite + TypeScript (strict, noUnusedLocals/Parameters)
- Pinia for state (toast store)
- vue-router with lazy-loaded views
- Tailwind CSS configured locally (no CDN), PostCSS + autoprefixer
- API base from VITE_API_BASE defaulting to http://localhost:8000/api
- Typed API client module (src/api/index.ts) matching the contract
- Domain types (src/types/index.ts) from data-model.md

Tests (vitest, all passing):
- router.test.ts: router renders 3 tab links (CV, Research, Applications)
- Applications.test.ts: kanban groups cards by state from fixture
- ApplicationDetail.test.ts: Send disabled until confirmed; 409 error toast

Build: npm run build passes (vue-tsc --noEmit + vite build)
Tests: npm run test passes (4 tests, 3 files)
2026-07-30 18:00:55 +00:00
hermes
8d8a863300 T2: packages/artifacts + packages/llm-gateway + docker-compose.yml + .env.example
packages/artifacts:
- render_cv_pdf(profile, sections) -> bytes: data-driven CV PDF generation
  using fpdf2 with bundled DejaVuSans TTF for unicode (Swedish chars tested).
  Jinja2 template for layout data prep, adapted from build_cv.py approach.
- render_cover_letter(text, profile) -> bytes: simple cover letter PDF.
- hash_bytes(b) -> str: sha256 hex digest.
- next_version(existing) -> int: version numbering helper.
- 16 tests, all passing: PDF validity, Swedish characters, hash stability,
  cover letter rendering, hash correctness, version logic.

packages/llm-gateway:
- Async-first Gateway class with provider config from env.
- Mock mode default when no API key env present (deterministic canned outputs
  per task name, defined in mock.py).
- Telemetry sink injectable (async or sync callable, receives TelemetryRow).
- Budget guard raises BudgetExceeded BEFORE any provider call is made.
- Retry policy: max 2 retries on 429/5xx, then fallback provider for STRONG
  tasks only. CHEAP tasks never use fallback (paid provider protection).
- Schema validation via jsonschema; SchemaValidationError on mismatch.
- Task class routing: CHEAP (score, extract, cv_assist) vs STRONG (critique,
  cl_critique, research). Model routing per task class.
- Paid provider detection heuristic; warns on paid fallback config.
- 31 tests, all passing: mock determinism, schema pass/fail, budget guard
  (mock + real mode), telemetry sink (async/sync/none), config from env,
  provider calls with mocked HTTP (retry, fallback, no-fallback-for-cheap).

docker-compose.yml:
- postgres:16 service, user/pass/db = jobhunt, host port 5433->5432,
  named volume jobhunt_pgdata, healthcheck.

.env.example:
- DATABASE_URL, LLM provider config (primary + fallback), task budgets,
  API and web settings.
2026-07-30 17:59:56 +00:00
hermes
b77c8b0044 Bootstrap: README, ADR-0001 (LLM at decision points), data model, API contract, worker task cards
Design foundation for POC. Monorepo: FastAPI+Postgres backend, Vue 3 frontend,
Python packages (llm-gateway, artifacts, connectors). Approval gate and
token budgets are architectural constraints per measured prototype findings.
2026-07-30 17:56:07 +00:00