Skip to content

Data Model

All candidate-specific data lives in Postgres. The repo contains zero personal data. This page documents what tables exist, what keys live in JSONB, and which flow owns each piece of data.

Tables

users

Single row. Structured columns plus data JSONB for semi-structured profile info.

ColumnTypePurpose
idSERIAL PKAlways 1 (single user)
nameTEXTUser's full name
emailTEXTUser's email (unique)
dataJSONBAll semi-structured data (see below)

users.data JSONB keys

KeyWhat it holdsWritten byRead by
profileCV extraction: name, title, summary, skills, experience, education, languages, projects, github, blog, cv_url, cv_pathprofileapply, targets, news, daily
job_preferences30 questionnaire answers with Must/Strong/Nice weightsprofileapply, targets, news, daily
form_answersStandard answers for Easy Apply and other job formsonboarding, applylinkedin-easy-apply.js, apply flow
style_profileCommunication style: tone, language, length, greeting, closing, emojis, samplesprofilenews (drafting replies), all flows (language)
platformsPlatform tier assignment: tier_1, tier_2, tier_3, discardedprofileradar, apply, news
target_companiesCurated target companies by regionprofile or manualtargets, apply
strategyJob search strategy parameters (level, batch sizes, thresholds, etc.)onboarding, strategy flow, memoryAll flows (pre-flight)
availabilityInterview time preferences (preferred hours, timezone, blocked slots)onboardingnews (scheduling)

applications

Every job application registered.

ColumnTypePurpose
idSERIAL PK
user_idINTEGER FKAlways 1
platformTEXTlinkedin, email, teamtailor, etc.
companyTEXTCompany name
roleTEXTJob title
urlTEXTJob posting URL (used for dedup)
statusTEXTPipeline stage (discovered, contacted, applied, in_review, screening, interview, offer, hired, rejected, withdrawn, skipped)
applied_atTIMESTAMPTZDefault NOW()
dataJSONBMatch reason, method, location, stage_history

company_registrations

Tracks registration and application status per target company. Enables resumability for the targets flow.

messages

Recruiter and contact messages, with drafts and send tracking.

preferences

Autonomous preference storage. Populated by the memory skill from conversation signals.

CategoryKeyValuesPurpose
toolingbrowser_modeheadless, headed, headed_logins_only, ask_each_timeControls browser visibility. Default: headed_logins_only
workflowstrategy_levelpassive, selective, active, aggressiveControls job search aggressiveness. Default: selective

Pipeline stages

Active stages (left to right in the kanban): discovered -> contacted -> applied -> in_review -> screening -> interview -> offer -> hired

Closed stages: rejected, withdrawn, skipped

Released under the MIT License.