Remove Instructions/Feedback + lp_profiles; sync retry, purge, mobile fixes (v0.1.0:104)

Removals (net -570 lines):
- Delete the Instructions and Feedback (feature_requests) pages + backend.
- Retire lp_profiles + investor_type across server, ingest, and seeds; migration
  0008 drops both empty tables (a sanctioned one-off exception to
  never-hard-delete). 0001's lp_profiles ALTER is removed so a fresh DB doesn't
  break the migration chain (live DBs already applied it).

Fixes:
- Email sync: a transient timeout no longer terminally parks a mailbox; the
  scheduler retries 'retrying' each cycle and re-includes errored accounts on an
  hourly backoff, so stuck mailboxes self-heal.
- Mobile Contacts: page through the full directory (server caps 500/page) -- one
  fetch silently truncated at 720, hiding people from the list and from search.
- Mobile email review: clock icon to set a reminder inline; approval cards show
  date/time.

New:
- Admin-only purge of soft-deleted rows (Settings -> Admin; type-to-confirm,
  refuses any row still linked to live data).

Tests: 45/45 (adds test_sync_ready + test_purge_soft_deleted). Reviewer pass
applied (NULL reminders.contact_id on contact purge). Bumped to v0.1.0:104.
This commit is contained in:
Keysat
2026-06-20 20:06:11 -05:00
parent 985cba3c81
commit 1564c087bf
21 changed files with 629 additions and 694 deletions
@@ -0,0 +1,42 @@
-- 0008_drop_retired_tables.down.sql (manual rollback only — never auto-applied)
--
-- Recreates the two dropped tables as EMPTY shells, matching the schema that existed
-- immediately before 0008 (lp_profiles includes the deleted_at column that migration
-- 0001 had added). Data is not restored — both tables were empty when dropped.
CREATE TABLE IF NOT EXISTS lp_profiles (
id TEXT PRIMARY KEY,
contact_id TEXT NOT NULL UNIQUE REFERENCES contacts(id) ON DELETE CASCADE,
commitment_amount REAL DEFAULT 0,
funded_amount REAL DEFAULT 0,
commitment_date TEXT,
fund_name TEXT,
investor_type TEXT,
accredited INTEGER DEFAULT 0,
legal_docs_signed INTEGER DEFAULT 0,
signed_date TEXT,
wire_received INTEGER DEFAULT 0,
wire_date TEXT,
k1_sent INTEGER DEFAULT 0,
preferred_communication TEXT DEFAULT 'email',
notes TEXT,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
deleted_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_lp_profiles_contact ON lp_profiles(contact_id);
CREATE TABLE IF NOT EXISTS feature_requests (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
page TEXT,
category TEXT DEFAULT 'general',
priority TEXT DEFAULT 'medium',
status TEXT DEFAULT 'new',
requested_by TEXT,
requested_by_user_id TEXT REFERENCES users(id),
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_feature_requests_status ON feature_requests(status);
CREATE INDEX IF NOT EXISTS idx_feature_requests_created_at ON feature_requests(created_at);