All checks were successful
CI / skip-ci-check (push) Successful in 1m23s
CI / lint-and-type-check (push) Successful in 1m46s
CI / test (push) Successful in 1m51s
CI / build (push) Successful in 1m54s
CI / secret-scanning (push) Successful in 1m24s
CI / dependency-scan (push) Successful in 1m28s
CI / sast-scan (push) Successful in 2m32s
CI / workflow-summary (push) Successful in 1m21s
# Merge Request: Production Deployment Fixes and Enhancements ## Summary This MR includes critical fixes for production deployment, authentication improvements, file upload serving, and monitoring capabilities. All changes have been tested and are ready for production. ## 🐛 Critical Fixes ### 1. Authentication & Session Management - **Fixed TypeScript error in session callback** (`lib/auth.ts`) - Removed `return null` that caused build failures - Session callback now always returns a valid session object - **Fixed login redirect loop** (`app/login/page.tsx`) - Changed from `router.push()` to `window.location.href` for full page reload - Ensures session cookie is available before middleware checks - **Created proper middleware** (`proxy.ts`) - Next.js 16 requires `proxy.ts` instead of `middleware.ts` - Fixed authentication checks in Edge runtime - Explicitly specifies cookie name for `getToken` ### 2. Build & Deployment - **Fixed Prisma initialization** (`lib/prisma.ts`) - Made Prisma client initialization lazy to fix build without DATABASE_URL - Uses Proxy pattern for on-demand initialization - Prevents build failures when DATABASE_URL not set ### 3. File Upload & Serving - **Fixed photo upload serving** (`app/api/uploads/[filename]/route.ts`) - Created dedicated API route to serve uploaded files - Files now served via `/api/uploads/[filename]` instead of static `/uploads/` - Ensures files are accessible regardless of filesystem location - Added file existence verification and proper error handling - **Updated upload routes** to use new API endpoint - `app/api/photos/upload/route.ts` - Updated to use `/api/uploads/` URLs - `app/api/photos/upload-multiple/route.ts` - Updated to use `/api/uploads/` URLs - **Fixed photo display components** - `components/PhotoThumbnail.tsx` - Uses regular `img` tag for uploads - `components/PhotoImage.tsx` - Uses regular `img` tag for uploads - Avoids Next.js Image component issues with dynamically uploaded files ### 4. Middleware & Route Protection - **Updated proxy middleware** (`proxy.ts`) - Added `/uploads` and `/api/uploads` to public routes - Added comprehensive activity logging - Improved error handling and logging ## ✨ New Features ### Activity Logging - **Created activity logging utility** (`lib/activity-log.ts`) - Structured logging for user actions - Tracks: page visits, photo uploads, guess submissions - Includes user info, IP, timestamps, and action details - **Added activity logging to key routes** - `proxy.ts` - Logs all page visits and API calls - `app/api/photos/upload/route.ts` - Logs photo uploads - `app/api/photos/[photoId]/guess/route.ts` - Logs guess submissions ### Monitoring - **Activity monitoring commands** - Watch logs: `sudo journalctl -u app-backend -f | grep -E "\[ACTIVITY\]|\[PHOTO_UPLOAD\]|\[GUESS_SUBMIT\]"` - Filter by user, action type, or time range ## 📝 Documentation Updates - **README.md** - Added deployment notes section - Added file upload details and troubleshooting - Added activity monitoring commands - Added database query examples - Updated troubleshooting section - **ARCHITECTURE.md** - Updated middleware references (proxy.ts instead of middleware.ts) - Added activity logging documentation - Updated photo upload flow with file upload details - Added file serving architecture - Updated guess submission flow - **CLEANUP.md** (new) - Created cleanup checklist for future improvements - Documents debug code and verbose logging - Provides recommendations for optimization ## 🔧 Technical Changes ### Files Modified - `lib/auth.ts` - Fixed session callback return type - `app/login/page.tsx` - Fixed redirect to use full page reload - `proxy.ts` - Created/updated middleware with activity logging - `lib/prisma.ts` - Made initialization lazy - `app/api/photos/upload/route.ts` - Updated file serving, added logging - `app/api/photos/upload-multiple/route.ts` - Updated file serving - `components/PhotoThumbnail.tsx` - Fixed image display - `components/PhotoImage.tsx` - Fixed image display ### Files Created - `app/api/uploads/[filename]/route.ts` - File serving API route - `lib/activity-log.ts` - Activity logging utility - `CLEANUP.md` - Cleanup checklist ## ✅ Testing - [x] Authentication flow tested (login, session persistence) - [x] Photo upload tested (file and URL uploads) - [x] Photo display tested (uploaded files visible to all users) - [x] Guess submission tested - [x] Build tested (no TypeScript errors) - [x] Middleware tested (route protection working) - [x] Activity logging verified ## 🚀 Deployment Notes ### Environment Variables Required - `NODE_ENV=production` - `NEXTAUTH_URL` - Production domain - `NEXTAUTH_SECRET` - Secret key - `AUTH_TRUST_HOST=true` (if using reverse proxy) - `DATABASE_URL` - Production database connection ### Post-Deployment 1. Verify `public/uploads/` directory exists and has write permissions 2. Test photo upload and verify files are accessible 3. Monitor activity logs to ensure logging is working 4. Verify authentication flow works correctly ### Monitoring - Watch activity logs: `sudo journalctl -u app-backend -f | grep -E "\[ACTIVITY\]|\[PHOTO_UPLOAD\]|\[GUESS_SUBMIT\]"` - Check for errors: `sudo journalctl -u app-backend --since "1 hour ago" | grep -i error` ## 🔄 Breaking Changes **None** - All changes are backward compatible. Existing photos with `/uploads/` URLs may need to be updated to `/api/uploads/` if files are not accessible, but the system will continue to work. ## 📋 Migration Notes ### For Existing Photos - Photos uploaded before this change use `/uploads/` URLs - New photos use `/api/uploads/` URLs - Old photos will continue to work if files exist in `public/uploads/` - Consider migrating old photo URLs if needed (optional) ## 🎯 Next Steps (Future) See `CLEANUP.md` for recommended cleanup tasks: - Reduce verbose logging in production - Add log levels (DEBUG, INFO, WARN, ERROR) - Protect debug endpoints - Optimize activity logging --- **Ready for Production:** ✅ Yes **Breaking Changes:** ❌ No **Requires Migration:** ⚠️ Optional (old photo URLs) Reviewed-on: #3
344 lines
11 KiB
Markdown
344 lines
11 KiB
Markdown
# MirrorMatch
|
|
|
|
A photo guessing game where users upload photos and other users guess who is in the picture to earn points. Built with Next.js, PostgreSQL, and NextAuth.
|
|
|
|
## 📚 Important: Read Documentation First
|
|
|
|
**Before making code changes, please read:**
|
|
- **`.cursor/rules/mirrormatch.mdc`** - Project rules and guidelines
|
|
- **`ARCHITECTURE.md`** - System design and data flows
|
|
- **`CONTRIBUTING.md`** - Coding conventions and workflow
|
|
- **`SECURITY.md`** - Security practices
|
|
- **This README** - Setup and usage
|
|
|
|
**Keep documentation updated:** When you modify code that changes behavior or architecture, update the relevant documentation files to keep them in sync.
|
|
|
|
## Features
|
|
|
|
- **User Management**: Admin can create users with email/password authentication
|
|
- **Photo Upload**: Users can upload photos with answer names
|
|
- **Guessing Game**: Users guess who is in photos to earn points
|
|
- **Email Notifications**: Users receive emails when new photos are uploaded
|
|
- **Leaderboard**: Track user points and rankings
|
|
- **Profile Management**: Users can view their points and change passwords
|
|
|
|
## Tech Stack
|
|
|
|
- **Framework**: Next.js 16 (App Router)
|
|
- **Language**: TypeScript
|
|
- **Database**: PostgreSQL
|
|
- **ORM**: Prisma
|
|
- **Authentication**: NextAuth.js (Credentials Provider)
|
|
- **Styling**: Tailwind CSS
|
|
- **Email**: Nodemailer (Ethereal in dev, SMTP in production)
|
|
|
|
## Prerequisites
|
|
|
|
- Node.js 18+ and npm
|
|
- PostgreSQL database (local or remote)
|
|
- For production: SMTP email server credentials
|
|
|
|
## Installation
|
|
|
|
1. **Clone the repository** (if applicable) or navigate to the project directory:
|
|
```bash
|
|
cd mirrormatch
|
|
```
|
|
|
|
2. **Install dependencies**:
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
3. **Set up environment variables**:
|
|
Create a `.env` file in the root directory with the following variables:
|
|
```env
|
|
# Database
|
|
DATABASE_URL="postgresql://user:password@localhost:5432/mirrormatch?schema=public"
|
|
|
|
# NextAuth
|
|
NEXTAUTH_URL="http://localhost:3000"
|
|
NEXTAUTH_SECRET="your-secret-key-here-generate-with-openssl-rand-base64-32"
|
|
|
|
# Email Configuration (for production)
|
|
SMTP_HOST="smtp.example.com"
|
|
SMTP_PORT="587"
|
|
SMTP_USER="your-email@example.com"
|
|
SMTP_PASSWORD="your-email-password"
|
|
SMTP_FROM="MirrorMatch <noreply@mirrormatch.com>"
|
|
```
|
|
|
|
**Generate NEXTAUTH_SECRET**:
|
|
```bash
|
|
openssl rand -base64 32
|
|
```
|
|
|
|
**Note**: In development, emails will use Ethereal (test emails) or console logging. No SMTP config is needed for dev mode.
|
|
|
|
4. **Set up the database**:
|
|
```bash
|
|
# Generate Prisma Client
|
|
npm run db:generate
|
|
|
|
# Run migrations
|
|
npm run db:migrate
|
|
|
|
# Or push schema directly (for development)
|
|
npm run db:push
|
|
```
|
|
|
|
5. **Seed the database** (creates default admin user):
|
|
```bash
|
|
npm run db:seed
|
|
```
|
|
|
|
This creates an admin user with:
|
|
- Email: `admin@mirrormatch.com`
|
|
- Password: `admin123`
|
|
- **⚠️ Important**: Change this password after first login!
|
|
|
|
## Basic Usage
|
|
|
|
### Workflow Overview
|
|
|
|
1. **Admin creates users:**
|
|
- Admin logs in and navigates to `/admin`
|
|
- Creates new users with email, password, and role
|
|
- Users receive temporary passwords
|
|
|
|
2. **Users log in:**
|
|
- Users navigate to `/login`
|
|
- Enter email and password
|
|
- Access the main application
|
|
|
|
3. **Users upload photos:**
|
|
- Navigate to `/upload`
|
|
- Enter photo URL and answer name (the correct name to guess)
|
|
- Photo is saved and emails are sent to all other users
|
|
|
|
4. **Users guess photos:**
|
|
- View photos on `/photos` page
|
|
- Click a photo to view details
|
|
- Submit guesses for who is in the photo
|
|
- Earn points for correct guesses (case-insensitive matching)
|
|
|
|
5. **Leaderboard:**
|
|
- View rankings on `/leaderboard` page
|
|
- See all users sorted by points
|
|
- Track your own position
|
|
|
|
### Key Features
|
|
|
|
- **Admin Panel:** Create and manage users, reset passwords
|
|
- **Photo Upload:** Upload photos with answer names
|
|
- **Guessing System:** Submit guesses and earn points
|
|
- **Email Notifications:** Get notified when new photos are uploaded
|
|
- **Leaderboard:** Track user rankings by points
|
|
- **Profile Management:** View points and change password
|
|
|
|
## Running the Application
|
|
|
|
### Development
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
Open [http://localhost:3000](http://localhost:3000) in your browser.
|
|
|
|
### Production
|
|
|
|
```bash
|
|
npm run build
|
|
npm start
|
|
```
|
|
|
|
### Deployment Notes
|
|
|
|
**Important Configuration:**
|
|
- Ensure `NODE_ENV=production` is set in production
|
|
- Set `NEXTAUTH_URL` to your production domain (e.g., `https://yourdomain.com`)
|
|
- Set `AUTH_TRUST_HOST=true` if using reverse proxy
|
|
- Ensure `DATABASE_URL` points to your production database
|
|
- Files are stored in `public/uploads/` directory - ensure this directory persists across deployments
|
|
|
|
**File Uploads:**
|
|
- Photos are uploaded to `public/uploads/` directory
|
|
- Files are served via `/api/uploads/[filename]` API route
|
|
- Ensure the uploads directory has proper write permissions
|
|
- Files are stored on the filesystem (not in database)
|
|
|
|
**Monitoring Activity:**
|
|
- User activity is logged to console/systemd logs
|
|
- Watch logs in real-time: `sudo journalctl -u app-backend -f | grep -E "\[ACTIVITY\]|\[PHOTO_UPLOAD\]|\[GUESS_SUBMIT\]"`
|
|
- Activity logs include: page visits, photo uploads, guess submissions
|
|
|
|
## Database Commands
|
|
|
|
- `npm run db:generate` - Generate Prisma Client
|
|
- `npm run db:migrate` - Run database migrations
|
|
- `npm run db:push` - Push schema changes to database (dev only)
|
|
- `npm run db:studio` - Open Prisma Studio (database GUI)
|
|
- `npm run db:seed` - Seed database with initial admin user
|
|
|
|
### Querying the Database
|
|
|
|
**Get all photo answers:**
|
|
```bash
|
|
psql "postgresql://user:password@host:5432/database" -c "SELECT \"answerName\" FROM \"Photo\" ORDER BY \"createdAt\" DESC;"
|
|
```
|
|
|
|
**Get answers with uploader info:**
|
|
```bash
|
|
psql "postgresql://user:password@host:5432/database" -c "SELECT p.\"answerName\", p.url, u.name as uploader, p.\"createdAt\" FROM \"Photo\" p JOIN \"User\" u ON p.\"uploaderId\" = u.id ORDER BY p.\"createdAt\" DESC;"
|
|
```
|
|
|
|
## Creating the First Admin User
|
|
|
|
The seed script automatically creates an admin user. If you need to create one manually:
|
|
|
|
1. Run the seed script: `npm run db:seed`
|
|
2. Or use Prisma Studio: `npm run db:studio` and create a user with `role: "ADMIN"`
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
mirrormatch/
|
|
├── app/ # Next.js App Router pages
|
|
│ ├── api/ # API routes
|
|
│ │ ├── admin/ # Admin API routes
|
|
│ │ ├── auth/ # NextAuth routes
|
|
│ │ ├── photos/ # Photo-related API routes
|
|
│ │ └── profile/ # Profile API routes
|
|
│ ├── admin/ # Admin panel page
|
|
│ ├── leaderboard/ # Leaderboard page
|
|
│ ├── login/ # Login page
|
|
│ ├── photos/ # Photos listing and detail pages
|
|
│ ├── profile/ # User profile page
|
|
│ └── upload/ # Photo upload page
|
|
├── components/ # React components
|
|
├── lib/ # Utility libraries
|
|
│ ├── auth.ts # NextAuth configuration
|
|
│ ├── email.ts # Email sending utilities
|
|
│ ├── prisma.ts # Prisma client instance
|
|
│ └── utils.ts # Helper functions
|
|
├── prisma/ # Prisma schema and migrations
|
|
│ ├── schema.prisma # Database schema
|
|
│ └── seed.ts # Database seed script
|
|
└── types/ # TypeScript type definitions
|
|
```
|
|
|
|
## Features Overview
|
|
|
|
### Authentication
|
|
- Email/password login via NextAuth
|
|
- Protected routes with middleware
|
|
- Role-based access control (ADMIN/USER)
|
|
|
|
### Admin Panel (`/admin`)
|
|
- View all users
|
|
- Create new users
|
|
- Reset user passwords
|
|
- View user points and roles
|
|
|
|
### Photo Upload (`/upload`)
|
|
- Upload photos via file upload or URL
|
|
- Files are stored in `public/uploads/` directory
|
|
- Files are served via `/api/uploads/[filename]` API route
|
|
- Set answer name for guessing
|
|
- Automatically sends email notifications to all other users
|
|
- Duplicate file detection (SHA256 hash)
|
|
|
|
### Photo Guessing (`/photos/[id]`)
|
|
- View photo and uploader info
|
|
- Submit guesses
|
|
- Get instant feedback (correct/wrong)
|
|
- Earn points for correct guesses
|
|
- Case-insensitive matching
|
|
|
|
### Leaderboard (`/leaderboard`)
|
|
- View all users ranked by points
|
|
- See your own ranking highlighted
|
|
|
|
### Profile (`/profile`)
|
|
- View your points and account info
|
|
- Change password (requires current password)
|
|
|
|
## Email Configuration
|
|
|
|
### Development
|
|
In development mode, the app uses:
|
|
- **Ethereal Email** (if available) - provides test email accounts with preview URLs
|
|
- **Console transport** (fallback) - logs emails to console
|
|
|
|
Check the console for email preview URLs when using Ethereal.
|
|
|
|
### Production
|
|
Set up SMTP credentials in `.env`:
|
|
- `SMTP_HOST` - Your SMTP server hostname
|
|
- `SMTP_PORT` - SMTP port (usually 587 for TLS, 465 for SSL)
|
|
- `SMTP_USER` - SMTP username
|
|
- `SMTP_PASSWORD` - SMTP password
|
|
- `SMTP_FROM` - From address for emails
|
|
|
|
## Security Notes
|
|
|
|
- Passwords are hashed using bcrypt
|
|
- NextAuth handles session management
|
|
- Middleware protects routes
|
|
- Admin routes are restricted to ADMIN role
|
|
- SQL injection protection via Prisma
|
|
|
|
## Troubleshooting
|
|
|
|
### Database Connection Issues
|
|
- Verify `DATABASE_URL` is correct
|
|
- Ensure PostgreSQL is running
|
|
- Check database exists and user has permissions
|
|
|
|
### Email Not Sending
|
|
- In dev: Check console for Ethereal preview URLs
|
|
- In production: Verify SMTP credentials
|
|
- Check email service logs
|
|
|
|
### Authentication Issues
|
|
- Verify `NEXTAUTH_SECRET` is set
|
|
- Check `NEXTAUTH_URL` matches your app URL
|
|
- Set `AUTH_TRUST_HOST=true` if using reverse proxy
|
|
- Clear browser cookies if needed
|
|
- Check middleware logs: `sudo journalctl -u app-backend | grep "Middleware"`
|
|
|
|
### Photo Upload Issues
|
|
- Verify `public/uploads/` directory exists and has write permissions
|
|
- Check file upload logs: `sudo journalctl -u app-backend | grep "UPLOAD"`
|
|
- Ensure files are being saved: check `public/uploads/` directory
|
|
- Files are served via `/api/uploads/[filename]` - verify API route is accessible
|
|
|
|
### Build Issues
|
|
- If build fails with `DATABASE_URL not set`, this is expected - Prisma initialization is lazy
|
|
- Ensure all environment variables are set in production
|
|
- Check for TypeScript errors: `npm run type-check`
|
|
|
|
## Documentation
|
|
|
|
This project maintains comprehensive documentation:
|
|
|
|
- **README.md** (this file) - Setup, installation, and basic usage
|
|
- **ARCHITECTURE.md** - System architecture, data models, and application flows
|
|
- **CONTRIBUTING.md** - Coding conventions and development workflow
|
|
- **SECURITY.md** - Security practices and vulnerability reporting
|
|
- **.cursor/rules/mirrormatch.mdc** - Project rules for AI tools and developers
|
|
|
|
**For Developers and AI Tools:**
|
|
|
|
**⚠️ Important:** Before making code changes, read `.cursor/rules/mirrormatch.mdc`, `ARCHITECTURE.md`, `CONTRIBUTING.md`, `SECURITY.md`, and this README. Keep them updated when behavior or architecture changes.
|
|
|
|
- Always read the relevant documentation before making changes
|
|
- Update documentation when behavior or architecture changes
|
|
- Keep all documentation files in sync with code changes
|
|
- Follow the guidelines in each document
|
|
|
|
## License
|
|
|
|
MIT
|