feat: Add comprehensive documentation for PunimTag Photo Viewer

This commit introduces several new documentation files for the PunimTag Photo Viewer project, including an Executive Summary, Quick Start Guide, Complete Plan, and Architecture Overview. These documents provide a high-level overview, setup instructions, detailed project plans, and architectural diagrams to assist developers and decision-makers. The README has also been updated to include links to these new resources, ensuring easy navigation and access to essential information for users and contributors.
This commit is contained in:
tanyar09 2025-11-14 13:33:55 -05:00
parent 8caa9e192b
commit 7f48d48b80
5 changed files with 4048 additions and 0 deletions

View File

@ -0,0 +1,780 @@
# PunimTag Photo Viewer - Architecture Overview
## System Architecture Diagram
```
┌─────────────────────────────────────────────────────────────────────────┐
│ EXISTING PUNIMTAG SYSTEM │
│ ┌────────────────────┐ ┌─────────────────┐ │
│ │ Desktop App │ │ Web Admin │ │
│ │ (Tkinter) │ │ Interface │ │
│ │ │ │ (React+FastAPI)│ │
│ └──────────┬─────────┘ └────────┬────────┘ │
│ │ │ │
│ │ ┌──────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ PostgreSQL Database │ │
│ │ ┌────────────────────────────┐ │ │
│ │ │ Tables: │ │ │
│ │ │ • photos │ │ │
│ │ │ • faces │ │ │
│ │ │ • people │ │ │
│ │ │ • person_encodings │ │ │
│ │ │ • tags │ │ │
│ │ │ • phototaglinkage │ │ │
│ │ │ • photo_favorites │ │ │
│ │ └────────────────────────────┘ │ │
│ └──────────────────┬─────────────────┘ │
└─────────────────────┼────────────────────────────────────────────────────┘
│ READ-ONLY ACCESS
┌─────────────────────▼──────────────────────────────────────────────────┐
│ NEW PHOTO VIEWER WEBSITE │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ User's Web Browser │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Desktop │ │ Tablet │ │ Mobile │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └──────────────────────────┬─────────────────────────────────────┘ │
│ │ HTTPS │
│ ┌──────────────────────────▼─────────────────────────────────────┐ │
│ │ Next.js 14 Frontend │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ React Server Components (App Router) │ │ │
│ │ │ • Photo Grid (Infinite Scroll) │ │ │
│ │ │ • Search & Filters │ │ │
│ │ │ • Lightbox Viewer │ │ │
│ │ │ • People & Tags Browsers │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ Client Components (Interactive) │ │ │
│ │ │ • TanStack Query (State Management) │ │ │
│ │ │ • Framer Motion (Animations) │ │ │
│ │ │ • React Photo Album (Grid Layout) │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────┬─────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼─────────────────────────────────────┐ │
│ │ Next.js API Routes (Optional) │ │
│ │ • /api/photos - List and search photos │ │
│ │ • /api/photos/[id] - Get photo details │ │
│ │ • /api/people - List people with photo counts │ │
│ │ • /api/tags - List tags with photo counts │ │
│ │ • /api/search - Combined search │ │
│ └──────────────────────────┬─────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼─────────────────────────────────────┐ │
│ │ Prisma ORM Client │ │
│ │ • Type-safe database queries │ │
│ │ • Read-only operations │ │
│ │ • Connection pooling │ │
│ └──────────────────────────┬─────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼─────────────────────────────────────┐ │
│ │ PostgreSQL (Read-Only User) │ │
│ │ Username: viewer_readonly │ │
│ │ Permissions: SELECT only on all tables │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
```
---
## Data Flow Diagram
### Photo Gallery Loading
```
User Opens Browser
┌─────────────────┐
│ Next.js Server │
│ (App Router) │
└────────┬────────┘
│ 1. Server Component Renders
│ await prisma.photo.findMany()
┌─────────────────┐
│ Prisma Client │
└────────┬────────┘
│ 2. SQL Query (Read-Only)
│ SELECT * FROM photos
│ WHERE processed = true
│ ORDER BY date_taken DESC
│ LIMIT 30
┌─────────────────┐
│ PostgreSQL │
│ Database │
└────────┬────────┘
│ 3. Return Photo Records
│ [{id, path, filename, date_taken, ...}, ...]
┌─────────────────┐
│ Next.js Server │
│ (Pre-renders) │
└────────┬────────┘
│ 4. Generate HTML with Photo Data
┌─────────────────┐
│ User Browser │
│ (Receives HTML)│
└────────┬────────┘
│ 5. Hydrate React Components
┌─────────────────┐
│ Photo Grid │
│ (Rendered) │
└────────┬────────┘
│ 6. Load Images (Lazy)
<Image src={photo.path} />
┌─────────────────┐
│ Next.js Image │
│ Optimization │
└────────┬────────┘
│ 7. Serve Optimized Images
│ (WebP, responsive sizes)
┌─────────────────┐
│ User Sees Photos│
└─────────────────┘
```
### Search Flow
```
User Types in Search
┌─────────────────┐
│ SearchBar │
│ (Debounced) │
└────────┬────────┘
│ 300ms delay
┌─────────────────┐
│ TanStack Query │
│ (React Query) │
└────────┬────────┘
│ Check cache first
│ If not cached:
┌─────────────────┐
│ API Route │
│ /api/search │
└────────┬────────┘
│ Build Query
│ {people: [1,2], tags: [3], dateFrom: '2024-01-01'}
┌─────────────────┐
│ Prisma Query │
│ Builder │
└────────┬────────┘
│ WHERE processed = true
│ AND faces.person_id IN (1,2)
│ AND photo_tags.tag_id IN (3)
│ AND date_taken >= '2024-01-01'
┌─────────────────┐
│ PostgreSQL │
│ (Indexed) │
└────────┬────────┘
│ Return Matching Photos
┌─────────────────┐
│ TanStack Query │
│ (Cache Result) │
└────────┬────────┘
│ staleTime: 5 min
│ cacheTime: 10 min
┌─────────────────┐
│ Photo Grid │
│ (Update UI) │
└─────────────────┘
```
---
## Component Hierarchy
```
App Layout
├── Header
│ ├── Logo
│ ├── Navigation
│ │ ├── Home Link
│ │ ├── People Link
│ │ ├── Tags Link
│ │ └── Timeline Link
│ ├── SearchButton
│ └── UserMenu
│ ├── Login/Logout
│ └── Settings
├── Main Content (Page)
│ │
│ ├── HomePage (/)
│ │ ├── Hero Section
│ │ ├── QuickFilters
│ │ └── PhotoGrid
│ │ ├── PhotoCard (x30)
│ │ │ ├── Image (Next.js)
│ │ │ ├── Overlay
│ │ │ └── Actions
│ │ └── InfiniteScroll Trigger
│ │
│ ├── SearchPage (/search)
│ │ ├── SearchBar
│ │ ├── FilterPanel
│ │ │ ├── PeopleFilter
│ │ │ ├── DateRangePicker
│ │ │ └── TagFilter
│ │ └── SearchResults
│ │ └── PhotoGrid
│ │
│ ├── PhotoDetailPage (/photo/[id])
│ │ ├── Lightbox
│ │ │ ├── FullSizeImage
│ │ │ ├── NavigationButtons
│ │ │ └── CloseButton
│ │ └── MetadataPanel
│ │ ├── DateTaken
│ │ ├── PeopleList
│ │ ├── TagList
│ │ └── Actions
│ │
│ ├── PeoplePage (/people)
│ │ ├── PeopleGrid
│ │ │ └── PersonCard (x many)
│ │ │ ├── RepresentativePhoto
│ │ │ ├── PersonName
│ │ │ └── PhotoCount
│ │ └── SearchBar
│ │
│ └── TagsPage (/tags)
│ ├── TagCloud
│ │ └── TagBadge (x many)
│ │ ├── TagName
│ │ └── PhotoCount
│ └── SearchBar
└── Footer
├── Copyright
├── Links
└── Version
```
---
## Technology Stack Layers
```
┌──────────────────────────────────────────────────────┐
│ Presentation Layer │
│ ┌────────────────────────────────────────────────┐ │
│ │ React Server Components + Client Components │ │
│ │ • shadcn/ui (UI Components) │ │
│ │ • Tailwind CSS (Styling) │ │
│ │ • Framer Motion (Animations) │ │
│ │ • Lucide React (Icons) │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ Application Layer │
│ ┌────────────────────────────────────────────────┐ │
│ │ Next.js 14 (App Router) │ │
│ │ • Server-Side Rendering │ │
│ │ • API Routes │ │
│ │ • Image Optimization │ │
│ │ • Route Handlers │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ State Management Layer │
│ ┌────────────────────────────────────────────────┐ │
│ │ TanStack Query (React Query) │ │
│ │ • Server State Caching │ │
│ │ • Automatic Refetching │ │
│ │ • Optimistic Updates │ │
│ │ • Infinite Scroll │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ Data Access Layer │
│ ┌────────────────────────────────────────────────┐ │
│ │ Prisma ORM │ │
│ │ • Type-Safe Queries │ │
│ │ • Connection Pooling │ │
│ │ • Query Builder │ │
│ │ • Migration Management │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ Database Layer │
│ ┌────────────────────────────────────────────────┐ │
│ │ PostgreSQL │ │
│ │ • Relational Database │ │
│ │ • ACID Transactions │ │
│ │ • Indices for Performance │ │
│ │ • Read-Only User (viewer_readonly) │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
```
---
## Deployment Architecture
### Option 1: Vercel (Recommended)
```
┌──────────────────────────────────────────────────────────┐
│ Vercel Edge Network │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Global CDN (Automatic) │ │
│ │ • Caches static assets │ │
│ │ │ - HTML, CSS, JS │ │
│ │ │ - Optimized images │ │
│ │ └─ Serves from nearest edge location │ │
│ └────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼───────────────────────────────┐ │
│ │ Next.js Server (Serverless Functions) │ │
│ │ • API Routes │ │
│ │ │ - /api/photos │ │
│ │ │ - /api/search │ │
│ │ │ - /api/people │ │
│ │ └─ Server Components rendering │ │
│ └────────────────────┬───────────────────────────────┘ │
└────────────────────────┼──────────────────────────────────┘
│ Database Connection
│ (Secure, encrypted)
┌────────────────────────▼──────────────────────────────────┐
│ Your PostgreSQL Server │
│ • On your local network OR │
│ • Hosted database (Railway, Supabase, etc.) │
│ • Connection via DATABASE_URL env variable │
└───────────────────────────────────────────────────────────┘
```
### Option 2: Self-Hosted (Docker)
```
┌──────────────────────────────────────────────────────────┐
│ Your Server / VPS │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Caddy (Reverse Proxy + Auto HTTPS) │ │
│ │ • Automatic SSL certificates │ │
│ │ • HTTPS redirection │ │
│ │ • Static file serving │ │
│ └────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼───────────────────────────────┐ │
│ │ Docker Container: punimtag-viewer │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Next.js Production Server │ │ │
│ │ │ • Node.js 20 │ │ │
│ │ │ • Optimized build │ │ │
│ │ │ • Port 3000 │ │ │
│ │ └────────────────┬─────────────────────────────┘ │ │
│ └───────────────────┼────────────────────────────────┘ │
│ │ │
│ ┌───────────────────▼────────────────────────────────┐ │
│ │ Docker Container: PostgreSQL (Optional) │ │
│ │ • Or connect to existing PunimTag database │ │
│ └────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────┘
```
---
## Security Architecture
```
┌──────────────────────────────────────────────────────────┐
│ User Browser │
└───────────────────────┬──────────────────────────────────┘
│ HTTPS Only
│ (TLS 1.3)
┌──────────────────────────────────────────────────────────┐
│ Authentication Layer │
│ ┌────────────────────────────────────────────────────┐ │
│ │ NextAuth.js (Optional) │ │
│ │ • JWT Sessions │ │
│ │ • OAuth Providers (Google, etc.) │ │
│ │ • OR Simple Password Protection │ │
│ └────────────────────┬───────────────────────────────┘ │
└────────────────────────┼──────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Authorization Layer │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Read-Only Access │ │
│ │ • No write operations allowed │ │
│ │ • No photo uploads │ │
│ │ • No deletion │ │
│ │ • Favorites only write operation (per user) │ │
│ └────────────────────┬───────────────────────────────┘ │
└────────────────────────┼──────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ API Security Layer │
│ ┌────────────────────────────────────────────────────┐ │
│ │ • Rate Limiting (10 req/10s per IP) │ │
│ │ • Input Validation (Zod schemas) │ │
│ │ • SQL Injection Prevention (Prisma ORM) │ │
│ │ • XSS Prevention (React auto-escaping) │ │
│ │ • CSRF Protection (SameSite cookies) │ │
│ └────────────────────┬───────────────────────────────┘ │
└────────────────────────┼──────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Database Security │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Read-Only PostgreSQL User │ │
│ │ • Username: viewer_readonly │ │
│ │ • SELECT permission only │ │
│ │ • No INSERT, UPDATE, DELETE │ │
│ │ • Connection over encrypted channel │ │
│ └────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
```
---
## Performance Optimization Strategy
```
┌──────────────────────────────────────────────────────────┐
│ Browser Layer │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Browser Caching │ │
│ │ • Static assets: 1 year │ │
│ │ • Images: 1 month │ │
│ │ • API responses: 5 minutes │ │
│ └────────────────────────────────────────────────────┘ │
└───────────────────────┬──────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ React Query Layer │
│ ┌────────────────────────────────────────────────────┐ │
│ │ In-Memory Cache │ │
│ │ • Query results cached │ │
│ │ • staleTime: 5 minutes │ │
│ │ • cacheTime: 10 minutes │ │
│ │ • Automatic background refetching │ │
│ └────────────────────────────────────────────────────┘ │
└───────────────────────┬──────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Next.js Layer │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Image Optimization │ │
│ │ • Automatic WebP/AVIF conversion │ │
│ │ • Responsive images (srcset) │ │
│ │ • Lazy loading │ │
│ │ • Blur placeholders │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ Code Splitting │ │
│ │ • Route-based splitting │ │
│ │ • Dynamic imports │ │
│ │ • Component lazy loading │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ Server-Side Rendering │ │
│ │ • Initial render on server │ │
│ │ • Faster first contentful paint │ │
│ └────────────────────────────────────────────────────┘ │
└───────────────────────┬──────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Database Layer │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Prisma Connection Pooling │ │
│ │ • Reuse database connections │ │
│ │ • Max connections: 10 │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ PostgreSQL Indices │ │
│ │ • idx_photos_date_taken │ │
│ │ • idx_photos_processed │ │
│ │ • idx_faces_person_id │ │
│ │ • idx_photo_tags_tag │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ Query Optimization │ │
│ │ • Cursor-based pagination │ │
│ │ • SELECT only needed columns │ │
│ │ • Minimize JOINs │ │
│ └────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
```
---
## Comparison: Admin Interface vs Photo Viewer
| Aspect | Admin Interface | Photo Viewer |
|--------|----------------|--------------|
| **Purpose** | Manage & Process | View & Browse |
| **Tech Stack** | React + FastAPI | Next.js 14 |
| **Rendering** | Client-Side (SPA) | Server + Client (SSR) |
| **State** | React Context | TanStack Query |
| **Database Access** | Full (R/W) via API | Read-Only via Prisma |
| **Photo Upload** | ✅ Yes | ❌ No |
| **Face Processing** | ✅ Yes | ❌ No |
| **Search** | ✅ Advanced | ✅ User-friendly |
| **Performance** | Good | Excellent |
| **Mobile UX** | Functional | Optimized |
| **Auth** | Required | Optional |
| **Deployment** | Backend + Frontend | Single Next.js App |
| **Target Users** | Admin (1-2) | All Users (5-50+) |
| **Complexity** | High | Low |
---
## Database Read Patterns
### Admin Interface (Write-Heavy)
```
┌─────────────────────────────────────┐
│ Photo Upload │
│ INSERT INTO photos │
│ (Heavy write operations) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Face Processing │
│ INSERT INTO faces │
│ UPDATE photos SET processed │
│ (Batch operations) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Person Identification │
│ UPDATE faces SET person_id │
│ INSERT INTO person_encodings │
└─────────────────────────────────────┘
```
### Photo Viewer (Read-Heavy)
```
┌─────────────────────────────────────┐
│ Browse Photos │
│ SELECT * FROM photos │
│ WHERE processed = true │
│ ORDER BY date_taken DESC │
│ LIMIT 30 OFFSET X │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Search by Person │
│ SELECT p.* FROM photos p │
│ JOIN faces f ON p.id = f.photo_id │
│ WHERE f.person_id = X │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Get Photo Details │
│ SELECT * FROM photos WHERE id = X │
│ + JOIN faces + people + tags │
└─────────────────────────────────────┘
```
---
## Image Serving Strategy
```
┌──────────────────────────────────────────────────────────┐
│ Original Photo Files │
│ Location: /path/to/photos/2024/01/IMG_1234.jpg │
│ Size: 4000x3000, 8MB │
└───────────────────────┬──────────────────────────────────┘
│ Referenced by path in DB
┌───────────────────────▼──────────────────────────────────┐
│ Next.js Image Component │
<Image src={photo.path} width={800} height={600} />
└───────────────────────┬──────────────────────────────────┘
│ Optimization Request
┌───────────────────────▼──────────────────────────────────┐
│ Next.js Image Optimization │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 1. Load original image │ │
│ │ 2. Resize to requested dimensions │ │
│ │ 3. Convert to WebP/AVIF (browser support) │ │
│ │ 4. Apply quality compression (85%) │ │
│ │ 5. Generate blur placeholder (base64) │ │
│ │ 6. Cache optimized image │ │
│ └────────────────────────────────────────────────────┘ │
└───────────────────────┬──────────────────────────────────┘
│ Serve Optimized
┌───────────────────────▼──────────────────────────────────┐
│ Browser Display │
│ Sizes: │
│ • Thumbnail: 300x200 (~30KB WebP) │
│ • Medium: 800x600 (~150KB WebP) │
│ • Large: 1920x1440 (~500KB WebP) │
│ • Full: 4000x3000 (~2MB original, if download enabled) │
└──────────────────────────────────────────────────────────┘
```
---
## Responsive Design Strategy
### Mobile First Approach
```
┌─────────────────────────────────────────────────────────┐
│ Mobile (<640px)
│ ┌───────────────────────────────────────────────────┐ │
│ │ [☰] PunimTag [🔍] │ │
│ ├───────────────────────────────────────────────────┤ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Photo │ │ Photo │ 2 columns │ │
│ │ └──────────┘ └──────────┘ │ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Photo │ │ Photo │ Compact │ │
│ │ └──────────┘ └──────────┘ │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Tablet (640px - 1024px) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ [Logo] Home | People | Tags [Search] [👤] │ │
│ ├───────────────────────────────────────────────────┤ │
│ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ │Photo│ │Photo│ │Photo│ 3-4 columns │ │
│ │ └─────┘ └─────┘ └─────┘ │ │
│ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ │Photo│ │Photo│ │Photo│ Medium size │ │
│ │ └─────┘ └─────┘ └─────┘ │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Desktop (>1024px) │
│ ┌───────────────────────────────────────────────────┐ │
│ │ [Logo] Home | People | Tags [Search Bar] [👤] │ │
│ ├──────┬────────────────────────────────────────────┤ │
│ │Filter│ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │
│ │ │ │Ph│ │Ph│ │Ph│ │Ph│ │Ph│ 5-6 columns │ │
│ │People│ └──┘ └──┘ └──┘ └──┘ └──┘ │ │
│ │☐ John│ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ │ │
│ │☐ Jane│ │Ph│ │Ph│ │Ph│ │Ph│ │Ph│ Large grid │ │
│ │ │ └──┘ └──┘ └──┘ └──┘ └──┘ │ │
│ │Tags │ │ │
│ │☐ Fam │ │ │
│ └──────┴────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
---
## Error Handling Flow
```
User Request
┌──────────────────┐
│ Try Operation │
└────────┬─────────┘
├─ Success ────────────────┐
│ ▼
│ ┌─────────────────┐
│ │ Return Data │
│ │ Update UI │
│ └─────────────────┘
└─ Error ──────────────────┐
┌──────────────────┐
│ Catch Error │
└────────┬─────────┘
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌─────────────┐ ┌────────────┐
│ Network Error │ │ 404 Not │ │ 500 Server │
│ (Offline) │ │ Found │ │ Error │
└───────┬───────┘ └──────┬──────┘ └─────┬──────┘
│ │ │
│ │ │
└────────────────┼──────────────┘
┌──────────────────┐
│ Log Error │
│ (Sentry) │
└────────┬─────────┘
┌──────────────────┐
│ Show Error UI │
│ • Toast │
│ • Error Page │
│ • Retry Button │
└──────────────────┘
```
---
This architecture ensures a clean separation between the admin interface (for management) and the photo viewer (for browsing), while sharing the same database and maintaining data consistency.

View File

@ -0,0 +1,425 @@
# PunimTag Photo Viewer - Executive Summary
## 📋 Overview
This document provides a high-level summary of the plan to create a new photo viewing website for PunimTag. This summary is designed for decision-makers and provides key recommendations.
---
## 🎯 What Are We Building?
A **modern, fast, beautiful photo gallery website** that allows family members to browse and search photos from your PunimTag database without needing admin access.
### Key Features
- ✅ Browse all photos in a beautiful grid layout
- ✅ Search by people, dates, and tags
- ✅ View full-size photos with metadata
- ✅ Mobile-optimized responsive design
- ✅ Fast loading with modern optimizations
- ✅ Optional authentication for privacy
### What It's NOT
- ❌ Not a replacement for the admin interface
- ❌ No photo uploads (read-only)
- ❌ No face processing or management
- ❌ No bulk operations
---
## 💡 Why Do We Need This?
### Current Situation
You have a powerful admin interface for managing photos, but it's:
- Too complex for casual family browsing
- Requires admin credentials
- Focused on management, not viewing
- Not optimized for mobile devices
### The Solution
A separate, simplified photo viewer that:
- Focuses solely on viewing and searching
- Easy for anyone in the family to use
- Optimized for browsing experience
- Beautiful, modern design
- Works great on all devices
---
## 🏗️ Technical Approach
### Recommended Technology Stack
| Component | Technology | Why? |
|-----------|-----------|------|
| **Framework** | Next.js 14 | Best-in-class for performance, SEO, and developer experience |
| **UI Library** | shadcn/ui + Tailwind | Modern, beautiful, customizable components |
| **Database** | Existing PostgreSQL | Reuse your database with read-only access |
| **ORM** | Prisma | Type-safe database queries, excellent PostgreSQL support |
| **State** | TanStack Query | Perfect for server data caching and infinite scroll |
| **Images** | Next.js Image | Automatic optimization, WebP conversion, lazy loading |
| **Hosting** | Vercel (recommended) | Zero-config deployment, global CDN, free tier available |
### Architecture Overview
```
User Browser → Next.js Frontend → Prisma ORM → PostgreSQL Database
(Read-Only User)
```
---
## 📊 Decision Matrix
### 🌟 Recommended Approach: Next.js with Vercel
**Pros:**
- ⭐ Fastest time to market (6-8 weeks)
- ⭐ Best performance (Lighthouse score >90)
- ⭐ Easiest deployment (zero config)
- ⭐ Free hosting tier available
- ⭐ Automatic image optimization
- ⭐ Built-in SEO and accessibility
**Cons:**
- 💰 Can be expensive for high traffic (but free tier is generous)
- 🌐 Requires database to be network-accessible (or use hosted DB)
**Best For:** Most users, especially if you want the best UX and fastest development
---
### Alternative 1: Self-Hosted Docker
**Pros:**
- 💰 Lower ongoing costs (after initial setup)
- 🔒 Full control over hosting
- 🏠 Can run on local network
- 🔐 More privacy (no third-party hosting)
**Cons:**
- 🛠️ Requires DevOps knowledge
- ⏰ Longer setup time
- 📈 Manual scaling
- 🔧 More maintenance
**Best For:** Technical users who want full control and have server management experience
---
### Alternative 2: Astro + React Islands
**Pros:**
- ⚡ Even faster than Next.js
- 💾 Lower bandwidth usage
- 🎨 Great for content-heavy sites
**Cons:**
- 📚 Smaller ecosystem than Next.js
- 🆕 Less mature (but stable)
- 🔧 More manual configuration
**Best For:** Users who prioritize absolute maximum performance
---
## 💰 Cost Analysis
### Development Costs
| Approach | Timeline | Estimated Cost |
|----------|----------|---------------|
| **DIY (Self-Development)** | 12 weeks | Your time (200-300 hours) |
| **Freelancer** | 8-12 weeks | $18,000 - $28,000 |
| **Agency** | 6-10 weeks | $30,000 - $50,000 |
### Monthly Hosting Costs
| Option | Cost/Month | Best For |
|--------|------------|----------|
| **Vercel (Free Tier)** | $0 | Small families (<100 users) |
| **Vercel (Pro)** | $20 | Medium usage (100-1000 users) |
| **Railway** | $5-20 | Hobby projects |
| **VPS (DigitalOcean)** | $12-24 | Self-hosted, full control |
| **Home Server** | $0* | After hardware cost, local network |
**Recommendation:** Start with Vercel Free Tier, upgrade if needed
---
## ⏱️ Timeline
### Fast Track (6 weeks)
| Week | Phase | Deliverables |
|------|-------|--------------|
| 1-2 | Foundation | Project setup, database connection, basic layout |
| 3-4 | Core Features | Photo grid, lightbox, search by people/tags |
| 5 | Polish | Responsive design, animations, performance |
| 6 | Launch | Deploy, test, documentation |
### Standard Track (12 weeks)
| Week | Phase | Deliverables |
|------|-------|--------------|
| 1-2 | Foundation | Setup + authentication |
| 3-4 | Core Features | Photo browsing |
| 5-6 | Search | Advanced search and filters |
| 7-8 | Polish | Optimization and UX |
| 9-10 | Advanced | Favorites, sharing, timeline |
| 11-12 | Launch | Testing, deployment, docs |
**Recommendation:** Standard track for best quality and features
---
## 🎨 Design Approach
### Modern, Clean, Fast
- **Inspiration:** Google Photos, iCloud Photos
- **Style:** Minimalist, photo-first design
- **Colors:** Modern blues and clean whites/darks
- **Typography:** Inter font family (clean, readable)
- **Layout:** Responsive grid (masonry or justified)
- **Animations:** Subtle, smooth, meaningful
### Mobile First
- Works beautifully on phones and tablets
- Touch-optimized interactions
- Fast loading on cellular networks
- Responsive images for all screen sizes
---
## 🔒 Security Considerations
### Database Security
- ✅ Read-only PostgreSQL user (no write access)
- ✅ Separate credentials from admin interface
- ✅ Encrypted database connections
- ✅ Network isolation (if self-hosted)
### Application Security
- ✅ Optional authentication (NextAuth.js)
- ✅ Rate limiting to prevent abuse
- ✅ Input validation on all queries
- ✅ XSS and CSRF protection (built-in)
- ✅ HTTPS only (automatic with Vercel/Caddy)
### Privacy Options
- ✅ Strip GPS data from EXIF
- ✅ Configurable download permissions
- ✅ Per-user favorites (privacy-preserving)
- ✅ Optional authentication requirement
---
## 📈 Success Metrics
### Technical Goals
- 🎯 Lighthouse Performance Score: >90
- 🎯 Page Load Time: <2 seconds
- 🎯 Image Load Time: <1 second
- 🎯 API Response Time: <200ms
- 🎯 Mobile Experience: Excellent
### User Experience Goals
- 🎯 User Adoption: 90% of family members
- 🎯 Session Duration: >5 minutes
- 🎯 Return Visits: >60% weekly
- 🎯 User Satisfaction: >4.5/5 stars
- 🎯 Mobile Usage: >50% of traffic
---
## 🚦 Go/No-Go Criteria
### ✅ Proceed If:
- You have a PostgreSQL database with photos
- You want to share photos with family/friends
- You have budget for development OR time to DIY
- You value user experience and modern design
- You want mobile-optimized photo browsing
### ❌ Don't Proceed If:
- Your database has <100 photos (not worth it yet)
- You're happy with current admin interface for viewing
- Budget constraints (<$500 for hosting/development)
- You don't care about mobile experience
- You need write operations (upload, edit, delete)
---
## 🎬 Next Steps
### Option A: Hire Developer/Agency
1. ✅ Approve this plan
2. ✅ Choose technology stack (recommend: Next.js + Vercel)
3. ✅ Set budget and timeline
4. ✅ Find and hire developer/agency
5. ✅ Provide database access (read-only user)
6. ✅ Review progress weekly
7. ✅ Test and provide feedback
8. ✅ Launch and train users
### Option B: DIY Development
1. ✅ Review technical requirements
2. ✅ Follow Quick Start Guide (`docs/PHOTO_VIEWER_QUICKSTART.md`)
3. ✅ Set up development environment
4. ✅ Follow phase-by-phase plan (`docs/PHOTO_VIEWER_PLAN.md`)
5. ✅ Build incrementally (one feature at a time)
6. ✅ Test with real users frequently
7. ✅ Deploy when stable
8. ✅ Iterate based on feedback
### Option C: Hybrid Approach
1. ✅ Hire freelancer for initial setup (Weeks 1-4)
2. ✅ Learn and customize yourself (Weeks 5+)
3. ✅ Freelancer available for support
4. ✅ Best of both worlds
**Recommendation:** Option A or C for fastest, highest-quality results
---
## ❓ Frequently Asked Questions
### Q: Can I keep using the admin interface?
**A:** Yes! The photo viewer is a separate application. Your admin interface continues working exactly as before.
### Q: Will this modify my database?
**A:** No. The photo viewer uses a read-only database user. It can't modify your photos, faces, or people data. The only exception is the optional favorites feature, which adds per-user favorites to a separate table.
### Q: Do I need to migrate data?
**A:** No. The photo viewer reads directly from your existing PunimTag PostgreSQL database. No data migration needed.
### Q: Can I customize the design?
**A:** Absolutely! The design is fully customizable. You can change colors, fonts, layouts, and components to match your preferences.
### Q: What if I have 100,000 photos?
**A:** The architecture is designed to scale. With proper indexing and pagination, it can handle hundreds of thousands of photos. Performance may require some optimization for very large databases.
### Q: Can users upload photos?
**A:** Not in the initial design (read-only). However, this can be added as a future enhancement if needed. The admin interface remains the primary way to add photos.
### Q: Is it mobile-friendly?
**A:** Yes! Mobile-first design with responsive layouts, touch-optimized interactions, and fast loading on cellular networks.
### Q: What about authentication?
**A:** Optional. You can:
- Make it completely public (no login)
- Add simple password protection
- Use OAuth (Google, Facebook)
- Use email/password authentication
Choose based on your privacy needs.
### Q: Can I host it on my home server?
**A:** Yes! You can self-host using Docker. The plan includes instructions for both cloud (Vercel) and self-hosted (Docker) deployment.
### Q: What if my database is not network-accessible?
**A:** For Vercel hosting, you'll need network access. For self-hosted, you can run it on the same network as your database.
### Q: How do I update it when new photos are added?
**A:** It's automatic! The viewer reads from the live database, so new photos appear immediately after they're processed in the admin interface.
---
## 🎯 Recommendation Summary
### For Most Users: Next.js + Vercel
- ⭐ Best performance and user experience
- ⭐ Fastest development (6-8 weeks)
- ⭐ Easiest deployment and maintenance
- ⭐ Free hosting tier available
- ⭐ Proven, mature ecosystem
### Cost: $0-20/month hosting + $18K-28K development (or DIY)
### Timeline: 6-12 weeks depending on approach
### Next Action: Review full plan, make go/no-go decision, allocate budget
---
## 📚 Documentation Index
| Document | Purpose | Audience |
|----------|---------|----------|
| **This Document** | Executive summary and decision guide | Decision makers |
| `PHOTO_VIEWER_PLAN.md` | Complete detailed plan (20+ pages) | Developers, project managers |
| `PHOTO_VIEWER_QUICKSTART.md` | Quick setup guide (5 minutes to start) | Developers |
| `PHOTO_VIEWER_ARCHITECTURE.md` | Technical architecture and diagrams | Developers, architects |
---
## ✅ Action Items
### For You (Decision Maker)
- [ ] Review this executive summary
- [ ] Read the full detailed plan if needed
- [ ] Make go/no-go decision
- [ ] Allocate budget (development + hosting)
- [ ] Choose deployment approach (Vercel vs self-hosted)
- [ ] Decide on authentication requirement
- [ ] Approve timeline and milestones
### For Developer/Agent
- [ ] Read all documentation
- [ ] Set up development environment
- [ ] Create read-only database user
- [ ] Initialize Next.js project
- [ ] Follow Phase 1 tasks
- [ ] Provide weekly progress updates
---
## 🎊 Expected Outcome
After completion, you'll have:
**A beautiful, modern photo gallery** that family members love to use
**Fast, responsive browsing** on all devices (desktop, tablet, mobile)
**Powerful search capabilities** (people, dates, tags)
**Read-only access** that keeps your database safe
**Separate from admin interface** so you can manage photos independently
**Scalable architecture** that grows with your photo collection
**Low maintenance** with automatic updates and optimizations
---
## 📧 Questions?
If you have questions or need clarification on any part of this plan:
1. **Review the detailed plan** (`PHOTO_VIEWER_PLAN.md`)
2. **Check the architecture** (`PHOTO_VIEWER_ARCHITECTURE.md`)
3. **Try the quick start** (`PHOTO_VIEWER_QUICKSTART.md`)
4. **Consult Next.js docs** (https://nextjs.org/docs)
---
**Ready to proceed?** 🚀
Choose your path:
- **Option A:** Hire a developer and provide them with this plan
- **Option B:** Build it yourself using the Quick Start Guide
- **Option C:** Hybrid approach (developer + your customizations)
**This is a well-planned project with clear deliverables, proven technologies, and realistic timelines.**
Let's build something amazing! 🎉
---
**Document Version:** 1.0
**Last Updated:** November 14, 2025
**Status:** Ready for Decision
**Recommended Action:** Proceed with Next.js + Vercel approach

1989
docs/PHOTO_VIEWER_PLAN.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,470 @@
# PunimTag Photo Viewer - Quick Start Guide
## 🎯 What Is This?
A **modern, fast, beautiful photo viewing website** that connects to your existing PunimTag PostgreSQL database. Perfect for sharing photos with family members without giving them admin access.
---
## 🚀 Quick Setup (5 Minutes)
### 1. Create the Project
```bash
# Navigate to your projects folder
cd /home/ladmin/Code
# Create Next.js project
npx create-next-app@latest punimtag-viewer --typescript --tailwind --app --no-src-dir
# Navigate into project
cd punimtag-viewer
```
When prompted, choose:
- TypeScript: **Yes**
- ESLint: **Yes**
- Tailwind CSS: **Yes**
- `src/` directory: **No** (we'll use app directory)
- App Router: **Yes**
- Import alias: **Yes** (@/*)
### 2. Install Core Dependencies
```bash
# UI Components & Styling
npx shadcn-ui@latest init
# Database
npm install @prisma/client
npm install -D prisma
# State Management & Data Fetching
npm install @tanstack/react-query
# Image Gallery
npm install react-photo-album yet-another-react-lightbox
# Icons & Animations
npm install lucide-react framer-motion
# Date Handling
npm install date-fns
# Authentication (Optional)
npm install next-auth
```
### 3. Set Up Database Connection
```bash
# Initialize Prisma
npx prisma init
```
Edit `.env`:
```bash
DATABASE_URL="postgresql://viewer_readonly:password@localhost:5432/punimtag"
```
### 4. Create Prisma Schema
Create `prisma/schema.prisma`:
```prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Photo {
id Int @id @default(autoincrement())
path String @unique
filename String
dateAdded DateTime @default(now()) @map("date_added")
dateTaken DateTime? @map("date_taken")
processed Boolean @default(false)
faces Face[]
photoTags PhotoTagLinkage[]
favorites PhotoFavorite[]
@@map("photos")
}
model Person {
id Int @id @default(autoincrement())
firstName String @map("first_name")
lastName String @map("last_name")
middleName String? @map("middle_name")
maidenName String? @map("maiden_name")
dateOfBirth DateTime? @map("date_of_birth") @db.Date
createdDate DateTime @default(now()) @map("created_date")
faces Face[]
personEncodings PersonEncoding[]
@@unique([firstName, lastName, middleName, maidenName, dateOfBirth], name: "uq_people_names_dob")
@@map("people")
}
model Face {
id Int @id @default(autoincrement())
photoId Int @map("photo_id")
personId Int? @map("person_id")
encoding Bytes
location String
confidence Decimal @default(0) @db.Decimal
qualityScore Decimal @default(0) @map("quality_score") @db.Decimal
detectorBackend String @default("retinaface") @map("detector_backend")
modelName String @default("ArcFace") @map("model_name")
faceConfidence Decimal @default(0) @map("face_confidence") @db.Decimal
poseMode String @default("frontal") @map("pose_mode")
photo Photo @relation(fields: [photoId], references: [id])
person Person? @relation(fields: [personId], references: [id])
personEncodings PersonEncoding[]
@@index([photoId])
@@index([personId])
@@map("faces")
}
model PersonEncoding {
id Int @id @default(autoincrement())
personId Int @map("person_id")
faceId Int @map("face_id")
encoding Bytes
qualityScore Decimal @default(0) @map("quality_score") @db.Decimal
detectorBackend String @default("retinaface") @map("detector_backend")
modelName String @default("ArcFace") @map("model_name")
createdDate DateTime @default(now()) @map("created_date")
person Person @relation(fields: [personId], references: [id])
face Face @relation(fields: [faceId], references: [id])
@@index([personId])
@@map("person_encodings")
}
model Tag {
id Int @id @default(autoincrement())
tagName String @unique @map("tag_name")
createdDate DateTime @default(now()) @map("created_date")
photoTags PhotoTagLinkage[]
@@map("tags")
}
model PhotoTagLinkage {
linkageId Int @id @default(autoincrement()) @map("linkage_id")
photoId Int @map("photo_id")
tagId Int @map("tag_id")
linkageType Int @default(0) @map("linkage_type")
createdDate DateTime @default(now()) @map("created_date")
photo Photo @relation(fields: [photoId], references: [id])
tag Tag @relation(fields: [tagId], references: [id])
@@unique([photoId, tagId], name: "uq_photo_tag")
@@index([photoId])
@@index([tagId])
@@map("phototaglinkage")
}
model PhotoFavorite {
id Int @id @default(autoincrement())
username String
photoId Int @map("photo_id")
createdDate DateTime @default(now()) @map("created_date")
photo Photo @relation(fields: [photoId], references: [id])
@@unique([username, photoId], name: "uq_user_photo_favorite")
@@index([username])
@@index([photoId])
@@map("photo_favorites")
}
```
### 5. Generate Prisma Client
```bash
npx prisma generate
```
### 6. Test Database Connection
```bash
npx prisma db pull # Verify schema matches database
npx prisma studio # Open database browser (optional)
```
### 7. Create First Component
Create `app/page.tsx`:
```typescript
import { prisma } from '@/lib/db';
import { PhotoGrid } from '@/components/PhotoGrid';
export default async function HomePage() {
const photos = await prisma.photo.findMany({
where: { processed: true },
orderBy: { dateTaken: 'desc' },
take: 30,
});
return (
<main className="container mx-auto px-4 py-8">
<h1 className="text-4xl font-bold mb-8">Family Photos</h1>
<PhotoGrid photos={photos} />
</main>
);
}
```
Create `lib/db.ts`:
```typescript
import { PrismaClient } from '@prisma/client';
const globalForPrisma = global as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
log: ['error'],
});
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
```
### 8. Run Development Server
```bash
npm run dev
```
Open http://localhost:3000
---
## 📁 Project Structure
```
punimtag-viewer/
├── app/ # Next.js 14 App Router
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page (photo grid)
│ ├── photo/[id]/ # Photo detail page
│ ├── people/ # People browser
│ ├── tags/ # Tags browser
│ └── search/ # Search page
├── components/ # React components
│ ├── ui/ # shadcn components
│ ├── PhotoGrid.tsx # Photo grid
│ ├── PhotoCard.tsx # Photo card
│ └── Lightbox.tsx # Photo viewer
├── lib/ # Utilities
│ ├── db.ts # Prisma client
│ ├── queries.ts # Database queries
│ └── utils.ts # Helpers
├── prisma/
│ └── schema.prisma # Database schema
├── .env # Environment variables
└── package.json
```
---
## 🎨 Install UI Components
```bash
# Install shadcn/ui components as needed
npx shadcn-ui@latest add button
npx shadcn-ui@latest add card
npx shadcn-ui@latest add input
npx shadcn-ui@latest add dialog
npx shadcn-ui@latest add dropdown-menu
npx shadcn-ui@latest add popover
npx shadcn-ui@latest add select
npx shadcn-ui@latest add calendar
npx shadcn-ui@latest add badge
npx shadcn-ui@latest add skeleton
```
---
## 🔐 Set Up Read-Only Database User
On your PostgreSQL server:
```sql
-- Create read-only user
CREATE USER viewer_readonly WITH PASSWORD 'your_secure_password';
-- Grant permissions
GRANT CONNECT ON DATABASE punimtag TO viewer_readonly;
GRANT USAGE ON SCHEMA public TO viewer_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO viewer_readonly;
-- Grant on future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO viewer_readonly;
-- Verify no write permissions
REVOKE INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public FROM viewer_readonly;
```
---
## 🚢 Deploy to Vercel (5 Minutes)
### 1. Push to GitHub
```bash
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/yourusername/punimtag-viewer.git
git push -u origin main
```
### 2. Deploy to Vercel
```bash
# Install Vercel CLI
npm i -g vercel
# Login
vercel login
# Deploy
vercel
# Set environment variables
vercel env add DATABASE_URL
```
Or use the Vercel dashboard:
1. Go to https://vercel.com
2. Import your GitHub repository
3. Add environment variable `DATABASE_URL`
4. Deploy!
---
## 🎯 Next Steps
### Essential Features (Week 1)
- [ ] Create photo grid with infinite scroll
- [ ] Add photo lightbox/viewer
- [ ] Implement search by people
- [ ] Add date range filter
- [ ] Create tag browser
### Nice-to-Have Features (Week 2-3)
- [ ] Add favorites system
- [ ] Implement timeline view
- [ ] Add photo sharing
- [ ] Create mobile navigation
- [ ] Add authentication (if needed)
### Polish (Week 4)
- [ ] Optimize performance (Lighthouse > 90)
- [ ] Add animations
- [ ] Test responsive design
- [ ] Add error handling
- [ ] Write documentation
---
## 📚 Key Documentation
- **Full Plan:** `docs/PHOTO_VIEWER_PLAN.md`
- **Next.js Docs:** https://nextjs.org/docs
- **Prisma Docs:** https://www.prisma.io/docs
- **shadcn/ui:** https://ui.shadcn.com/
---
## 🆘 Troubleshooting
### "Can't connect to database"
```bash
# Test connection manually
psql -U viewer_readonly -d punimtag -h localhost
# Check .env file has correct credentials
cat .env | grep DATABASE_URL
```
### "Module not found: @/..."
```bash
# Check tsconfig.json has paths configured
# Should have: "@/*": ["./*"]
```
### "Prisma Client not generated"
```bash
npx prisma generate
```
### "Images not loading"
```bash
# Check file paths in database
# Configure Next.js image domains in next.config.js
```
---
## 💡 Pro Tips
1. **Use React Server Components** - They're faster and simpler
2. **Enable Image Optimization** - Configure Next.js Image component
3. **Add Loading States** - Use Suspense and loading.tsx files
4. **Implement Infinite Scroll** - Use TanStack Query's useInfiniteQuery
5. **Cache Aggressively** - Photos don't change often
6. **Test Mobile First** - Most users will view on phones
7. **Add Dark Mode** - Use next-themes package
8. **Monitor Performance** - Use Vercel Analytics
---
## 🎨 Design Resources
**Color Schemes:**
- Modern Blue: `#3b82f6`
- Clean White: `#ffffff`
- Dark Mode: `#0f172a`
**Fonts:**
- Inter (Google Fonts)
- SF Pro (System font)
**Inspiration:**
- Google Photos
- iCloud Photos
- Unsplash
---
## 🤝 Need Help?
- Read the full plan: `docs/PHOTO_VIEWER_PLAN.md`
- Check Next.js docs: https://nextjs.org/docs
- Join Next.js Discord: https://nextjs.org/discord
- Check shadcn/ui examples: https://ui.shadcn.com/examples
---
**Ready to build something awesome!** 🚀
Start with Phase 1 in the full plan and iterate based on user feedback.

