6.2 KiB
6.2 KiB
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:
- Public SEO website — Landing pages for visitors
- Admin dashboard — Authenticated admin interface for gallery/photo management
- 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:
# 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
# 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:
# 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 Unsplashwg_gallery_sync_state— Sync state tracking
Conventions
Routing
- Use App Router (
app/). Never createpages/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.yamlwhen 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 ofspace-x-*/space-y-*.
Python Scripts
- All Python code lives in
scripts/. - Use virtual environment at
scripts/.venv/. - Keep
.env.localparsing logic consistent with Node.js scripts.
Known Issues / Gotchas
- Next.js 16 uses
proxy.tsinstead ofmiddleware.tsfor route interception. - shadcn/ui base-nova style uses
@base-ui/reactprimitives, not Radix. - ESLint has
react-hooks/set-state-in-effectdisabled (false positives with async data fetching). .venv/andnode_modules/should be ignored by ESLint (configured ineslint.config.mjs).- 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 lintpassespnpm buildsucceeds- 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