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
This commit is contained in:
@@ -5,6 +5,7 @@ Job Tracker is a simple, self-hosted app for tracking job applications with a Re
|
||||
## Features (high level)
|
||||
|
||||
- Track job applications (status, applied date, notes, tags, follow-up dates, deadlines, salary, links, etc.)
|
||||
- Share opt-in public CV links with recruiter-friendly PDF download
|
||||
- Company management (location/source, recruiter details, pipeline stage, next contact date)
|
||||
- Correspondence log per application (email/messages with subject/channel/date)
|
||||
- Attachments per application (upload, list, download, rename, delete)
|
||||
@@ -16,6 +17,7 @@ Job Tracker is a simple, self-hosted app for tracking job applications with a Re
|
||||
- Note: no offline service-worker cache is bundled by design (the app is deployed frequently; an aggressive cache would risk serving stale builds). The manifest provides installability and share-to-capture without it.
|
||||
- Optional local AI service for short/full descriptions
|
||||
- Optional Google sign-in (Google ID tokens) to protect the API
|
||||
- Standard Problem Details responses with trace IDs for unhandled API errors
|
||||
|
||||
## Architecture
|
||||
|
||||
@@ -103,7 +105,18 @@ npm start
|
||||
|
||||
The UI defaults to calling `http://localhost:5202/api` when running on localhost (see `job-tracker-ui/src/api.ts`).
|
||||
|
||||
### 3) (Optional) Run the AI service
|
||||
### 3) Run the browser smoke suite
|
||||
|
||||
```bash
|
||||
cd job-tracker-ui
|
||||
npx playwright install chromium
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
The suite starts isolated API/SQLite and Next.js processes, then covers login, saved-job creation,
|
||||
Career Workspace, and anonymous public-CV/PDF access. It is also a required CI gate.
|
||||
|
||||
### 4) (Optional) Run the AI service
|
||||
|
||||
The API calls a local FastAPI service to generate summaries. If it’s not running, the app still works (summary generation may be empty / best-effort).
|
||||
|
||||
@@ -130,7 +143,8 @@ Common keys:
|
||||
- `ConnectionStrings:JobTracker`: overrides SQLite location (otherwise uses `DataRoot/jobtracker.db`)
|
||||
- `Data:Root`: folder for the SQLite DB + exports (defaults to API content root)
|
||||
- `Data:AttachmentsRoot`: override attachments folder (defaults to `<Data:Root>/Attachments`)
|
||||
- `Cors:Origins`: list of allowed origins (defaults to `http://localhost:3000`; use `"*"` to allow all)
|
||||
- `CvExports:RetainDays`: generated PDF retention in days (default `30`, clamped to `1`–`365`)
|
||||
- `Cors:Origins`: list of allowed origins (defaults to `http://localhost:3000`; wildcard origins are rejected because requests use credentials)
|
||||
- `Ai:BaseUrl`: AI service base URL (default `http://127.0.0.1:8001`)
|
||||
- `Exports:DailyEnabled`: enable/disable daily export background job
|
||||
- `Exports:DailyFolder`: export destination (relative to `Data:Root` if not absolute)
|
||||
@@ -147,6 +161,8 @@ Common keys:
|
||||
- `Auth:AdminEmail` / `Auth:AdminPassword`: optional seed admin user (created on startup if missing)
|
||||
- `Auth:AllowRegistration`: allow self-service registration via `POST /api/auth/register` (default `false`)
|
||||
- `Auth:Require`: if `true`, all endpoints require auth (except endpoints explicitly marked anonymous)
|
||||
- `Stripe:SecretKey`, `Stripe:PricePremium`, `Stripe:WebhookSecret`: enable hosted Premium checkout,
|
||||
the customer portal, and signed subscription webhooks when all are configured
|
||||
- `Translation:Provider`: `none` (default) or `libretranslate`
|
||||
- `Translation:LibreTranslate:BaseUrl`: base URL for LibreTranslate (only if provider enabled)
|
||||
- `Translation:LibreTranslate:ApiKey`: optional API key for LibreTranslate
|
||||
@@ -163,7 +179,7 @@ Common keys:
|
||||
|
||||
### UI settings
|
||||
|
||||
- `REACT_APP_API_BASE_URL`: override the API base URL (example: `http://localhost:5202/api`)
|
||||
- `NEXT_PUBLIC_API_BASE_URL`: override the API base URL (example: `http://localhost:5202/api`)
|
||||
|
||||
## API endpoint reference
|
||||
|
||||
@@ -206,7 +222,7 @@ Authentication:
|
||||
- `GET /api/jobapplications/stats`
|
||||
- Returns totals, counts by status, applied-last-30-days, and average days since applied.
|
||||
- `GET /api/jobapplications/{id}/match-score`
|
||||
- Deterministic CV↔job keyword-coverage score (0–100) with matched/missing keywords and per-CV-section coverage. No AI calls: results are instant and reproducible. Requires profile CV text/structure and a job description. (The AI narrative equivalent is `GET /api/jobapplications/{id}/candidate-fit`.)
|
||||
- Deterministic CV↔job keyword-coverage score (0–100) with matched/missing keywords and per-CV-section coverage. Missing skills also seed a checklist-backed job-specific learning path, so users can mark them learned or dismiss them. No AI calls: results are instant and reproducible. Requires profile CV text/structure and a job description. (The AI narrative equivalent is `GET /api/jobapplications/{id}/candidate-fit`.)
|
||||
- `GET /api/jobapplications/{id}/status-suggestion`
|
||||
- Deterministic status suggestion derived from the job's most recent inbound message (interview invite / offer / rejection). Returns a forward-only suggestion (`hasSuggestion`, `suggestedStatus`, `signal`, …) or `hasSuggestion: false`. Applying it is a normal `PATCH .../status` — always user-confirmed.
|
||||
- `DELETE /api/jobapplications/{id}`
|
||||
|
||||
Reference in New Issue
Block a user