384
docs/PHOTO_VIEWER_README.md Normal file
View File

@ -0,0 +1,384 @@
# PunimTag Photo Viewer - Documentation Index
## 📖 Welcome
This directory contains comprehensive documentation for the **PunimTag Photo Viewer** project - a modern, fast, and beautiful photo gallery website that connects to your existing PunimTag PostgreSQL database.
---
## 📑 Documentation Structure
### 🎯 Start Here
| Document | Description | Who Should Read |
|----------|-------------|-----------------|
| **[Executive Summary](PHOTO_VIEWER_EXECUTIVE_SUMMARY.md)** | High-level overview, recommendations, and decision guide | 👔 Decision makers, Project sponsors |
| **[Quick Start Guide](PHOTO_VIEWER_QUICKSTART.md)** | Get up and running in 5 minutes | 👨‍💻 Developers (DIY approach) |
### 📚 Detailed Documentation
| Document | Description | Who Should Read |
|----------|-------------|-----------------|
| **[Complete Plan](PHOTO_VIEWER_PLAN.md)** | 20+ page detailed plan with all features, phases, and specifications | 👨‍💻 Developers, 👷 Project managers, 🏗️ Architects |
| **[Architecture](PHOTO_VIEWER_ARCHITECTURE.md)** | System architecture, diagrams, data flows, and technical design | 👨‍💻 Developers, 🏗️ Architects |
---
## 🚀 Quick Navigation
### I want to...
| Goal | Document | Section |
|------|----------|---------|
| **Understand what this is** | [Executive Summary](PHOTO_VIEWER_EXECUTIVE_SUMMARY.md) | Overview |
| **Make a decision on whether to proceed** | [Executive Summary](PHOTO_VIEWER_EXECUTIVE_SUMMARY.md) | Decision Matrix |
| **Estimate costs** | [Executive Summary](PHOTO_VIEWER_EXECUTIVE_SUMMARY.md) | Cost Analysis |
| **See the timeline** | [Executive Summary](PHOTO_VIEWER_EXECUTIVE_SUMMARY.md) | Timeline |
| **Start building right now** | [Quick Start Guide](PHOTO_VIEWER_QUICKSTART.md) | All |
| **Understand the technology choices** | [Complete Plan](PHOTO_VIEWER_PLAN.md) | Technology Stack |
| **See the architecture** | [Architecture](PHOTO_VIEWER_ARCHITECTURE.md) | All |
| **Learn about security** | [Complete Plan](PHOTO_VIEWER_PLAN.md) | Security & Access Control |
| **Understand deployment options** | [Complete Plan](PHOTO_VIEWER_PLAN.md) | Deployment Options |
| **See the roadmap** | [Complete Plan](PHOTO_VIEWER_PLAN.md) | Development Roadmap |
| **Compare with admin interface** | [Architecture](PHOTO_VIEWER_ARCHITECTURE.md) | Comparison Table |
---
## 🎯 Project Overview
### What Is This?
A **modern, lightweight photo viewing website** that allows family members to browse and search photos from your PunimTag database without admin access.
### Key Features
- ✅ **Beautiful Photo Grid** - Responsive, infinite scroll gallery
- ✅ **Powerful Search** - Search by people, dates, tags
- ✅ **Photo Lightbox** - Full-size viewing with metadata
- ✅ **Mobile Optimized** - Works great on all devices
- ✅ **Fast Loading** - Modern optimizations (Lighthouse >90)
- ✅ **Read-Only** - Safe access to your database
### Technology Stack
- **Frontend:** Next.js 14 + React + TypeScript
- **UI:** shadcn/ui + Tailwind CSS
- **Database:** PostgreSQL (existing PunimTag DB)
- **ORM:** Prisma (type-safe queries)
- **State:** TanStack Query (React Query)
- **Hosting:** Vercel (recommended) or Self-hosted
---
## 📊 Documentation at a Glance
### Executive Summary (5 min read)
**File:** `PHOTO_VIEWER_EXECUTIVE_SUMMARY.md`
**Contains:**
- ✅ What we're building and why
- ✅ Technical approach and recommendations
- ✅ Cost analysis ($0-20/month hosting)
- ✅ Timeline (6-12 weeks)
- ✅ Decision criteria (go/no-go)
- ✅ FAQ and next steps
**Best For:** Decision makers who need high-level overview
---
### Quick Start Guide (10 min read)
**File:** `PHOTO_VIEWER_QUICKSTART.md`
**Contains:**
- ✅ 5-minute project setup
- ✅ Step-by-step installation
- ✅ Database configuration
- ✅ First component creation
- ✅ Deployment instructions
- ✅ Troubleshooting tips
**Best For:** Developers ready to start coding
---
### Complete Plan (60 min read)
**File:** `PHOTO_VIEWER_PLAN.md`
**Contains:**
- ✅ Comprehensive feature specifications
- ✅ Detailed technology stack justifications
- ✅ Complete architecture design
- ✅ UI/UX design system
- ✅ Performance optimization strategies
- ✅ Security implementation
- ✅ 6-phase development roadmap
- ✅ Testing strategy
- ✅ Deployment options
- ✅ Cost estimates
- ✅ Risk analysis
**Best For:** Developers, project managers, technical leads
---
### Architecture (30 min read)
**File:** `PHOTO_VIEWER_ARCHITECTURE.md`
**Contains:**
- ✅ System architecture diagrams
- ✅ Data flow diagrams
- ✅ Component hierarchy
- ✅ Technology stack layers
- ✅ Deployment architectures
- ✅ Security architecture
- ✅ Performance optimization
- ✅ Image serving strategy
- ✅ Responsive design strategy
- ✅ Error handling flow
**Best For:** Developers, architects, technical reviewers
---
## 🎨 Project Highlights
### Design Philosophy
**Modern. Clean. Fast.**
- Photo-first design (content is king)
- Minimalist interface (photos speak for themselves)
- Smooth animations (delightful interactions)
- Mobile-first approach (works everywhere)
- Accessible (WCAG AA compliant)
### Performance Targets
| Metric | Target |
|--------|--------|
| Lighthouse Score | >90 |
| Page Load Time | <2s |
| Image Load Time | <1s |
| API Response Time | <200ms |
### Browser Support
- ✅ Chrome/Edge (last 2 versions)
- ✅ Firefox (last 2 versions)
- ✅ Safari (last 2 versions)
- ✅ Mobile Safari (iOS 14+)
- ✅ Chrome Mobile (Android 10+)
---
## 💰 Cost Summary
### Development
| Approach | Cost | Timeline |
|----------|------|----------|
| DIY | Your time (200-300 hrs) | 12 weeks |
| Freelancer | $18K-28K | 8-12 weeks |
| Agency | $30K-50K | 6-10 weeks |
### Hosting (Monthly)
| Option | Cost | Best For |
|--------|------|----------|
| Vercel Free | $0 | Small families |
| Vercel Pro | $20 | Medium usage |
| VPS | $12-24 | Self-hosted |
| Home Server | $0* | Local network |
**Recommended:** Vercel Free Tier → upgrade if needed
---
## ⏱️ Timeline
### Fast Track: 6 Weeks
1. **Weeks 1-2:** Foundation (setup, DB, layout)
2. **Weeks 3-4:** Core Features (gallery, search)
3. **Week 5:** Polish (responsive, animations)
4. **Week 6:** Launch (deploy, test)
### Standard Track: 12 Weeks
1. **Weeks 1-2:** Foundation + Auth
2. **Weeks 3-4:** Core Features
3. **Weeks 5-6:** Search & Filters
4. **Weeks 7-8:** Polish & Optimization
5. **Weeks 9-10:** Advanced Features
6. **Weeks 11-12:** Testing & Launch
---
## 🚦 Decision Guide
### ✅ Proceed If:
- You have PostgreSQL database with photos
- You want to share photos with family
- You have budget/time for development
- You value UX and modern design
- You need mobile-optimized browsing
### ❌ Wait If:
- Database has <100 photos
- Happy with admin interface for viewing
- Budget constraints (<$500)
- Don't need mobile experience
- Need write operations (upload/edit)
---
## 🎬 Getting Started
### Option A: Hire Developer
1. Share this documentation with developer
2. Approve budget and timeline
3. Provide read-only database access
4. Review progress weekly
5. Test and provide feedback
6. Launch!
### Option B: DIY
1. Read [Quick Start Guide](PHOTO_VIEWER_QUICKSTART.md)
2. Follow setup instructions
3. Build phase by phase
4. Test with real users
5. Deploy and iterate
### Option C: Hybrid
1. Hire developer for initial setup
2. Learn and customize yourself
3. Developer available for support
---
## 📚 Additional Resources
### External Documentation
- **Next.js:** https://nextjs.org/docs
- **Prisma:** https://www.prisma.io/docs
- **shadcn/ui:** https://ui.shadcn.com/
- **TanStack Query:** https://tanstack.com/query/latest
- **Tailwind CSS:** https://tailwindcss.com/docs
### Inspiration
- **Google Photos:** https://photos.google.com
- **iCloud Photos:** https://www.icloud.com/photos
- **Unsplash:** https://unsplash.com
### Example Projects
- Next.js + Prisma: https://github.com/vercel/next.js/tree/canary/examples/with-prisma
- Photo Gallery: https://github.com/topics/photo-gallery
---
## 🆘 Support & Help
### Common Questions
**Q: Can I use this with SQLite?**
A: Yes, but PostgreSQL is recommended for better performance with large photo collections.
**Q: Do I need to migrate my database?**
A: No! The viewer reads from your existing PunimTag database.
**Q: Can I customize the design?**
A: Absolutely! All colors, fonts, and layouts are customizable.
**Q: What if I have 100K photos?**
A: The architecture scales well with proper indexing and pagination.
**Q: Is authentication required?**
A: No, it's optional. Configure based on your privacy needs.
### Getting Help
1. Check the documentation (you're reading it!)
2. Review the FAQ in Executive Summary
3. Check Next.js documentation
4. Search GitHub issues/discussions
5. Ask in Next.js Discord community
---
## 📝 Version History
| Version | Date | Changes |
|---------|------|---------|
| 1.0 | Nov 14, 2025 | Initial comprehensive plan |
---
## 🙏 Credits
**Planned and documented by:** AI Assistant (Claude Sonnet 4.5)
**For:** PunimTag Project
**Purpose:** Family photo sharing and browsing
---
## ✅ Checklist: Before Starting Development
### Planning Phase
- [ ] Read Executive Summary
- [ ] Review Complete Plan
- [ ] Understand Architecture
- [ ] Make go/no-go decision
- [ ] Approve budget
- [ ] Approve timeline
### Technical Preparation
- [ ] Verify PostgreSQL database access
- [ ] Create read-only database user
- [ ] Test database connection
- [ ] Identify photo storage location
- [ ] Choose hosting platform (Vercel vs self-hosted)
- [ ] Set up development environment
### Team Preparation
- [ ] Assign developer(s)
- [ ] Set up project management (GitHub, etc.)
- [ ] Schedule regular check-ins
- [ ] Identify test users
- [ ] Plan feedback process
### Ready to Start? 🚀
- [ ] Follow [Quick Start Guide](PHOTO_VIEWER_QUICKSTART.md)
- [ ] Begin Phase 1 of [Complete Plan](PHOTO_VIEWER_PLAN.md)
---
## 🎯 Success Criteria
This project will be successful when:
**Users love it** - Family members prefer it over admin interface for browsing
**It's fast** - Lighthouse score >90, loads in <2 seconds
**It's beautiful** - Modern design, smooth animations
**It works everywhere** - Great experience on mobile, tablet, desktop
**It's reliable** - 99.9% uptime, handles errors gracefully
**It's maintainable** - Clean code, good documentation
---
## 🎊 Let's Build Something Amazing!
You now have everything you need to create a world-class photo viewing experience for your family. The plan is comprehensive, the technology is proven, and the path is clear.
**Choose your starting point:**
- 👔 **Decision maker?** → Read [Executive Summary](PHOTO_VIEWER_EXECUTIVE_SUMMARY.md)
- 👨‍💻 **Developer?** → Follow [Quick Start Guide](PHOTO_VIEWER_QUICKSTART.md)
- 🏗️ **Architect?** → Study [Architecture](PHOTO_VIEWER_ARCHITECTURE.md)
- 👷 **Project manager?** → Review [Complete Plan](PHOTO_VIEWER_PLAN.md)
**Ready when you are!** 🚀
---
**Questions?** Start with the Executive Summary and work your way through the documentation. Everything you need is here.
**Good luck!** 🎉