Skip to content

Database

The platform uses Cloudflare D1 (edge SQLite) for all structured data. Schema is defined in db/schema.sql, seed data in db/seed.sql, and incremental changes in db/migrations/.

db/migrations/ is forward-only — wrangler auto-applies every .sql file there in alphabetical order. Manual rollbacks live in db/rollbacks/ and are never auto-applied; see Database Migrations → Rollbacks.

TablePurpose
usersAuthenticated users (auto-created on first login). Auth-only: id, email, name, picture, job_title, pronunciation, access_level, template IDs
tool_permissionsPer-tool, per-access-level permission grants
org_settingsOrganisation-level key-value settings (timezone, holiday_state)
user_preferencesPer-user preference overrides (timezone, holiday_state)
squadsTeam groupings derived from people.squad column during Productive sync
sidebar_favoritesPer-user pinned sidebar items
daily_quotesRotating quotes shown on dashboard
historyAudit trail of changes across all resource types
notesFreeform notes attached to any resource (company, contact, deal, project, etc)
TablePurpose
peopleSource of truth for all employee/HR data. Synced from Productive, enriched via Xero. Includes pronunciation (phonetic name guide, propagated from the linked user). manager_id drives data scoping hierarchy
person_linkedin_activitiesLinkedIn activity snapshots for people
person_change_alertsAlerts when LinkedIn/external data indicates a change
TablePurpose
onboarding_templatesNamed onboarding templates assigned to users
scorecard_templatesNamed scorecard templates assigned to users
scorecard_template_itemsChecklist items belonging to a scorecard template
review_templatesNamed KPI templates for performance reviews
review_template_itemsKPI items per review template (area, label, is_mandatory, sort_order)
template_profilesNamed role bundles that group one onboarding + one scorecard + one review template
TablePurpose
onboarding_phases5 phases with name, description, sort order
onboarding_itemsChecklist items within phases (linked to a template; tpl-onb-common = shown to all users)
onboarding_progressPer-user completion state for each item. person_id links to people
TablePurpose
objectivesBusiness objectives with category (financial/customer/operational/people)
prioritiesCurrent priorities linked to an objective, with is_active flag
kpi_definitionsKPI definitions linked to a priority, scoped by access_level
TablePurpose
scorecardsScorecard header (squad, week, type, period_key, notes, scorecard_template_id). person_id links to people
scorecard_scoresIndividual score items (status, note)
scorecard_kpisKPI entries (text, target, actual, status, kpi_definition_id)
scorecard_metricsFinancial metrics (billable, utilisation, revenue, profit)
TablePurpose
review_cyclesReview periods (quarterly/annual) with draft/open/closed lifecycle
reviewsOne per person per cycle; status workflow, KPI pass/fail, self-assessment, salary decision
review_kpi_ratingsSnapshot of template items with 3-tier ratings (needs_urgent_work/achieving/exceeding)
review_goalsSMART goals (goal, success measures, support needed, completion status)
feedback_requests360 feedback assignments with pending/submitted/declined status
feedback_responsesStructured 5-area feedback with ratings and comments
review_questionsCentral question bank for reviews and feedback
report_snapshotsCached performance reporting data snapshots
TablePurpose
announcementsTitle, content, category (process/team/client/company), attachment URL/name, author
announcement_readsRead receipts per user per announcement
announcement_distributionsDistribution tracking: channel (slack/google_calendar/email), status, external_id, error
TablePurpose
calendar_settingsPer-user calendar display and sync settings
eventsTeam events with voting, categories, and scheduling
event_votesPer-user votes on event proposals
TablePurpose
connectionsOrg-level OAuth/API tokens for external services (Xero, Slack, Productive). Tokens are AES-GCM encrypted
user_connectionsPer-user OAuth tokens for personal integrations (Google, GitHub, etc)
TablePurpose
leave_typesCached from Xero PayItems (leave type ID, name, is_paid)
leave_balancesPer-person leave balances cached from Xero (1hr TTL)
leave_requestsLeave requests with status, dates, approval chain, external integration IDs
TablePurpose
public_holidaysCached Australian public holidays from Nager.Date API (24hr TTL)
TablePurpose
pay_summariesCached pay template info from Xero (annual salary, earnings YTD, next pay date). PK is person_id
payslipsCached payslip summaries from Xero
TablePurpose
documentsEmployee documents (contracts, policies, certificates) with type, file URL, expiry tracking
TablePurpose
companiesCompany records with industry, domain, logo, pronunciation, Productive/Stripe IDs, parent company hierarchy
contactsIndividual contacts linked to a company with role, email, phone, pronunciation, LinkedIn, is_primary flag
contact_communicationsCommunication history with contacts (emails, calls, meetings)
contact_relationship_profilesAI-enriched relationship context per contact
contact_life_eventsKey dates and life events for relationship nurturing
contact_partnersContact-to-contact partner/relationship links
TablePurpose
dealsSales pipeline deals with stage, value, probability, company, close date
deal_pipeline_templatesNamed pipeline configurations
deal_pipeline_stagesOrdered stages within a pipeline template
deal_participantsTeam members assigned to a deal
deal_contact_linksContacts associated with a deal
deal_research_briefsAI-generated research context for deals
deal_project_linksLinks between won deals and resulting projects
TablePurpose
contractsService contracts with terms, value, renewal dates, signing status
contract_templatesReusable contract templates
contract_signersSigners on a contract with status tracking
TablePurpose
proposalsClient proposals with status, approval chain, pricing
proposal_templatesReusable proposal templates
proposal_template_pagesPage content within proposal templates
proposal_pagesPage content within individual proposals
proposal_pricing_sectionsPricing sections with subtotals
proposal_pricing_itemsIndividual line items within pricing sections
proposal_approvalsInternal approval workflow entries
proposal_team_membersTeam members presented on a proposal
proposal_signersExternal signers with signing status
proposal_viewsAnalytics: when a proposal was viewed by the client
proposal_slide_viewsAnalytics: per-slide view tracking
TablePurpose
recruitment_jobsJob postings with title, department, status, salary range, remote policy
recruitment_candidatesCandidate profiles with contact info, pronunciation, source, LinkedIn, resume
recruitment_applicationsApplications linking candidates to jobs with stage tracking
recruitment_application_stage_historyAudit trail of stage transitions
recruitment_pipeline_templatesNamed pipeline configurations for hiring
recruitment_pipeline_stagesOrdered stages within a pipeline template
recruitment_hiring_teamTeam members assigned to a job
recruitment_job_requirementsSkills/requirements for a job posting
recruitment_consentsCandidate GDPR/privacy consent records
recruitment_interviewsScheduled interviews with type, date, location, feedback
recruitment_interview_participantsInterviewers assigned to an interview
recruitment_evaluationsPost-interview evaluations by team members
recruitment_evaluation_scoresScores per criterion within an evaluation
recruitment_scorecard_templatesEvaluation criteria templates for jobs
recruitment_scorecard_criteriaIndividual criteria within a scorecard template
recruitment_email_templatesEmail templates for candidate communication
recruitment_stage_email_rulesAuto-send email rules triggered by stage transitions
recruitment_communicationsSent emails and messages to candidates
TablePurpose
projectsClient projects with company, owner, delivery manager, squad, SLA policy, type, auto-ticket config
project_membersTeam members assigned to a project with role
project_goalsOKR-style goals within a project
project_decisionsKey decisions recorded on a project with context and outcome
project_ai_summariesAI-generated project summaries cached per project
project_reportsPeriodic project status reports with metrics and narrative
project_report_settingsPer-project report configuration (frequency, recipients, sections)
project_setup_templatesReusable project setup templates with phases and tasks
project_setup_template_phasesPhase definitions within a setup template
project_setup_template_tasksTask definitions within a setup template phase
tasksTask/issue tracking scoped to any resource. Includes stage, priority, estimate, approval fields
task_resourcesResource allocations within a task (compute, budget, team)
task_slaSLA tracking per task — response/resolution deadlines, breach flags
task_todosOrdered checklist items within a task
task_watchersUsers watching a task for notifications
sprintsTime-boxed iterations within a project
TablePurpose
roadmapsNamed roadmaps with description and date range
roadmap_itemsIndividual items on a roadmap with status, dates, owner
TablePurpose
budgetsProject budgets with type (fixed/time_and_materials), total, billing details
budget_line_itemsLine items within a budget (service, quantity, rate, amount)
invoicesInvoices with status, amounts, payment terms, Xero sync tracking
invoice_line_itemsLine items within an invoice
invoice_paymentsPayment records against invoices
invoice_mapping_rulesRules for mapping time entries to invoice line items
TablePurpose
time_entriesManual time entries with project, task, duration, billing status
activity_signalsAuto-detected activity signals from connected tools (Memtime-style)
auto_time_draftsAI-generated draft time entries from activity signals
auto_tracking_preferencesPer-user auto-tracking configuration
TablePurpose
allocationsResource bookings linking a user to a project, deal, or recruitment role for a date range
user_weekly_schedulesPer-user weekly availability schedules
user_resourcing_profilesSkills, rates, and capacity data for resourcing
resourcing_suggestionsAI-suggested resource matches for project/role needs
TablePurpose
sla_policiesNamed SLA policy definitions with response/resolution targets
sla_policy_rulesPriority-based rules within an SLA policy
TablePurpose
emailsSynced emails with subject, body, thread tracking, entity matching
email_contactsEmail address ↔ contact resolution
email_sync_statePer-user email sync cursor/token state
inbound_emailsEmails received via the inbound webhook (auto-ticket creation)
TablePurpose
pagesRich-text wiki pages with title, content, icon, cover, parent hierarchy
page_favouritesPer-user bookmarked pages
page_discussionsDiscussion threads on a page
page_commentsComments within a page discussion
page_versionsVersion history snapshots of page content
TablePurpose
meetingsSynced calendar meetings with attendees, transcript, entity matching
meeting_attendeesAttendees per meeting
meeting_transcriptsMeeting transcript content
meeting_action_itemsAction items extracted from meetings
TablePurpose
client_profilesClient tier, health score, assigned DM, dashboard settings. FK to companies
client_onboarding_templatesTemplates for client onboarding journeys
client_onboarding_stagesStages within a client onboarding template
client_onboarding_milestonesMilestones within a client onboarding stage
client_milestone_progressPer-client progress on onboarding milestones
client_health_scoresHistorical health score records per client
client_tier_historyTier scoring history for trend tracking
client_platform_connectionsOAuth/API credentials for connected platforms (Shopify, Meta Ads, etc)
client_metric_snapshotsTime-series key-value metrics (ad_spend, revenue, sessions, etc)
client_campaign_snapshotsDenormalised campaign-level metrics for ad platforms
client_dashboard_insightsAI-generated weekly analysis with health score and recommendations
client_oauth_statesOAuth flow state for client platform connections
client_goalsMetric targets with baseline, current value, and tracking
client_qbrsQuarterly Business Reviews with AI-generated content and portal visibility
client_service_cellsService offering cells within a client relationship
client_success_profilesFinancial year, trading periods, channel mix, growth priorities
client_winsNotable outcomes linked to projects, goals, or meetings
TablePurpose
portal_usersExternal client users with access to the client portal
portal_invitationsPending invitations to the client portal
TablePurpose
notificationsIn-app notifications with type, title, body, action URL, read/dismissed state
notification_preferencesPer-user notification channel preferences
notification_typesRegistered notification type definitions
notification_delivery_logDelivery tracking per notification per channel
push_subscriptionsWeb push subscription endpoints per user
TablePurpose
squad_sessions4P squad kickoff/retro sessions
squad_actionsAction items from squad sessions
squad_leadsSquad leadership assignments
squad_notification_configPer-squad notification routing config
TablePurpose
action_itemsCentralised action items across all sources (meetings, reviews, squads)
action_centre_preferencesPer-user action centre display preferences
TablePurpose
custom_field_definitionsUser-defined field schemas per entity type
custom_field_valuesField values per entity per custom field definition
config_listsNamed configuration lists (dropdown options, categories)
config_list_itemsItems within a configuration list
service_typesService type definitions for projects and budgets
TablePurpose
agent_project_configPer-project agent configuration (enabled features, thresholds)
agent_task_metaAgent metadata per task (session_id, status, last run)
agent_task_runsIndividual agent execution runs with input/output/duration
TablePurpose
relationship_auto_actionsAI-suggested relationship nurturing actions
relationship_messagesDrafted/sent relationship messages
TablePurpose
lead_scan_logLead scanning activity log

