Build Careerflow

YESreplaces $23.99/mosaves $287.88/yrback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A local job search workspace whose hard problems are keeping a tailored document traceable to approved evidence, treating imported document text as an approximate suggestion rather than fact, and reporting requirement coverage instead of inventing a score.

estimated effort weekendthe files for this build are in the project pack

RuntimeNext.js with TypeScript and SQLite through Drizzle, bound to loopbackEvidenceStructured rows with an approval flag, the only source of document textImportsPDF and text imports held as drafts with extraction warnings shownModelOptional, restricted to rephrasing approved text, with the difference shown before savingOutputDocuments rendered from structured data, never from edited free text

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the application and the document rendering.

    Get it nodejs.org, or nvm install 22. open ↗

    Verify node --version prints v22 or higher

  2. have readyfree

    Why Coverage and extraction are only meaningful against a description you might actually apply to, and a seeded example will pass every test that matters.

    Get it Your current CV as a PDF, and two descriptions saved as text or PDF.

    Verify Both import, and the requirements list needs only small edits

  3. have readyfree

    Why The column interleaving warning is the one extraction behaviour most likely to be missed, and it needs a document that actually has the problem.

    Get it Any CV or leaflet laid out in two columns, saved as a PDF and kept in the fixtures.

    Verify Extraction of it raises the interleaving warning with a page number

  4. installfree

    Why Documents are rendered from structured data, so the renderer is a dependency rather than a browser print dialogue.

    Get it Any maintained library that renders from structured content and can be run headless.

    Verify It renders a fixture document whose text extracts back in the right order

  5. API keypennies per document

    Why Only for rephrasing approved text, and the tool is designed to stay useful when it is absent.

    Get it Create a key in your provider's console and put it in .env, or leave it unset.

    Verify With it unset, everything except rephrasing still works

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- evidence(id, kind, title, organisation, start_date, end_date, body, metrics_json, source_note, approved_at) · nothing is usable until it is approved
- imports(id, kind, filename, extracted_text, warnings_json, approved_at) · an import is a draft until a person confirms it line by line
- roles(id, company, title, description_text, source_url, imported_at) · the job, kept as text you can quote from
- requirements(role_id, ordinal, text, kind) · extracted from the description and editable, because the extraction is a suggestion
- coverage(role_id, requirement_ordinal, evidence_id, strength, note) · no rows means not covered, which is a perfectly good answer
- variants(id, role_id, name, created_at) and variant_items(variant_id, ordinal, evidence_id, rendered_text) · every rendered line points at one evidence row
- applications(id, role_id, variant_id, stage, applied_at, next_action_at, outcome, notes) · contacts and activity hang off this row

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DATABASE_PATHrequired./data/career.dbEvidence, roles, variants and applications.
DOCUMENTS_DIRrequired./data/documentsRendered CVs and letters. Deleted with their application.
BIND_ADDRESSrequired127.0.0.1Loopback. This folder holds your salary history and your rejections.
USER_TIMEZONErequiredEurope/LondonThe due view depends on it, and follow ups are the point of the tracker.
EXPORT_DIRrequired./exportsJSON and CSV exports, which are how you leave.
MODEL_MODErequiredrephrase-onlyThe only permitted mode. There is no generate mode to switch to.
OPENAI_API_KEYsecretoptionalsk-...redactedOptional. Unset disables rephrasing and nothing else.

The build, in order

  1. An evidence bank you actually wrote

    Every fact about your career exists once, dated, with a note on where it came from.

    1. Unapproved rows are invisible to every document query.

      Files src/evidence.tstests/approval-gate.test.ts

    2. One sentence about how you know it, which is also what you will say in the interview.

      Files src/db/schema.ts

    3. The same job entered twice produces two truths.

      Files src/evidence/dedupe.ts

    done when · tick each as it passes
    watch out
    • Letting a resume import become evidence directly means every later document is tailored from an approximate parse of your own history, complete with a metric that was mangled and a date that slipped, and you will not notice because it looks like something you wrote. Imports land as drafts and become evidence only when a person approves each row.
  2. Extracted text is a suggestion

    Nothing imported becomes data until a person has seen what came out.

    1. Two panes, and the failure becomes obvious in a second.

      Files src/imports/review.tsx

    2. Detect short alternating fragments and say which page.

      Files src/imports/extract.tstests/two-column.test.ts

    3. So a bad import can be understood later rather than repeated.

      Files src/imports/approve.ts

    done when · tick each as it passes
    watch out
    • Text pulled out of a PDF arrives in the order the document's structure gives, not the order the eye follows: the W3C technique on PDF reading order notes that if a two column document is not properly tagged a reader goes straight across both columns and treats them as one, so an untagged two column CV extracts as interleaved half sentences that look like a typing error rather than a parsing failure. Show the extraction for approval and mark the pages where the order looks wrong.
  3. Coverage, not a score

    A role shows which requirements you can evidence and which you cannot.

    1. Extraction proposes; the person applying decides.

      Files src/requirements.ts

    2. Strength is a judgement, recorded as one.

      Files src/coverage.ts

    3. There is no function that does it, not a setting that hides it.

      Files src/coverage.tstests/no-score.test.ts

    done when · tick each as it passes
    watch out
    • A single match percentage is the number everybody wants and the one thing here that cannot be honest, because it implies knowledge of a process you cannot observe and it hides which specific requirement has nothing behind it. Show the three states per requirement with the evidence attached, and leave the summarising to the person applying.
  4. A document assembled from approved rows

    Every rendered line traces to an evidence row and adds nothing to it.

    1. A token level comparison against the source row catches the common cases.

      Files src/rephrase/guard.tstests/no-invention.test.ts

    2. The person approves the change, not the idea of the change.

      Files src/rephrase/review.tsx

    3. So what you send is what the data says, in an order you chose.

      Files src/render/document.ts

    done when · tick each as it passes
    watch out
    • A model asked to make a bullet sound stronger will quietly add 'by 40 percent' because that is what strong bullets look like, and the invented figure then gets defended in an interview by somebody who believes they wrote it. Compare the rephrasing against the source row, block any new number, date or proper noun, and show the difference before saving.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more career.