feat(pitch-admin): generate magic link + 72h investor data masking
Build pitch-deck / build-push-deploy (push) Successful in 1m30s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 29s
CI / test-python-voice (push) Successful in 29s
CI / test-bqas (push) Successful in 30s
Build pitch-deck / build-push-deploy (push) Successful in 1m30s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 29s
CI / test-python-voice (push) Successful in 29s
CI / test-bqas (push) Successful in 30s
- New POST /api/admin/investors/[id]/generate-link endpoint: creates a magic link without sending email, returns the URL for the admin to copy and share manually (for when email is filtered) - Adds 'Copy Link' button (emerald) to investor list and detail pages; link is copied to clipboard on click - New lib/masking.ts: maskOverdueInvestors() UPDATE that anonymizes email/name/company → revokes sessions 72h after first investor login - first_activity_at recorded on first verify (COALESCE, set once only) - migration 004 adds first_activity_at + data_masked_at columns with partial index; also wired into /api/admin/migrate for one-shot apply - Admin UI shows 'anonymized' badge, expiry countdown, and masked state; Copy Link + Resend are disabled for anonymized investors - verify route returns 410 if data_masked_at is set (belt-and-suspenders alongside the revoked status check) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,12 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
// Finanzplan tables — the ones missing on production
|
||||
const statements = [
|
||||
// 004 — investor data masking columns
|
||||
`ALTER TABLE pitch_investors ADD COLUMN IF NOT EXISTS first_activity_at TIMESTAMPTZ`,
|
||||
`ALTER TABLE pitch_investors ADD COLUMN IF NOT EXISTS data_masked_at TIMESTAMPTZ`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_pitch_investors_mask_check
|
||||
ON pitch_investors (first_activity_at)
|
||||
WHERE first_activity_at IS NOT NULL AND data_masked_at IS NULL`,
|
||||
`CREATE TABLE IF NOT EXISTS fp_scenarios (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL DEFAULT 'Base Case',
|
||||
|
||||
Reference in New Issue
Block a user