docs: Update architecture for supabase
test: Add tests for auth workflow
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
# Session Handoff: Local Dev Setup & Ionic Module Migration
|
||||
**Date:** 2026-03-26
|
||||
**Session Duration:** ~1.5 hours
|
||||
**Session Focus:** Initialize local Supabase DB, get app loading in browser, fix Ionic/Nuxt router integration using the official @nuxtjs/ionic module
|
||||
**Context Usage at Handoff:** Medium-high
|
||||
|
||||
## What Was Accomplished
|
||||
|
||||
1. **Node upgraded to 22** — added `engines: { node: ">=22" }` to `package.json`, created `.nvmrc` with value `22`
|
||||
2. **Local Supabase initialized** — schema applied via migration; DB running at `postgresql://postgres:postgres@127.0.0.1:54322/postgres`
|
||||
3. **`.env` switched to local Supabase** — URL `http://127.0.0.1:54321`, publishable key `sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH`
|
||||
4. **Schema migration created** — `supabase/migrations/20260325000000_initial_schema.sql` (reordered from `schema.sql`: all tables first, then RLS policies, then trigger — original order caused `members` not found error during `boats` policy creation)
|
||||
5. **`yarn dev` running** — app responds HTTP 200 at `http://localhost:3000`
|
||||
6. **Migrated to `@nuxtjs/ionic`** — replaced manual IonicVue plugin + navManager/viewStacks shims (250 lines) with the official Nuxt Ionic module
|
||||
|
||||
## Exact State of Work in Progress
|
||||
|
||||
- App loads and serves HTTP 200; browser rendering not fully verified (IonRouterOutlet may still need testing)
|
||||
- No pages beyond skeleton `index.vue`, `login.vue`, `auth/callback.vue` — all page content is TODO
|
||||
- Auth flow not implemented (`login.vue` is still a skeleton)
|
||||
|
||||
## Decisions Made This Session
|
||||
|
||||
- USE `@nuxtjs/ionic` module INSTEAD OF manual `@ionic/vue` plugin BECAUSE it is the idiomatic Nuxt+Ionic integration; provides `@ionic/vue-router` correctly (which supplies `navManager` and `viewStacks` that `IonRouterOutlet` requires) — STATUS: confirmed
|
||||
- USE local Supabase via CLI INSTEAD OF remote project for development BECAUSE user decision — STATUS: confirmed
|
||||
- DOCKER_HOST must be set to `unix:///run/user/1000/podman/podman.sock` for all `npx supabase` commands on this machine — STATUS: confirmed
|
||||
- USE `supabase db reset` to apply schema changes locally — STATUS: confirmed
|
||||
- `mode: 'md'` moved from plugin to `ionic.config` in `nuxt.config.ts` — STATUS: confirmed
|
||||
|
||||
## Key Numbers Generated or Discovered This Session
|
||||
|
||||
- Local Supabase API port: 54321
|
||||
- Local Supabase DB port: 54322
|
||||
- Local Supabase Studio port: 54323
|
||||
- Local Supabase Mailpit port: 54324
|
||||
- Migration file timestamp: 20260325000000
|
||||
- 6 tables in schema (unchanged from prior session)
|
||||
- `@nuxtjs/ionic` version installed: 1.0.2
|
||||
|
||||
## Files Created or Modified
|
||||
|
||||
| File Path | Action | Description |
|
||||
|-----------|--------|-------------|
|
||||
| `.nvmrc` | Created | Pins Node to version 22 |
|
||||
| `package.json` | Modified | Added `engines: { node: ">=22" }`, added `@nuxtjs/ionic`, `@ionic/vue-router` |
|
||||
| `supabase/migrations/20260325000000_initial_schema.sql` | Created | Initial schema migration (reordered from schema.sql) |
|
||||
| `.env` | Modified | Switched from remote Supabase to local (URL + publishable key) |
|
||||
| `nuxt.config.ts` | Modified | Added `@nuxtjs/ionic` module, `ionic: { css: { utilities: true }, config: { mode: 'md' } }`, removed manual Ionic CSS imports and CDN link, removed vite optimizeDeps for @ionic/vue |
|
||||
| `app/plugins/ionic.client.ts` | Deleted | Replaced by @nuxtjs/ionic module |
|
||||
|
||||
## What the NEXT Session Should Do
|
||||
|
||||
1. **First**: Verify app renders correctly in browser (check for Vue/Ionic console errors, confirm IonRouterOutlet works)
|
||||
2. **Then**: Implement `app/pages/login.vue` — OTP flow: email input → `sendOtp()` → token input → `verifyOtp()` → redirect to `/`
|
||||
3. **Then**: Implement `app/pages/auth/callback.vue` — handle magic link redirect (Supabase sets session from URL hash)
|
||||
4. **Then**: Test auth flow end-to-end: send OTP via Mailpit (http://127.0.0.1:54324), verify, confirm member row created in `members` table
|
||||
5. **Then**: Implement `app/pages/index.vue` — home page shell showing boat list or welcome state
|
||||
6. **Then**: Run `npx supabase gen types typescript --local > app/types/supabase.ts` to replace placeholder types and remove `as any` casts in stores
|
||||
|
||||
## Open Questions Requiring User Input
|
||||
|
||||
- [ ] Should `login.vue` support magic link (email link) in addition to OTP, or OTP-only? — impacts login page UI
|
||||
- [ ] Scheduling refactor design still deferred — should it be designed before or after auth + boat pages?
|
||||
|
||||
## Assumptions That Need Validation
|
||||
|
||||
- ASSUMED: `@nuxtjs/ionic` module correctly wires `@ionic/vue-router` so `IonRouterOutlet` has `navManager` and `viewStacks` — validate by loading app in browser and checking for no inject warnings
|
||||
- ASSUMED: `handle_new_user()` trigger fires on magic link / OTP first sign-in — validate by signing in a test user and checking `members` table
|
||||
- ASSUMED: `useIonRouter()` composable (from `@nuxtjs/ionic` auto-imports) should be used instead of `useRouter()` — validate against module docs; update `app/stores/auth.ts` if needed
|
||||
|
||||
## What NOT to Re-Read
|
||||
|
||||
- `docs/archive/handoffs/handoff-2026-03-25-initial-setup.md` — superseded
|
||||
- `docs/archive/handoffs/handoff-2026-03-25-project-scaffold.md` — superseded
|
||||
|
||||
## Files to Load Next Session
|
||||
|
||||
- `app/pages/login.vue` — primary implementation target
|
||||
- `app/stores/auth.ts` — has `sendOtp()`, `verifyOtp()`, `sendMagicLink()` — needed for login page
|
||||
- `app/pages/auth/callback.vue` — second implementation target
|
||||
- `app/types/supabase.ts` — after regenerating with `--local` flag
|
||||
|
||||
## Dev Environment Reference
|
||||
|
||||
```
|
||||
# Start local Supabase (already running, but if needed):
|
||||
DOCKER_HOST=unix:///run/user/1000/podman/podman.sock npx supabase start
|
||||
|
||||
# Check status / get keys:
|
||||
DOCKER_HOST=unix:///run/user/1000/podman/podman.sock npx supabase status
|
||||
|
||||
# Apply schema changes:
|
||||
DOCKER_HOST=unix:///run/user/1000/podman/podman.sock npx supabase db reset
|
||||
|
||||
# Start app:
|
||||
yarn dev
|
||||
|
||||
# Mailpit (view OTP emails):
|
||||
http://127.0.0.1:54324
|
||||
|
||||
# Supabase Studio:
|
||||
http://127.0.0.1:54323
|
||||
```
|
||||
78
docs/summaries/handoff-2026-04-12-splash-and-login.md
Normal file
78
docs/summaries/handoff-2026-04-12-splash-and-login.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Session Handoff: Splash Page & Magic Link Login
|
||||
**Date:** 2026-04-12
|
||||
**Session Duration:** ~30 minutes
|
||||
**Session Focus:** Implement unauthenticated splash page with logo and login button; implement magic link login page
|
||||
**Context Usage at Handoff:** Low
|
||||
|
||||
## What Was Accomplished
|
||||
|
||||
1. **Splash page implemented** → `app/pages/index.vue` — unauthenticated users see centered logo + "Log In" button; authenticated users see home content with header/menu
|
||||
2. **Login page implemented** → `app/pages/login.vue` — email input, sends magic link via `auth.sendMagicLink()`, shows confirmation state with mail icon after send
|
||||
3. **Auth middleware updated** → `app/middleware/auth.ts` — added `/` to public routes; unauthenticated users redirected to `/` (not `/login`)
|
||||
4. **Supabase redirect config updated** → `nuxt.config.ts` — `login` redirect changed from `/login` to `/`; `/` added to `exclude` list
|
||||
|
||||
## Exact State of Work in Progress
|
||||
|
||||
- Splash + login pages coded but not yet tested end-to-end against local Supabase
|
||||
- `auth/callback.vue` still a skeleton — magic link redirect will land there; not yet implemented
|
||||
|
||||
## Decisions Made This Session
|
||||
|
||||
- USE `/` as the unauthenticated landing route INSTEAD OF `/login` BECAUSE the splash/logo page IS the unauthenticated entry point; `/login` is a detail page reached from it — STATUS: confirmed
|
||||
- MAGIC LINK ONLY on login page (not OTP) BECAUSE user stated "sends a magic link" — STATUS: confirmed; OTP flow (`sendOtp` + `verifyOtp`) exists in auth store but unused by login page
|
||||
|
||||
## Key Numbers Generated or Discovered This Session
|
||||
|
||||
- Logo file: `public/oysqn_logo.png` (confirmed present)
|
||||
- Max logo display width: 280px (CSS)
|
||||
- Max login form width: 400px (CSS)
|
||||
|
||||
## Files Created or Modified
|
||||
|
||||
| File Path | Action | Description |
|
||||
|-----------|--------|-------------|
|
||||
| `app/pages/index.vue` | Modified | Splash (unauthenticated) + home (authenticated) in single page, toggled by `useSupabaseUser()` |
|
||||
| `app/pages/login.vue` | Modified | Email input → `sendMagicLink()` → confirmation state; uses `IonBackButton` to return to splash |
|
||||
| `app/middleware/auth.ts` | Modified | Added `/` to public routes; redirects unauthenticated to `/` |
|
||||
| `nuxt.config.ts` | Modified | `supabase.redirectOptions.login` = `/`; added `/` to `exclude` |
|
||||
|
||||
## What the NEXT Session Should Do
|
||||
|
||||
1. **First**: Test the auth flow end-to-end: load app → confirm splash shows logo + Login button → tap Login → enter email → check Mailpit (http://127.0.0.1:54324) for magic link → click link → confirm redirect to `/auth/callback` → confirm redirect to `/` (home state)
|
||||
2. **Then**: Implement `app/pages/auth/callback.vue` — handle magic link redirect (Supabase sets session from URL hash; page should show a spinner, then navigate to `/`)
|
||||
3. **Then**: Verify `useAuthStore` is auto-imported by Pinia Nuxt module (currently explicitly imported in `login.vue` with `import { useAuthStore } from '~/stores/auth'` — check if explicit import is still needed or if auto-import covers it)
|
||||
4. **Then**: Run `npx supabase gen types typescript --local > app/types/supabase.ts` to replace placeholder types
|
||||
5. **Then**: Implement `app/pages/index.vue` home content (authenticated state) — boat list or welcome state
|
||||
|
||||
## Open Questions Requiring User Input
|
||||
|
||||
- [ ] Should the login page also support OTP (enter token from email) as a fallback, or magic link only? — `sendOtp` + `verifyOtp` exist in auth store but unused — impacts login page UI
|
||||
- [ ] Should `auth/callback.vue` redirect to a specific page after login (e.g., boats list) or always to `/`? — impacts callback implementation
|
||||
|
||||
## Assumptions That Need Validation
|
||||
|
||||
- ASSUMED: `@nuxtjs/ionic` + `@pinia/nuxt` auto-imports `useAuthStore` — currently explicitly imported; validate by removing explicit import and testing
|
||||
- ASSUMED: `sendMagicLink()` in auth store correctly sets `emailRedirectTo` to `/auth/callback` — validate by clicking the email link and checking where it lands
|
||||
- ASSUMED: `IonRouterOutlet` handles `router-link` on `IonButton` correctly — validate by tapping Login button in browser
|
||||
|
||||
## Files to Load Next Session
|
||||
|
||||
- `app/pages/auth/callback.vue` — primary implementation target
|
||||
- `app/pages/index.vue` — may need home content (authenticated state) built out
|
||||
- `app/stores/auth.ts` — reference for `sendMagicLink` signature and redirect URL
|
||||
|
||||
## Dev Environment Reference
|
||||
|
||||
```
|
||||
# Start local Supabase (if not running):
|
||||
DOCKER_HOST=unix:///run/user/1000/podman/podman.sock npx supabase start
|
||||
|
||||
# Start app:
|
||||
yarn dev
|
||||
|
||||
# Mailpit (view magic link emails):
|
||||
http://127.0.0.1:54324
|
||||
|
||||
# Supabase Studio:
|
||||
http://127.0.0.1:54323
|
||||
```
|
||||
Reference in New Issue
Block a user