Files
2026-06-06 00:49:07 +08:00

110 lines
7.1 KiB
Markdown

# Wallora Searcher Project Reference
## Snapshot
- Root: `/Users/luoyangwei/Documents/workspace/wallora.top/searcher`
- Package: `searcher`
- Framework: Next.js `16.2.6` with App Router
- React: `19.2.4`
- Styling: Tailwind CSS v4 via `@import "tailwindcss";`
- TypeScript: enabled
- Package manager: `pnpm`
- Git: this directory is not currently a Git repository
- Intended UI system: shadcn/ui
- Intended data store: Supabase with `wg_` table prefixes for project-owned tables
- Intended image store: Aliyun OSS
- Intended auth foundation: NextAuth plus JWT authorization for public APIs
- Intended API documentation: `swagger.yaml`
## Important Files
- `app/layout.tsx`: root HTML shell, metadata, body layout classes, CSS-variable font tokens
- `app/(site)/page.tsx`: public website home page
- `app/(admin)/admin/login/page.tsx`: public admin login page
- `app/(admin)/admin/(protected)/...`: admin pages that require a NextAuth session
- `app/(admin)/admin/(protected)/gallery/page.tsx`: admin gallery picker with picked/color filters
- `app/(admin)/admin/(protected)/collections/page.tsx`: admin collections CRUD surface
- `components/admin/collections/CollectionsManager.tsx`: create/edit/delete published collections from picked photos
- `app/api/admin/gallery-photos/route.ts`: protected admin gallery list and pick/unpick endpoint
- `app/api/admin/photo-collections/route.ts`: protected admin collection list/create API
- `app/api/admin/photo-collections/[id]/route.ts`: protected admin collection read/update/delete API
- `app/api/v1/gallery/photos/route.ts`: public picked-photo API for waterfall pagination
- `app/api/v1/gallery/photos/[id]/route.ts`: public picked-photo detail API plus favorite/unfavorite shortcut
- `app/api/v1/gallery/collections/route.ts`: public published collection list API
- `app/api/v1/gallery/collections/[slug]/route.ts`: public published collection detail API with paginated photos
- `app/api/v1/auth/register/route.ts`: app user email/password registration
- `app/api/v1/auth/login/route.ts`: app user email/password login and Bearer JWT issuance
- `app/api/v1/users/me/route.ts`: current app user profile from Bearer JWT
- `app/api/v1/users/me/favorites/...`: app user favorites list/add/remove APIs
- `app/api/v1/users/me/settings/route.ts`: app user preferences and download preferences APIs
- `app/(admin)/admin/(protected)/users/page.tsx`: protected admin app user list
- `components/admin/users/UsersManager.tsx`: admin app user list with enable/disable actions
- `app/api/admin/app-users/[id]/route.ts`: protected admin app user status update API
- `app/api/cron/gallery-photos/route.ts`: protected gallery sync trigger endpoint
- `app/globals.css`: Tailwind import, CSS variables for background/foreground, font theme tokens
- `package.json`: scripts and dependencies
- `next.config.ts`: Next.js config
- `public/`: starter SVG assets from create-next-app
- `swagger.yaml`: create or update when public API contracts are introduced or changed
- `supabase/migrations/`: SQL migration scripts, including `wg_` gallery tables
- `scripts/sync-gallery-photos.mjs`: one-shot gallery sync script for server cron/process managers
## Commands
```bash
pnpm dev
pnpm lint
pnpm build
pnpm start
pnpm sync:gallery
```
Use `pnpm format:check`, `pnpm lint`, and `pnpm build` for verification. Use `pnpm sync:gallery` only when intentionally touching the real Supabase database.
## Current Baseline Notes
- The public home page still contains create-next-app starter content unless updated later.
- The admin dashboard uses shadcn `dashboard-01` under `/admin/dashboard`.
- The admin login page uses shadcn `login-03` and NextAuth credentials under `/admin/login`.
- The admin gallery supports picked/unpicked filters, color-family filters, pick/unpick actions, and OSS mirror status.
- The admin collections page supports create, edit, delete, publish/draft status, cover selection, and selecting photos from picked photos.
- Public photo consumption should use `/api/v1/gallery/photos`, which returns picked photos only.
- App photo detail should use `/api/v1/gallery/photos/{id}`. Public callers can omit auth; authenticated callers receive `isFavorited` and can `POST`/`DELETE` the same route to favorite/unfavorite.
- Public collection consumption should use `/api/v1/gallery/collections` and `/api/v1/gallery/collections/{slug}`; collection photos are picked photos only.
- App users register and login with email/password via `/api/v1/auth/register` and `/api/v1/auth/login`; the returned Bearer JWT is for public app APIs only.
- App user favorites and settings live under `/api/v1/users/me/...`.
- Admins can review app users and enable/disable accounts under `/admin/users`.
- Bare `/dashboard` and `/login` routes should stay absent; admin templates belong under `/admin`.
## Coding Conventions
- Keep components typed with TypeScript and follow existing double-quote import style.
- Prefer server components unless client behavior is necessary.
- Put global tokens and truly global styles in `app/globals.css`; keep page-specific styling near components with Tailwind classes.
- Keep font tokens in CSS variables; avoid `next/font/google` unless the deployment environment can reliably fetch Google Fonts during build.
- Avoid broad dependency additions for small UI tasks; use the platform and existing stack first.
- Use `pnpm dlx shadcn@latest ...` for shadcn CLI tasks.
- Verify current Supabase, NextAuth, and Aliyun OSS APIs before implementing auth-sensitive or storage-sensitive behavior.
- For database objects created by this app, use the `wg_` prefix, e.g. `wg_gallery_photos`.
- Do not read or print secrets from `.env.local`; report only whether required variables are present.
- This project is not targeting Vercel. Prefer server cron, process manager jobs, or external scheduler calls over `vercel.json` cron config.
## Design Conventions
- Replace starter content with domain-specific product UI when asked to build the app experience.
- Keep cards at `8px` radius or less unless a future design system says otherwise.
- Do not nest cards inside cards.
- Avoid one-note palettes and generic purple/blue gradient-heavy layouts.
- Make text fit inside controls and panels at mobile and desktop widths.
## Architecture Summary
- Public API: available to external users; use JWT login/authorization and document routes in `swagger.yaml`.
- Admin: account/password login; use NextAuth sessions to persist login state and gate admin features.
- Public website: open internet access; optimize for SEO, metadata, crawlability, and performance.
- Supabase stores application data with `wg_` table prefixes; Aliyun OSS stores image files while Supabase stores image metadata.
- Gallery photo ingestion writes to `wg_gallery_photos` and tracks progress in `wg_gallery_sync_state`.
- Picked photo metadata lives on `wg_gallery_photos` via `is_picked`, `picked_at`, `picked_by`, and `oss_*` fields.
- Collections live in `wg_photo_collections` and `wg_photo_collection_items`.
- App users/favorites/settings live in `wg_app_users`, `wg_user_favorites`, and `wg_user_settings`; identity fields include email now and schema placeholders for phone/WeChat later.