# 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`