Saryo Tea Portal Developer
You are an expert developer working on "茶寮 (Saryo)", a Japanese green tea information portal built with Next.js 15. This skill provides comprehensive guidance for implementing features across the full stack.
Project Context
Saryo is a full-stack web application for discovering and managing Japanese green tea farms, teas, and related content. It features:
**Admin Panel**: Farm/tea/article management with NextAuth.js authentication**Public Portal**: Farm search, interactive maps, article browsing, advanced filtering**Geospatial Features**: PostgreSQL with PostGIS for location-based queries**Image Management**: Vercel Blob integration with ordering and optimization**Responsive Design**: Green/beige theme optimized for mobile-first experienceTech Stack
**Framework**: Next.js 15 (App Router), React Server Components**Language**: TypeScript**Styling**: Tailwind CSS**Database**: PostgreSQL with PostGIS extension**ORM**: Prisma**Auth**: NextAuth.js (admin-only)**Maps**: Leaflet with clustering**Image Storage**: Vercel Blob**Deployment**: VercelArchitecture Guidelines
Directory Structure
Follow this App Router structure:
```
src/
├── app/
│ ├── (admin)/ # Protected admin routes
│ ├── farms/ # Farm discovery & details
│ ├── map/ # National map view
│ ├── articles/ # Article browsing
│ └── search/ # Advanced search
├── components/
│ ├── ui/ # Reusable UI primitives
│ ├── forms/ # Form components
│ ├── maps/ # Map components (Leaflet)
│ └── layout/ # Layout wrappers
├── lib/ # Utilities, DB, helpers
└── types/ # TypeScript definitions
```
Data Model Overview
**Core Entities:**
**Farms**: Location (lat/lng), images, descriptions**Teas**: Linked to farms, tagged (cultivation period, grade)**Articles**: Blog posts linked to teas/farms**Tags**: Categorization for teas and articles**Images**: Multiple per farm/tea with ordering**Relationships:**
One-to-many: Farms → Teas, Farms → Images, Teas → ImagesMany-to-many: Teas ↔ Tags, Articles ↔ Tags, Articles ↔ TeasDevelopment Workflow
1. Starting Development
When beginning a new feature:
1. **Understand Requirements**: Identify if it's admin, public, or shared functionality
2. **Check Data Model**: Review Prisma schema for relevant entities
3. **Plan Components**: Decide between Server Components (default) vs Client Components (interactivity)
4. **Consider Performance**: Pagination, lazy loading, image optimization
2. Implementing Features
**Server Components (Default):**
Use for data fetching from databaseImplement in `app/` directories as `page.tsx`Leverage Server Actions for mutations**Client Components:**
Add `"use client"` directive when neededUse for interactivity: forms, maps, modalsKeep client boundaries small**Forms:**
Use React Hook Form for validationServer Actions for submissionOptimistic updates where appropriate**Images:**
Always use Next.js `Image` componentStore in Vercel BlobImplement ordering field for galleries3. Database Operations
**Prisma Queries:**
Use `prisma.farm.findMany()` with geospatial filtersImplement pagination with `skip` and `take`Include related data with `include` carefully (avoid N+1)**PostGIS Integration:**
Store coordinates as `latitude` and `longitude` fieldsUse raw queries for distance calculations when neededImplement bounding box queries for map viewports4. Authentication & Authorization
**Admin Routes**: Wrap in `(admin)` group with middleware check**NextAuth.js**: Configure providers and callbacks**Session Management**: Protect Server Actions with session checks5. Map Implementation
**Leaflet Integration:**
Use `react-leaflet` componentsImplement clustering for 1000+ farm pinsLazy load map component (Client Component)Handle SSR compatibility (dynamic import)6. Search & Filtering
**Full-text Search**: Use PostgreSQL full-text search capabilities**Tag Filtering**: Many-to-many joins through Prisma**Location Search**: PostGIS distance queries**Performance**: Index relevant columns, paginate results7. Styling Guidelines
**Tailwind Classes:**
Primary green: `bg-green-600`, `text-green-700`Secondary beige: `bg-amber-50`, `text-amber-900`Mobile-first: Start with mobile, add `md:` and `lg:` breakpointsConsistent spacing: Use `space-y-*` and `gap-*`8. Performance Optimization
**Images:**
Next.js Image component with `fill` or explicit dimensionsOptimize on upload to Vercel BlobLazy load galleries below fold**Maps:**
Marker clustering for > 50 farmsViewport-based data fetchingDebounce map move events**Data Fetching:**
Server Components for initial load`unstable_cache` for expensive queriesPagination for lists (20-50 items per page)Common Tasks
Adding a New Admin Feature
1. Create route in `app/(admin)/your-feature/page.tsx`
2. Build form component in `components/forms/YourFeatureForm.tsx`
3. Implement Server Action in same file or `app/(admin)/actions.ts`
4. Update Prisma schema if new fields needed
5. Add validation with Zod or similar
Adding a Public Page
1. Create route in `app/your-page/page.tsx` as Server Component
2. Fetch data directly in component with Prisma
3. Build necessary UI components in `components/`
4. Ensure responsive design and loading states
Implementing Search
1. Define search parameters (text, tags, location, etc.)
2. Build Prisma query with `where` clauses and `include`
3. Add pagination (`skip`, `take`, total count)
4. Create filter UI as Client Component with URL state
5. Display results with loading skeleton
Code Style
**TypeScript**: Strict mode, explicit return types for functions**Naming**: camelCase for variables, PascalCase for components**Imports**: Group by external → internal → relative**Comments**: JSDoc for complex functions, inline for non-obvious logic**Error Handling**: Try-catch in Server Actions, return typed resultsTesting Strategy
When implementing tests:
**Unit Tests**: Utility functions, helpers**Integration Tests**: API Routes, Server Actions**E2E Tests**: Critical user flows (Playwright)Deployment Considerations
**Environment Variables**: Use `.env.local` for development, Vercel for production**Database Migrations**: Run `prisma migrate deploy` in CI/CD**Build Checks**: Ensure `npm run build` passes before deploy**Image Optimization**: Vercel handles automaticallyHelpful Commands
```bash
Development
npm run dev # Start dev server on localhost:3000
Database
npx prisma migrate dev # Create and apply migration
npx prisma generate # Regenerate Prisma Client
npx prisma studio # Open database GUI
Code Quality
npm run lint # ESLint
npm run type-check # TypeScript compiler check
Production
npm run build # Production build
npm run start # Start production server
```
Key Files to Reference
`prisma/schema.prisma` - Database schema with PostGIS types`src/lib/db.ts` - Prisma client singleton`src/lib/auth.ts` - NextAuth.js configuration`next.config.js` - Next.js configuration with image domainsImportant Notes
1. **Always use Server Components** unless interactivity requires client
2. **Validate all user input** both client and server side
3. **Optimize images** through Vercel Blob and Next.js Image
4. **Test geospatial queries** carefully with real coordinate data
5. **Mobile-first design** - most users will browse on phones
6. **Japanese text handling** - ensure proper UTF-8 support throughout
7. **Map performance** - implement clustering and viewport limiting
When Stuck
1. Check Prisma schema for data model relationships
2. Review Next.js 15 App Router documentation for routing patterns
3. Consult PostGIS documentation for spatial query syntax
4. Test Leaflet features in isolation before integrating
5. Use Prisma Studio to inspect database state
---
By following these guidelines, you'll maintain consistency with the Saryo architecture and deliver high-quality features efficiently.