Humanize READMEs and guides for clearer, professional tone
CI / skip-ci-check (pull_request) Successful in 30s
CI / secret-scan (pull_request) Successful in 29s
CI / node-ci (pull_request) Successful in 2m23s

Align with project-template docs/writing-docs.md: plain openings, no
emoji decoration, archive scratch plans where they cluttered live docs.
This commit is contained in:
2026-08-05 14:52:47 -04:00
parent d6b4d2fe51
commit cc01736c81
5 changed files with 62 additions and 351 deletions
+5 -5
View File
@@ -148,11 +148,11 @@ Write clear, descriptive commit messages:
- **Reference issues:** If applicable, reference issue numbers - **Reference issues:** If applicable, reference issue numbers
**Examples:** **Examples:**
- ✅ "Add password strength validation to change password form" - "Add password strength validation to change password form"
- ✅ "Fix case-insensitive guess matching bug" - "Fix case-insensitive guess matching bug"
- ✅ "Update README with new environment variables" - "Update README with new environment variables"
- ❌ "Fixed stuff" - "Fixed stuff"
- ❌ "Updates" - "Updates"
### Code Review Checklist ### Code Review Checklist
+6 -6
View File
@@ -2,7 +2,7 @@
This document contains ideas, suggestions, and potential enhancements to make MirrorMatch better, faster, and more professional. This document contains ideas, suggestions, and potential enhancements to make MirrorMatch better, faster, and more professional.
## 🚀 Performance Optimizations ## Performance Optimizations
### Database & Query Optimization ### Database & Query Optimization
- [ ] **Add database indexes** - Create indexes on frequently queried fields (`Photo.createdAt`, `User.points`) to speed up queries - [ ] **Add database indexes** - Create indexes on frequently queried fields (`Photo.createdAt`, `User.points`) to speed up queries
@@ -64,7 +64,7 @@ This document contains ideas, suggestions, and potential enhancements to make Mi
- [ ] **CDN integration** - Add CDN for static assets and uploaded images to reduce server load - [ ] **CDN integration** - Add CDN for static assets and uploaded images to reduce server load
- **Why:** Serving files from your server uses bandwidth and slows responses. A CDN serves files from locations closer to users, reducing latency by 50-80% and offloading server load. - **Why:** Serving files from your server uses bandwidth and slows responses. A CDN serves files from locations closer to users, reducing latency by 50-80% and offloading server load.
## 🎨 UI/UX Enhancements ## UI/UX Enhancements
### User Interface ### User Interface
- [ ] **Dark mode support** - Add dark mode toggle with user preference persistence - [ ] **Dark mode support** - Add dark mode toggle with user preference persistence
@@ -128,7 +128,7 @@ This document contains ideas, suggestions, and potential enhancements to make Mi
- [ ] **Photo filtering** - Add filters to show: unguessed photos, correct guesses, wrong guesses, and photos by specific users - [ ] **Photo filtering** - Add filters to show: unguessed photos, correct guesses, wrong guesses, and photos by specific users
- **Why:** Users want to focus on specific subsets of photos. Filtering helps users find unguessed photos to play, review their performance, or follow specific uploaders, significantly improving usability. - **Why:** Users want to focus on specific subsets of photos. Filtering helps users find unguessed photos to play, review their performance, or follow specific uploaders, significantly improving usability.
## 🔒 Security Improvements ## Security Improvements
- [ ] **CSRF protection** - Implement CSRF tokens for all state-changing operations - [ ] **CSRF protection** - Implement CSRF tokens for all state-changing operations
- **Why:** CSRF attacks can trick users into performing unwanted actions. CSRF protection is a security best practice that prevents unauthorized state changes and protects user accounts. - **Why:** CSRF attacks can trick users into performing unwanted actions. CSRF protection is a security best practice that prevents unauthorized state changes and protects user accounts.
@@ -151,7 +151,7 @@ This document contains ideas, suggestions, and potential enhancements to make Mi
- [ ] **Audit logging** - Log all admin actions for security auditing and compliance - [ ] **Audit logging** - Log all admin actions for security auditing and compliance
- **Why:** Admin actions can have significant impact. Audit logs provide accountability, help detect unauthorized access, and are essential for security compliance and incident investigation. - **Why:** Admin actions can have significant impact. Audit logs provide accountability, help detect unauthorized access, and are essential for security compliance and incident investigation.
## 📊 Features & Functionality ## Features & Functionality
### Game Mechanics ### Game Mechanics
- [ ] **Streak tracking** - Track consecutive correct guesses and display current streak - [ ] **Streak tracking** - Track consecutive correct guesses and display current streak
@@ -208,7 +208,7 @@ This document contains ideas, suggestions, and potential enhancements to make Mi
- [ ] **Photo approval workflow** - Add optional admin approval workflow (can be toggled on/off) - [ ] **Photo approval workflow** - Add optional admin approval workflow (can be toggled on/off)
- **Why:** Content moderation ensures quality and safety. An approval workflow lets admins control what goes public, prevents inappropriate content, and maintains content standards. - **Why:** Content moderation ensures quality and safety. An approval workflow lets admins control what goes public, prevents inappropriate content, and maintains content standards.
## 🧪 Testing & Quality ## Testing & Quality
- [ ] **Increase test coverage** - Expand test coverage to all critical paths and edge cases - [ ] **Increase test coverage** - Expand test coverage to all critical paths and edge cases
- **Why:** Bugs in production are expensive and damage trust. Comprehensive tests catch issues early, reduce regressions, and give confidence when making changes. - **Why:** Bugs in production are expensive and damage trust. Comprehensive tests catch issues early, reduce regressions, and give confidence when making changes.
@@ -237,7 +237,7 @@ This document contains ideas, suggestions, and potential enhancements to make Mi
- [ ] **Error logging and monitoring** - Create comprehensive error logging and monitoring system - [ ] **Error logging and monitoring** - Create comprehensive error logging and monitoring system
- **Why:** You can't fix what you can't see. Error monitoring catches production bugs, provides context for debugging, and helps prioritize fixes based on impact. - **Why:** You can't fix what you can't see. Error monitoring catches production bugs, provides context for debugging, and helps prioritize fixes based on impact.
## 🔧 Technical Improvements ## Technical Improvements
### Architecture ### Architecture
- [ ] **Microservices migration** - Consider migrating to microservices if scale requires it - [ ] **Microservices migration** - Consider migrating to microservices if scale requires it
+37 -326
View File
@@ -1,348 +1,59 @@
# MirrorMatch # 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. Photo guessing game: upload a photo, others guess who is in it, points on
the leaderboard. Next.js, PostgreSQL, Prisma, NextAuth.
## 📚 Important: Read Documentation First Status: active. MIT. See [LICENSE](LICENSE).
**Before making code changes, please read:** ## Setup
- **`.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 ```bash
npm run dev cd mirrormatch # or mirror_match
npm install
cp .env.example .env # if present; otherwise create .env
``` ```
Open [http://localhost:3000](http://localhost:3000) in your browser. Required env (placeholders):
### Production ```env
DATABASE_URL="postgresql://user:password@localhost:5432/mirrormatch?schema=public"
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="$(openssl rand -base64 32)"
# Production email:
# SMTP_HOST= SMTP_PORT= SMTP_USER= SMTP_PASSWORD= SMTP_FROM=
```
```bash ```bash
npm run build npm run db:generate
npm start npm run db:migrate # or npm run db:push for quick local
npm run db:seed # default admin: admin@mirrormatch.com / admin123 — change it
npm run dev # http://localhost:3000
``` ```
### Deployment Notes Dev mail can use Ethereal or console; SMTP is for production.
**Important Configuration:** ## What it does
- 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:** - Admin creates users (email/password)
- Photos are uploaded to `public/uploads/` directory - Users upload photos with an answer name
- Files are served via `/api/uploads/[filename]` API route - Others guess for points; leaderboard ranks scores
- Ensure the uploads directory has proper write permissions - Optional email when new photos land
- Profile: view points, change password
**Upload Endpoints:** ## Docs
- `POST /api/photos/upload` - Single photo upload (supports both file and URL uploads)
- `POST /api/photos/upload-multiple` - Multiple photo uploads in batch (used by upload page)
- Files are stored on the filesystem (not in database)
**Monitoring Activity:** | Doc | Purpose |
- 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\]"` | [ARCHITECTURE.md](ARCHITECTURE.md) | Design |
- Activity logs include: page visits, photo uploads, guess submissions | [CONTRIBUTING.md](CONTRIBUTING.md) | Conventions |
- **Note:** For local development, use `./watch-activity.sh` script (if systemd/journalctl is not available, check application logs directly) | [SECURITY.md](SECURITY.md) | Security practices |
| [TESTING.md](TESTING.md) | Tests |
| `.cursor/rules/mirrormatch.mdc` | Agent rules |
## Database Commands ## Production
- `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 ```bash
psql "postgresql://user:password@host:5432/database" -c "SELECT \"answerName\" FROM \"Photo\" ORDER BY \"createdAt\" DESC;" NODE_ENV=production npm run build && npm start
``` ```
**Get answers with uploader info:** Set real `NEXTAUTH_SECRET`, SMTP, and rotate the seeded admin password.
```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
+6 -6
View File
@@ -167,12 +167,12 @@ When adding new features, ensure:
## Known Security Considerations ## Known Security Considerations
**Current Implementation:** **Current Implementation:**
- ✅ Passwords hashed with bcrypt - Passwords hashed with bcrypt
- ✅ Session management via NextAuth - Session management via NextAuth
- ✅ Route protection via middleware - Route protection via middleware
- ✅ Role-based access control - Role-based access control
- ✅ Input validation on server side - Input validation on server side
- ✅ SQL injection prevention via Prisma - SQL injection prevention via Prisma
**Future Considerations:** **Future Considerations:**
- Consider rate limiting for API routes - Consider rate limiting for API routes
+8 -8
View File
@@ -6,10 +6,10 @@ This guide will help you set up and test the MirrorMatch application locally.
Before starting, ensure you have: Before starting, ensure you have:
- ✅ **Node.js 18+** installed (`node --version`) - **Node.js 18+** installed (`node --version`)
- ✅ **npm** installed (`npm --version`) - **npm** installed (`npm --version`)
- ✅ **PostgreSQL** installed and running (`psql --version`) - **PostgreSQL** installed and running (`psql --version`)
- ✅ **Git** (if cloning the repository) - **Git** (if cloning the repository)
## Step-by-Step Setup ## Step-by-Step Setup
@@ -99,7 +99,7 @@ This creates the default admin user:
- **Email:** `admin@mirrormatch.com` - **Email:** `admin@mirrormatch.com`
- **Password:** `admin123` - **Password:** `admin123`
⚠️ **Important:** Change this password after first login! **Important:** Change this password after first login!
### 6. Start the Development Server ### 6. Start the Development Server
@@ -213,7 +213,7 @@ npm run db:generate
**Error:** `Migration failed` **Error:** `Migration failed`
**Solutions:** **Solutions:**
- Reset database (⚠️ deletes all data): - Reset database ( deletes all data):
```bash ```bash
npm run db:push -- --force-reset npm run db:push -- --force-reset
``` ```
@@ -274,7 +274,7 @@ Opens a GUI at [http://localhost:5555](http://localhost:5555) to browse and edit
### Reset Database ### Reset Database
⚠️ **Warning:** This deletes all data! **Warning:** This deletes all data!
```bash ```bash
npm run db:push -- --force-reset npm run db:push -- --force-reset
@@ -317,4 +317,4 @@ After testing locally:
--- ---
**Happy Testing! 🎯** **Happy Testing! **