first commit
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
# AGENTS.md — Wallora Searcher
|
||||
|
||||
> This file contains agent-focused context about the project: build steps, tests, conventions, and preferences that don't belong in the README.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Wallora Searcher is a Next.js 16 App Router project with three distinct surfaces:
|
||||
|
||||
1. **Public SEO website** — Landing pages for visitors
|
||||
2. **Admin dashboard** — Authenticated admin interface for gallery/photo management
|
||||
3. **Public API** — REST endpoints for external clients
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Framework**: Next.js 16.2.6 (App Router, Turbopack)
|
||||
- **Runtime**: React 19.2.4, React DOM 19.2.4
|
||||
- **Language**: TypeScript 6.0.3
|
||||
- **Styling**: Tailwind CSS v4, OKLCH color system
|
||||
- **UI System**: shadcn/ui (base-nova style, base primitives)
|
||||
- **Auth**: NextAuth.js v5 beta (Credentials provider)
|
||||
- **Database**: Supabase (PostgreSQL)
|
||||
- **Package Manager**: pnpm (monorepo with pnpm-workspace.yaml)
|
||||
- **Lint**: ESLint 9 + eslint-config-next + tailwind-canonical-classes
|
||||
- **Python Scripts**: Selenium + ChromeDriver for browser automation
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
app/
|
||||
(admin)/ # Admin route group
|
||||
admin/
|
||||
(protected)/ # Protected routes (requires auth)
|
||||
dashboard/ # Admin dashboard
|
||||
gallery/ # Gallery photo picker (瀑布流 masonry)
|
||||
login/ # Admin login page
|
||||
(site)/ # Public website route group
|
||||
api/ # API routes
|
||||
admin/
|
||||
gallery-photos/ # GET — paginated gallery photos
|
||||
auth/[...nextauth]/ # NextAuth handlers
|
||||
cron/
|
||||
gallery-photos/ # Cron job for sync
|
||||
|
||||
components/
|
||||
admin/gallery/ # Gallery-specific components
|
||||
ui/ # shadcn/ui components
|
||||
|
||||
lib/
|
||||
auth.ts # NextAuth configuration
|
||||
supabase/
|
||||
service-role.ts # Supabase service role client
|
||||
utils.ts # cn() utility
|
||||
|
||||
server/
|
||||
admin/gallery-sync.ts # Gallery sync logic
|
||||
api/unsplash.ts # Unsplash API client
|
||||
|
||||
scripts/
|
||||
sync-gallery-photos.py # Python script: Selenium Chrome → Unsplash → Supabase
|
||||
requirements.txt # Python deps: selenium, webdriver-manager, supabase, python-dotenv
|
||||
.venv/ # Python virtual environment
|
||||
|
||||
types/
|
||||
admin/gallery.ts # GalleryPhoto, GalleryPagination types
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Required in `.env.local`:
|
||||
|
||||
```bash
|
||||
# NextAuth
|
||||
AUTH_SECRET=<random-string>
|
||||
|
||||
# Supabase
|
||||
NEXT_PUBLIC_SUPABASE_URL=http://your-supabase-url
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=<anon-key>
|
||||
SUPABASE_SERVICE_ROLE_KEY=<service-role-key>
|
||||
|
||||
# Admin Credentials
|
||||
ADMIN_EMAIL=admin@example.com
|
||||
ADMIN_PASSWORD=yourpassword
|
||||
|
||||
# Cron (optional)
|
||||
CRON_SECRET=<random-string>
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
```bash
|
||||
# Development
|
||||
pnpm dev # Start dev server at localhost:3000
|
||||
|
||||
# Build & Lint
|
||||
pnpm build # Production build
|
||||
pnpm lint # ESLint check
|
||||
pnpm lint:fix # ESLint with auto-fix
|
||||
|
||||
# Format
|
||||
pnpm format # Prettier format all
|
||||
pnpm format:check # Prettier check
|
||||
|
||||
# Gallery Sync
|
||||
pnpm sync:gallery # Node.js sync script (legacy)
|
||||
|
||||
# Python Sync
|
||||
python scripts/sync-gallery-photos.py --max-pages=10 --topic=wallpapers
|
||||
```
|
||||
|
||||
## Python Sync Script
|
||||
|
||||
The Python script controls a real Chrome browser via Selenium to fetch Unsplash data:
|
||||
|
||||
```bash
|
||||
# Setup (first time)
|
||||
cd scripts
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Run
|
||||
python scripts/sync-gallery-photos.py --max-pages=5 --topic=wallpapers
|
||||
```
|
||||
|
||||
**Features**:
|
||||
|
||||
- `--max-pages`: Required. Pages to fetch (1..N)
|
||||
- `--topic`: Optional. Unsplash topic slug (e.g. `wallpapers`, `3d-renders`, `nature`)
|
||||
- `--per-page`: Optional. Default 20
|
||||
- `--headless/--no-headless`: Default headless
|
||||
- `--delay`: Base delay between pages (default 3s, +0-2s random)
|
||||
|
||||
## Admin Authentication
|
||||
|
||||
- Uses NextAuth.js v5 beta with Credentials provider
|
||||
- Login page: `/admin/login`
|
||||
- Protected routes: `/admin/(protected)/*`
|
||||
- Route protection via `proxy.ts` (Next.js 16 middleware convention)
|
||||
- Session stored as JWT
|
||||
|
||||
## Gallery Page Features
|
||||
|
||||
- **Masonry Layout**: 4 independent columns with greedy shortest-column algorithm
|
||||
- **Infinite Scroll**: IntersectionObserver-based pagination
|
||||
- **Animations**: Entrance fade + translateY + scale, hover scale + shadow, lightbox transitions
|
||||
- **Lightbox**: Click to view full image with metadata overlay
|
||||
- **API**: `/api/admin/gallery-photos?page=N&per_page=24`
|
||||
|
||||
## Supabase Tables
|
||||
|
||||
- `wg_gallery_photos` — Photo data from Unsplash
|
||||
- `wg_gallery_sync_state` — Sync state tracking
|
||||
|
||||
## Conventions
|
||||
|
||||
### Routing
|
||||
|
||||
- Use App Router (`app/`). Never create `pages/` unless explicitly requested.
|
||||
- Route groups: `(admin)` for admin, `(site)` for public.
|
||||
- Protected routes nested under `(protected)`.
|
||||
|
||||
### Components
|
||||
|
||||
- React Server Components by default.
|
||||
- Add `"use client"` only for interactivity (state, effects, browser APIs).
|
||||
- shadcn/ui as base. Use `npx shadcn@latest add <component>` to install.
|
||||
- Prefer Tailwind utility classes and CSS variables over custom CSS.
|
||||
|
||||
### API Design
|
||||
|
||||
- Separate JWT auth (public API) and session auth (admin) as different trust boundaries.
|
||||
- Update `swagger.yaml` when API contracts change.
|
||||
|
||||
### Styling
|
||||
|
||||
- Use semantic colors (`bg-primary`, `text-muted-foreground`).
|
||||
- No raw colors like `bg-blue-500`.
|
||||
- Use `size-*` for equal width/height.
|
||||
- Use `gap-*` instead of `space-x-*` / `space-y-*`.
|
||||
|
||||
### Python Scripts
|
||||
|
||||
- All Python code lives in `scripts/`.
|
||||
- Use virtual environment at `scripts/.venv/`.
|
||||
- Keep `.env.local` parsing logic consistent with Node.js scripts.
|
||||
|
||||
## Known Issues / Gotchas
|
||||
|
||||
1. **Next.js 16 uses `proxy.ts` instead of `middleware.ts`** for route interception.
|
||||
2. **shadcn/ui base-nova style** uses `@base-ui/react` primitives, not Radix.
|
||||
3. **ESLint** has `react-hooks/set-state-in-effect` disabled (false positives with async data fetching).
|
||||
4. **`.venv/` and `node_modules/`** should be ignored by ESLint (configured in `eslint.config.mjs`).
|
||||
5. **GalleryGrid** uses `<img>` not Next.js `<Image>` because external Unsplash URLs don't work well with the Image optimizer without domain configuration.
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
After making changes:
|
||||
|
||||
- [ ] `pnpm lint` passes
|
||||
- [ ] `pnpm build` succeeds
|
||||
- [ ] For visual changes: verify at `http://localhost:3000`
|
||||
- [ ] For admin changes: verify login/logout flow
|
||||
- [ ] For API changes: test with curl or browser
|
||||
|
||||
## Contact
|
||||
|
||||
- Admin: luoyw1106703846@gmail.com
|
||||
Reference in New Issue
Block a user