Commit graph

3 commits

Author SHA1 Message Date
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
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
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