feat: cloud upload - multi-image, category select, capture time, progress bar

This commit is contained in:
2026-05-21 01:14:19 +08:00
parent d4b07fba58
commit cb2581afb2
5 changed files with 650 additions and 6 deletions
+51
View File
@@ -0,0 +1,51 @@
# AGENTS.md
## Commands
- `npm run dev` — Vite dev server with HMR
- `npm run build``vue-tsc -b && vite build` (typecheck must pass or build aborts)
- `npx vue-tsc -b` — standalone typecheck (no script in package.json)
- No linter, formatter, or test runner exists
## Architecture
- **Vue 3 + Vite + Tailwind CSS + Vue Router + Pinia + Supabase + AMap (高德地图)**
- Path alias `@/``src/` (configured in both `vite.config.ts` and `tsconfig.app.json`)
- Supabase client singleton at `src/lib/supabase.ts` — throws at import if env vars missing
- AMap loaded lazily via `src/lib/amap.ts` with hand-rolled type declarations in `src/types/amap.d.ts`
- UI language is Chinese (zh-CN)
## Auth Flow (non-obvious)
- **`main.ts` races on pathname**: `/auth/confirm` mounts the app immediately without calling `authStore.initialize()`. All other routes wait for auth initialization before mounting. If you add new routes that need to bypass auth init, add them to the `if` check in `main.ts`.
- **AuthConfirmView uses a separate Supabase client**: It creates a temporary `createClient()` to call `setSession()` then `signOut()`, so the main auth store never sees a logged-in state. Do NOT consolidate with the singleton — the singleton isn't initialized at confirmation time.
- **Login sets `user.value` explicitly**: `login()` extracts `data.user` from `signInWithPassword` response and assigns it to the store directly, rather than relying on `onAuthStateChange`.
- **Profile is auto-created by DB trigger** (`handle_new_user` on `auth.users`), not by the frontend. The trigger uses `SECURITY DEFINER` with `SET search_path = public`.
- Auth error messages are translated to Chinese in the store.
## Supabase
- Env var is `VITE_SUPABASE_PUBLISHABLE_KEY` (not `VITE_SUPABASE_ANON_KEY`), using Supabase's `sb_publishable_` key format.
- All tables have RLS enabled. Check `plan.md` section 10 for the full schema and RLS policies.
- Storage bucket `clouds` is public read, authenticated upload.
- Profile `role` field (`user`/`admin`) controls admin access — checked in route guard, not in JWT metadata.
## MVP Constraints (from plan.md)
- No Supabase Realtime — refresh-based loading
- No OAuth — email/password only, email confirmation required
- No AI cloud identification — manual type selection
- AMap only (China-focused), no Mapbox fallback yet
## Environment Variables
Required now (app won't start without):
- `VITE_SUPABASE_URL`
- `VITE_SUPABASE_PUBLISHABLE_KEY`
Required for map features (views are stubs without):
- `VITE_AMAP_KEY`
- `VITE_AMAP_SECRET`
Future (Supabase Dashboard only, not in `.env`):
- `OPENAI_API_KEY`, `OPENWEATHERMAP_API_KEY`