The following tables have been removed during migrations:

TableReason
user_external_idsExternal IDs moved to people table columns (xero_employee_id, productive_id) in Phase 3
squad_membersSquad membership now derived from people.squad column, dropped in Phase 7
leave_request_historyRemoved — leave audit trail now tracked via the history table

The platform migrated from user-centric to people-centric data ownership across 7 phases:

  • Phase 1: Employee/HR fields moved from users to people. The users table is now auth-only.
  • Phase 2: Added person_id foreign keys to 8 employee data tables. Auth middleware resolves personId on every request.
  • Phase 3: Eliminated user_external_ids. External ID lookups read directly from people columns.
  • Phase 4: Added getScopedPersonIds() using people.manager_id hierarchy for data scoping.
  • Phase 5: Dropped dual-writes. All data queries use person_id. Manager verification uses people.manager_id.
  • Phase 6: Migrated payroll and leave balance reads to person_id. Replaced squad_members usage with people.manager_id hierarchy.
  • Phase 7: Recreated all 8 data tables to drop user_id columns. person_id is NOT NULL REFERENCES people(id) ON DELETE CASCADE. Dropped squad_members table.

All wrangler commands must run from apps/app/ (where wrangler.toml lives):

Terminal window
# Check pending migrations
npx wrangler d1 migrations list nucleus-db --local
# Apply migrations locally
npx wrangler d1 migrations apply nucleus-db --local
# Apply migrations to production
npx wrangler d1 migrations apply nucleus-db --remote
# Initial local setup (schema + seed)
pnpm db:migrate && pnpm db:seed

db/migrations/ is forward-only. Never drop a *.down.sql (or any other non-forward script) into it — wrangler will auto-apply it as another forward migration. Manual rollbacks live in db/rollbacks/ and are run on demand:

Terminal window
cd apps/app
pnpm wrangler d1 execute nucleus-db --remote \
--file=db/rollbacks/<migration-id>.down.sql

See Database Migrations → Rollbacks for the full convention.