The reason v2 is cheap: v1 didn't just ship a feature, it stood up the reusable surface every later feature needs. Read the right column — that's why each v2 item is an addition, not a project.
| v2 feature | What it fundamentally is | Reuses from the MVP |
|---|---|---|
| Guest headshot | a no-login photo sale | foto-service (live) · Core billing · the headshot UI |
| Career Radar | jobs fed into the dossier loop, on a schedule | the whole dossier route · preferences CRUD · oll-memory profile · applications CRUD |
| Get-found | a draft-post variant of generation + a scheduler | oll-write generation · the memory corpus · auth |
| Ollie (agent) | the dossier verbs driven autonomously | the exact dossier verbs (via MCP) · applications CRUD (the review inbox) |
A standalone, no-login page that sells the CHF 29 Bewerbungsfoto — the lowest-commitment on-ramp, and the quickest new revenue after v1. Status (2026-07-08): the frontend funnel is built and verified by running on branch feat/v2-guest-photo; both backend halves are green PRs awaiting merge.
/photo funnel — no-login: upload 4–8 snaps (client-validated) → Swiss style pick → CHF 29 pay-once (price on screen one) → Stripe return at /photo/fulfill (real foto FulfillResponse state machine → delivered image URLs)./api/photo/checkout·fulfill·health) mirror services/foto/openapi.yaml exactly, over FOTO_BASE + the v1 retry lib. Built on v1's design tokens — same product.CORE_UNAVAILABLE) surfaces — no mock.STRIPE_PRICE_HEADSHOT_CHF29_ONE_TIME, test→live).input_photo_urls are references; storage is a foto TODO). The funnel captures + validates snaps client-side but sends [] until a storage endpoint exists — flagged in the UI, not faked. This is the one genuine backend addition v2.1 needs before real Replicate training.FOTO_PUBLIC_BASE_URL={web-origin}/photo; a .ch domain (nice-to-have).The recurring hook: oll.in watches the market for you daily and keeps an application half-ready. This is where the product stops being a one-shot tool and becomes a service — and it reuses the entire dossier route.
/radar frontend renders real scored match cards off a live tick (pulled 7 → 4 strong → digest sent), with a live min-score filter and a "Build dossier" hand-off into the v1 composer. The review-fix caught + fixed a real broken hop (the BFF hit the now-auth-required scout with no Bearer → 401 → 0 matches); now forwards the real Core JWT. The CHF 19/mo tier is wired to a real Core subscription-mode session (no fake charge) — the one product that legitimately is a subscription. Anon preview — SOLID: a public, no-auth GET /api/scout/sample-matches (PR #93, fixture-scored in-memory — no PII, no Core round-trip) now backs the logged-out /radar preview, so a stranger sees real scored cards with zero 401s in prod; signed-in still forwards the real JWT to the ownership-scoped /matches (verified: prod-mode sample-matches → 200 with no Core hop, while the old anon path correctly 401'd). Sam-gated: AUTH_PROVIDER=core in prod · a live CHF 19/mo recurring price + RADAR_PLAN_GATE · a Jooble key for live CH coverage (Arbeitnow works keyless today).The second engine: instead of only applying out, help recruiters find you. oll.in drafts credible LinkedIn posts in your voice and schedules them — official OAuth only, you approve every one.
/get-found route is built and honest. The draft is real oll-write/Groq generation grounded on the corpus (4 grounded passages; honest abstain on a miss). Postiz connections honestly report "no key"; the schedule action returns a real 501/409 ("no LinkedIn channel connected") — never a fake "scheduled." Sam-gated: a POSTIZ_API_KEY + a LinkedIn OAuth app to actually schedule (sanctioned OAuth only — never scraping).The flagship: "Ollie" runs your search — scouts, matches, and prepares each application while you sleep, then hands you a ready dossier to send. You always hit send. The magic is that most of it is the v1 verbs driven autonomously — but this is the one v2 item that isn't purely a route + delta.
prepared_by=ollie, status=draft, nothing sent. UI is honest: "drafts for you to review, never auto-sent"; "Approve & mark sent" is a status marker, not an employer submission (hard ethics/ToS line — no auto-apply, human-on-send always). The always-on per-user runtime is deferred, infra-gated — "Prepare now" is an honest manual trigger today.Applications tracker+: extend v1's applications CRUD with a richer status pipeline, RAV-deadline reminders (Core email), and interview-reply nudges — a natural addition to the list that already exists. Full German: next-intl over the Next.js app; v1 output already adapts language to the job, so this is UI-string localization, not logic.
de.json, working language toggle; build passes). German — SOLID, proven by a Playwright walk across every surface (home/compose, /photo, /radar, applications, Ollie): a real defect was found + fixed (/photo and /radar were never wired to next-intl — English content under a German shell); now every visible string is routed through useTranslations (rich markup + interpolation), full EN/DE key parity, zero missing-key fallbacks or unresolved {vars}, no layout overflow on the longer German strings.The honest line holds: you own the tool (pay once); you subscribe to the work. The dossier engine is yours; Radar/Ollie is a service that never sleeps.