Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Status: PENDING - To be completed before migration deployment
Created: 2026-02-08
Target Date: 2026-02-15

Migration 1: hr_references Token Hashing ✓ PREP COMPLETE

Code Changes Needed

  • Edge Function: supabase/functions/hr-reference-submit/index.ts
    • Implement hashToken(token: string, salt: Uint8Array) function
    • Implement validateToken(presentedToken: string, storedHash: string) function
    • Generate 16-byte salt for new tokens: crypto.getRandomValues(new Uint8Array(16))
    • Store Base64(salt + hash) in access_token_hash column
    • Maintain backward compatibility: validate plaintext tokens during transition
  • Hook: src/cores/hr/hooks/useReferences.ts
    • Update token generation to use edge function for hashing
    • Log all token validations for audit
  • Tests: tests/unit/hr/useReferences.test.ts
    • Test token hashing with various inputs
    • Test backward compatibility with plaintext tokens
    • Test salt uniqueness per token

Validation Tests

# Run before migration
npm run test:unit -- tests/unit/hr/useReferences.test.ts
npm run test:e2e -- tests/e2e/hr/reference-flow.spec.ts

Estimated Effort

  • Development: 2-3 hours
  • Testing: 1-2 hours
  • Validation: 1 hour

Migration 2: hr_candidate_portal_sessions Organization Isolation ✓ PREP COMPLETE

Code Changes Needed

  • Hook: src/cores/hr/hooks/useCandidatePortalSession.ts
    • Update createSession() to require organizationId parameter
    • Pass organization_id to INSERT queries
    • Update fetchSession() to include organization_id in response
  • Components: Anywhere creating portal sessions
    • Search for createSession(candidateId) calls
    • Update to createSession(candidateId, organizationId)
    • Extract organization from auth context or route params
  • Edge Functions: Any portal session creation
    • Validate organization_id from JWT claims
    • Ensure sessions cannot be created for other organizations
  • RLS Policies: Verify in Supabase dashboard
    • Test org-scoped isolation
    • Verify cross-org access is blocked
# Find all useCandidatePortalSession usages
grep -r "createSession" src/cores/hr --include="*.ts" --include="*.tsx"

Validation Tests

npm run test:rls -- tests/rls/hr-candidate-portal-sessions.rls.test.ts
npm run test:unit -- tests/unit/hr/useCandidatePortalSession.test.ts

Estimated Effort

  • Development: 1-2 hours
  • Testing: 1-2 hours
  • Validation: 1 hour

Migration 3: hr_job_board_integrations Credential Encryption ✓ PREP COMPLETE

Code Changes Needed

  • Hook: src/cores/hr/hooks/useJobBoardIntegrations.ts
    • Update SELECT queries to fetch credential:pf_credentials!credential_id(*)
    • Add fallback logic to read from plaintext columns during transition
    • Create new records with credential_id instead of plaintext fields
    • Add migration helper to move existing credentials
  • Edge Functions: Any that use job board credentials
    • Fetch credentials from pf_credentials table
    • Decrypt via dedicated decryption function
    • Remove hardcoded plaintext credential usage
  • Migration Script: Create credential migration tool
    • Script: scripts/migrate-job-board-credentials.ts
    • Verify all plaintext credentials moved to pf_credentials
    • Log migrations in pf_credential_migrations table
  • Tests: Update to use encrypted credentials
    • Mock pf_credentials table instead of plaintext columns
    • Test credential decryption in edge functions

Transition Support Matrix

ScenarioBefore MigrationAfter MigrationFallback
New integrationplaintextcredential_idN/A
Old integration (no change)plaintextcredential_id OR plaintextplaintext
Updated integrationplaintextcredential_idplaintext if missing

Validation Tests

npm run test:unit -- tests/unit/hr/useJobBoardIntegrations.test.ts
npm run test:e2e -- tests/e2e/hr/job-board-sync.spec.ts

Estimated Effort

  • Development: 3-4 hours
  • Testing: 2-3 hours
  • Validation: 1-2 hours
  • Data migration: 0.5-1 hour

Database Type Updates

After all migrations are applied (by DevOps), run:
# Regenerate types from live database
npx supabase gen types typescript --local > src/integrations/supabase/types.ts

# Verify TypeScript compilation
npm run typecheck
Files that will need type updates:
  • src/cores/hr/hooks/useReferences.ts
  • src/cores/hr/hooks/useCandidatePortalSession.ts
  • src/cores/hr/hooks/useJobBoardIntegrations.ts
  • Components using these hooks

Summary: Code Readiness Status

ComponentStatusEst. HoursPriority
Token Hashing (Migration 1)PENDING4-5 hrsHIGH
Organization Isolation (Migration 2)PENDING3-4 hrsHIGH
Credential Encryption (Migration 3)PENDING6-7 hrsMEDIUM
Type UpdatesPENDING1-2 hrsHIGH
TOTAL14-18 hrs

Timeline Recommendation

  1. Feb 8-10: Implement code changes (14-18 hours)
  2. Feb 10-12: Review & test (4-6 hours)
  3. Feb 12-14: Staging run (2-3 hours)
  4. Feb 15: Production migration (1-2 hours with on-call)

Sign-Off

  • All code changes reviewed by tech lead
  • All tests passing (unit, RLS, E2E)
  • Staging migration successful
  • Team briefed on rollback procedures
  • On-call schedule confirmed for migration night