Add Database Persistence
Your app forgets everything on refresh: move state into a real database with working CRUD.
The route
5 steps to Done
- 01
Inventory unpersisted state
Find everything the app forgets - the full list, not samples.
Preview prompt + verify gate ▾ Hide ▴
Audit the app and produce a table of every piece of state that should persist but currently does not: the data (e.g. tasks, profile edits, settings), where it lives now (useState/localStorage/nowhere), what user action creates or changes it, and whether refresh loses it. Test by performing each action then refreshing. Mark each row KEEP-LOCAL (genuinely UI-only) or PERSIST.
- ✓ Each row was refresh-tested
- ✓ Every user-created data type appears
- ✓ PERSIST rows cover all important data
- 02
Design models and endpoints
Give each PERSIST item a schema and API before wiring.
Preview prompt + verify gate ▾ Hide ▴
For every PERSIST row, define: the database model (fields, types, owner id where user-scoped, timestamps) and the endpoints needed (list, create, update, delete as applicable) with request/response shapes. Note which lists need pagination and which data is user-scoped versus global. Then create the models and endpoint skeletons in the codebase.
- ✓ Every PERSIST item has a model
- ✓ User-scoped data includes an owner field
- ✓ Endpoints cover each needed operation
- 03
Wire writes to the backend
Every create/edit/delete must hit the database, not just state.
Preview prompt + verify gate ▾ Hide ▴
Wire all mutating actions to the backend. Requirements: create/edit/delete handlers call their endpoints and await success before confirming in the UI; failures show visible errors and do not fake success; optimistic updates (if used) roll back on failure; after each mutation the data refetches or reconciles. Prove each with a mutation followed by a hard refresh.
- ✓ Each create survives refresh
- ✓ Each edit survives refresh
- ✓ Each delete stays deleted
- ✓ Failures show errors without fake success
- 04
Wire reads with proper states
The UI must load truth from the backend with honest states.
Preview prompt + verify gate ▾ Hide ▴
Wire all reads. Requirements: every list/detail view fetches from the backend on mount; loading skeletons while fetching; empty states with helpful copy when there is no data; error states with retry on fetch failure; remove all hardcoded/demo arrays. User-scoped views must filter by the authenticated user.
- ✓ Hardcoded arrays are gone
- ✓ Loading and empty states render
- ✓ Fetch failure shows retry
- 05
Persistence QA pass
Prove the app remembers everything, everywhere.
Preview prompt + verify gate ▾ Hide ▴
Run persistence QA and report PASS/FAIL with evidence: for each PERSIST item - create, refresh, edit, refresh, delete, refresh; open a second browser/incognito session and verify consistency; kill the network and verify reads/writes show error states instead of silent loss; check user-scoping with two accounts if applicable. Fix all failures and re-run.
- ✓ Full CRUD-with-refresh cycle per entity
- ✓ Second-session consistency verified
- ✓ Offline behavior shows errors, not silent loss
- ✓ All failures fixed