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:
@@ -57,10 +57,20 @@ def _json(v) -> str:
|
||||
# ------------------------------------------------------------------ email_accounts
|
||||
|
||||
def list_sync_ready_accounts(conn: sqlite3.Connection) -> list[sqlite3.Row]:
|
||||
# Ready = healthy ('pending'/'active') + transient-failing ('retrying', retried every
|
||||
# cycle for fast recovery) + 'error' accounts whose last attempt was over an hour ago.
|
||||
# The hour-backoff on 'error' means a terminal failure (auth/permanent) self-heals once
|
||||
# the operator fixes it WITHOUT hammering Google, and un-sticks any mailbox parked by the
|
||||
# pre-v0.1.0:104 bug where one timeout dark-listed it forever. (last_synced_at is stamped
|
||||
# on every attempt, success or fail, so it doubles as the last-attempt clock here.)
|
||||
cur = conn.cursor()
|
||||
cur.execute(
|
||||
"SELECT * FROM email_accounts "
|
||||
"WHERE sync_enabled = 1 AND sync_status IN ('pending','active') "
|
||||
"WHERE sync_enabled = 1 AND ("
|
||||
" sync_status IN ('pending','active','retrying') "
|
||||
" OR (sync_status = 'error' AND (last_synced_at IS NULL "
|
||||
" OR last_synced_at < datetime('now','-1 hour')))"
|
||||
") "
|
||||
"ORDER BY last_synced_at IS NOT NULL, last_synced_at"
|
||||
)
|
||||
return cur.fetchall()
|
||||
|
||||
Reference in New Issue
Block a user