Wire the app to the Supabase backend, replacing localStorage-only

- DiagramRepository (renamed from ProjectRepository, per the
  organized-ideas.md §8 naming decision) now has a Supabase-backed
  implementation as the active repository. LocalStorageDiagramRepository
  stays in the codebase as a reference implementation / fallback, just
  no longer wired in. Only the storage layer's naming changed here --
  the domain type, store, and UI copy still say "Project"; that's a
  separate, larger mechanical rename tracked on its own.
- Minimal email/password auth gate (src/components/auth/LoginScreen.tsx)
  since Supabase RLS requires a real signed-in user to do anything --
  this is NOT the Phase 2 experience (Google SSO, polished signup),
  just enough of the same schema (username + email + password) to make
  the backend foundation usable end to end before that phase exists.
  Respects the hard email-verification gate from config.toml.
- .env.example documents the required VITE_SUPABASE_URL /
  VITE_SUPABASE_ANON_KEY (local dev values, not secrets); .env.local
  has the actual local values and is gitignored.

Verified end-to-end against the local stack: signup creates a
confirmed-pending user, the handle_new_user trigger creates their
profile, sign-in is blocked until confirmed, and a signed-in session
can upsert/read back its own diagram row exactly as the app's
save()/load() do it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
This commit is contained in:
2026-09-05 00:33:28 -05:00
co-authored by Claude Sonnet 5
parent 8cea3f8b92
commit 1ae967c8a4
13 changed files with 411 additions and 20 deletions
+108
View File
@@ -8,6 +8,7 @@
"name": "av-planner",
"version": "0.0.0",
"dependencies": {
"@supabase/supabase-js": "^2.115.0",
"@xyflow/react": "^12.11.5",
"react": "^19.2.8",
"react-dom": "^19.2.8",
@@ -714,6 +715,98 @@
"dev": true,
"license": "MIT"
},
"node_modules/@supabase/auth-js": {
"version": "2.115.0",
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.115.0.tgz",
"integrity": "sha512-YNQlQWm1H0gsXHSY8Jd/xepBhjO0Zhwx04iW17A83/joQ5kFiUin6iPj9s9kZZvupnwLjXVP/diTFiLz2jUbwQ==",
"license": "MIT",
"dependencies": {
"tslib": "2.8.1"
},
"engines": {
"node": ">=22.0.0"
}
},
"node_modules/@supabase/functions-js": {
"version": "2.115.0",
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.115.0.tgz",
"integrity": "sha512-p97V6/YFcdp+zblFDVJaE8f9rGKTNz0PRzyJ2d1w/EYIU5lwidKuc3l/wM+u27ACmAC62albvoGiUGzLPSg7Aw==",
"license": "MIT",
"dependencies": {
"tslib": "2.8.1"
},
"engines": {
"node": ">=22.0.0"
}
},
"node_modules/@supabase/phoenix": {
"version": "0.4.5",
"resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.5.tgz",
"integrity": "sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==",
"license": "MIT"
},
"node_modules/@supabase/postgrest-js": {
"version": "2.115.0",
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.115.0.tgz",
"integrity": "sha512-DdERcurLh5t84pgSywDg2LjLR5le7XAzl52/iQhC7FdboWDqGfDPMfaWJV3MHvhyxSlSNzbpSQG+RiQOBSn/4w==",
"license": "MIT",
"dependencies": {
"tslib": "2.8.1"
},
"engines": {
"node": ">=22.0.0"
}
},
"node_modules/@supabase/realtime-js": {
"version": "2.115.0",
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.115.0.tgz",
"integrity": "sha512-5HyBkvlA/IUV2v8jX3uLTdy15jmTPRVXwXKoxvH2SKw5jZMNURxCxt+VpCEukscXQlY7pUpH8Cy4NH6io4iaRw==",
"license": "MIT",
"dependencies": {
"@supabase/phoenix": "0.4.5",
"tslib": "2.8.1"
},
"engines": {
"node": ">=22.0.0"
}
},
"node_modules/@supabase/storage-js": {
"version": "2.115.0",
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.115.0.tgz",
"integrity": "sha512-dLyIxzbO+MCcKHhcce8rVUCQX1iyqXqQ8ytgkOVYJ7D+Zp0qKylPtQH3hamgxrGSxtDjaw47Urpzw2iK9PsKdA==",
"license": "MIT",
"dependencies": {
"iceberg-js": "^0.8.1",
"tslib": "2.8.1"
},
"engines": {
"node": ">=22.0.0"
}
},
"node_modules/@supabase/supabase-js": {
"version": "2.115.0",
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.115.0.tgz",
"integrity": "sha512-PYJSxtCo37R7tTZW6pAqsxUeSx/dlhA7zn8RzKEUSCqyTxCUhG+iHrDTb04UyVBYbttaUbhwkNTvb8h5HW+uZA==",
"license": "MIT",
"dependencies": {
"@supabase/auth-js": "2.115.0",
"@supabase/functions-js": "2.115.0",
"@supabase/postgrest-js": "2.115.0",
"@supabase/realtime-js": "2.115.0",
"@supabase/storage-js": "2.115.0"
},
"engines": {
"node": ">=22.0.0"
},
"peerDependencies": {
"@opentelemetry/api": ">=1.0.0"
},
"peerDependenciesMeta": {
"@opentelemetry/api": {
"optional": true
}
}
},
"node_modules/@tailwindcss/node": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz",
@@ -1639,6 +1732,15 @@
"dev": true,
"license": "ISC"
},
"node_modules/iceberg-js": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz",
"integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==",
"license": "MIT",
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/jiti": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
@@ -2158,6 +2260,12 @@
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/typescript": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",