This PR adds comprehensive photo management features, duplicate detection, attempt limits, penalty system improvements, and admin photo deletion capabilities to the MirrorMatch application. #1

Merged
ilia merged 12 commits from dev into main 2026-01-03 10:19:59 -05:00
Owner

Photo Management and Game Features

Summary

This PR adds comprehensive photo management features, duplicate detection, attempt limits, penalty system improvements, and admin photo deletion capabilities to the MirrorMatch application.

Features Added

1. Duplicate Photo Detection

  • File-based duplicates: Calculates SHA256 hash of uploaded files to detect duplicate content
  • URL-based duplicates: Checks for duplicate photo URLs
  • Prevents users from uploading the same photo multiple times
  • Returns HTTP 409 (Conflict) with clear error messages

2. Maximum Attempts Per Photo

  • Uploaders can set a maximum number of guesses allowed per user for each photo
  • Default: unlimited (null or 0)
  • UI displays remaining attempts counter
  • API enforces attempt limits before allowing guesses
  • Shows warning message when max attempts reached

3. Penalty System Improvements

  • Simplified UI: Removed checkbox - penalty automatically enabled when penalty points > 0
  • Score protection: Scores cannot go below 0, even with large penalties
  • If penalty would result in negative score, only deducts available points and sets to 0

4. Admin Photo Deletion

  • Admins can delete photos from:
    • Photos list page (hover to reveal delete icon)
    • Individual photo detail page (delete button in header)
  • Deletes associated guesses automatically
  • Deletes local uploaded files from filesystem
  • Confirmation dialog before deletion
  • Proper error handling and user feedback

5. Navigation Improvements

  • Logout button always visible in side menu (hamburger menu)
  • Improved side menu layout with fixed footer for logout button
  • Better mobile responsiveness

6. Self-Guess Prevention

  • Users cannot guess on their own uploaded photos
  • Shows informative message with answer for photo owners

Technical Changes

Database Schema

  • Added fileHash field (String?) to Photo model for duplicate detection
  • Added maxAttempts field (Int?) to Photo model for attempt limits
  • Added indexes on url and fileHash for performance

API Routes

  • POST /api/photos/upload-multiple: Enhanced with duplicate checking and maxAttempts
  • POST /api/photos/[photoId]/guess: Added maxAttempts enforcement and score floor protection
  • DELETE /api/photos/[photoId]: New route for admin photo deletion

Components

  • DeletePhotoButton: New reusable component for photo deletion
  • Updated upload form to remove penalty checkbox
  • Enhanced photo display pages with attempt counters and admin controls

Database Migrations

  • Run npm run db:push to apply schema changes
  • Run npm run db:generate to regenerate Prisma client

Testing

  • Test duplicate detection with same file and different filenames
  • Test duplicate detection with same URL
  • Test max attempts enforcement
  • Test penalty system with various point values
  • Test score floor (cannot go below 0)
  • Test admin photo deletion
  • Test self-guess prevention

Breaking Changes

None - all changes are backward compatible. Existing photos will have null for maxAttempts (unlimited) and fileHash (for URL uploads).

# Photo Management and Game Features ## Summary This PR adds comprehensive photo management features, duplicate detection, attempt limits, penalty system improvements, and admin photo deletion capabilities to the MirrorMatch application. ## Features Added ### 1. Duplicate Photo Detection - **File-based duplicates**: Calculates SHA256 hash of uploaded files to detect duplicate content - **URL-based duplicates**: Checks for duplicate photo URLs - Prevents users from uploading the same photo multiple times - Returns HTTP 409 (Conflict) with clear error messages ### 2. Maximum Attempts Per Photo - Uploaders can set a maximum number of guesses allowed per user for each photo - Default: unlimited (null or 0) - UI displays remaining attempts counter - API enforces attempt limits before allowing guesses - Shows warning message when max attempts reached ### 3. Penalty System Improvements - **Simplified UI**: Removed checkbox - penalty automatically enabled when penalty points > 0 - **Score protection**: Scores cannot go below 0, even with large penalties - If penalty would result in negative score, only deducts available points and sets to 0 ### 4. Admin Photo Deletion - Admins can delete photos from: - Photos list page (hover to reveal delete icon) - Individual photo detail page (delete button in header) - Deletes associated guesses automatically - Deletes local uploaded files from filesystem - Confirmation dialog before deletion - Proper error handling and user feedback ### 5. Navigation Improvements - Logout button always visible in side menu (hamburger menu) - Improved side menu layout with fixed footer for logout button - Better mobile responsiveness ### 6. Self-Guess Prevention - Users cannot guess on their own uploaded photos - Shows informative message with answer for photo owners ## Technical Changes ### Database Schema - Added `fileHash` field (String?) to Photo model for duplicate detection - Added `maxAttempts` field (Int?) to Photo model for attempt limits - Added indexes on `url` and `fileHash` for performance ### API Routes - `POST /api/photos/upload-multiple`: Enhanced with duplicate checking and maxAttempts - `POST /api/photos/[photoId]/guess`: Added maxAttempts enforcement and score floor protection - `DELETE /api/photos/[photoId]`: New route for admin photo deletion ### Components - `DeletePhotoButton`: New reusable component for photo deletion - Updated upload form to remove penalty checkbox - Enhanced photo display pages with attempt counters and admin controls ## Database Migrations - Run `npm run db:push` to apply schema changes - Run `npm run db:generate` to regenerate Prisma client ## Testing - Test duplicate detection with same file and different filenames - Test duplicate detection with same URL - Test max attempts enforcement - Test penalty system with various point values - Test score floor (cannot go below 0) - Test admin photo deletion - Test self-guess prevention ## Breaking Changes None - all changes are backward compatible. Existing photos will have `null` for `maxAttempts` (unlimited) and `fileHash` (for URL uploads).
ilia added 1 commit 2026-01-02 15:14:51 -05:00
fix: Resolve linting and TypeScript errors
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m19s
CI / lint-and-type-check (pull_request) Failing after 1m41s
CI / test (pull_request) Successful in 1m46s
CI / build (pull_request) Failing after 1m46s
CI / secret-scanning (pull_request) Successful in 1m20s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m22s
CI / workflow-summary (pull_request) Successful in 1m18s
90c5a9a4df
- Replace 'any' types with proper Prisma types
- Use PhotoUncheckedCreateInput for photo creation
- Use Prisma.PhotoWhereInput for where clauses
- Add proper type assertions for photo fields
- Fix Photo import error by using Prisma namespace
ilia added 1 commit 2026-01-02 15:28:59 -05:00
fix: Resolve TypeScript and linting errors for CI
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m19s
CI / lint-and-type-check (pull_request) Failing after 1m42s
CI / test (pull_request) Successful in 1m47s
CI / build (pull_request) Failing after 1m46s
CI / secret-scanning (pull_request) Successful in 1m20s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m27s
CI / workflow-summary (pull_request) Successful in 1m18s
f4461b277c
- Remove Prisma namespace imports (not available in Prisma 7)
- Use type assertions with eslint-disable for Prisma type issues
- Fix console.error calls to avoid format string warnings
- Sanitize file extensions to address path traversal warnings
- Add comments explaining server-side filename generation safety
ilia added 1 commit 2026-01-02 15:32:28 -05:00
fix: Improve navigation component styling and functionality
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m20s
CI / lint-and-type-check (pull_request) Failing after 1m41s
CI / test (pull_request) Successful in 1m46s
CI / build (pull_request) Failing after 1m46s
CI / secret-scanning (pull_request) Successful in 1m20s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m21s
CI / workflow-summary (pull_request) Successful in 1m18s
21fc9f33fb
- Add relative positioning to navigation elements for better stacking context
- Ensure side menu closes when navigating to Upload and Leaderboard links
- Adjust z-index values for side menu and overlay to improve layering
ilia added 1 commit 2026-01-02 16:14:14 -05:00
chore: Update CI configuration to include DATABASE_URL for Prisma Client generation
Some checks failed
CI / skip-ci-check (pull_request) Failing after 8m28s
CI / lint-and-type-check (pull_request) Has been skipped
CI / test (pull_request) Has been skipped
CI / build (pull_request) Has been skipped
CI / secret-scanning (pull_request) Has been skipped
CI / dependency-scan (pull_request) Has been skipped
CI / sast-scan (pull_request) Has been skipped
CI / workflow-summary (pull_request) Successful in 1m19s
c16b38522c
- Add DATABASE_URL environment variable to ensure Prisma can generate types using the same connection string as the build step
ilia added 1 commit 2026-01-02 16:50:50 -05:00
fix: Enhance CI workflow to improve skip logic and compatibility
Some checks failed
CI / skip-ci-check (pull_request) Failing after 8m25s
CI / lint-and-type-check (pull_request) Has been skipped
CI / test (pull_request) Has been skipped
CI / build (pull_request) Has been skipped
CI / secret-scanning (pull_request) Has been skipped
CI / dependency-scan (pull_request) Has been skipped
CI / sast-scan (pull_request) Has been skipped
CI / workflow-summary (pull_request) Successful in 1m18s
44cd5f5e0b
- Default to not skipping CI unless specified
- Set outputs in both modern and legacy formats for broader runner compatibility
- Refactor skip condition checks for consistency across jobs
ilia added 1 commit 2026-01-02 17:00:59 -05:00
fix: Refine CI skip logic for improved clarity and compatibility
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m19s
CI / lint-and-type-check (pull_request) Failing after 1m42s
CI / test (pull_request) Successful in 1m47s
CI / build (pull_request) Failing after 1m46s
CI / secret-scanning (pull_request) Successful in 1m21s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m25s
CI / workflow-summary (pull_request) Successful in 1m18s
4200975c78
- Default to 'false' for skip output to enhance runner compatibility
- Update skip condition checks to use boolean values for consistency
- Ensure CI is only skipped when explicitly indicated in branch name or commit message
ilia added 1 commit 2026-01-02 17:26:23 -05:00
chore: Update CI workflow to include Prisma Client generation and improve skip logic
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m19s
CI / lint-and-type-check (pull_request) Successful in 1m42s
CI / test (pull_request) Successful in 1m46s
CI / build (pull_request) Failing after 1m46s
CI / secret-scanning (pull_request) Successful in 1m20s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m27s
CI / workflow-summary (pull_request) Successful in 1m18s
cbf49bf306
- Add step to generate Prisma Client with DATABASE_URL for consistent type generation
- Clean up skip logic by removing unnecessary comments and legacy output formats
- Ensure CI skip checks are clear and maintain compatibility across runners
ilia added 1 commit 2026-01-02 17:31:00 -05:00
chore: Remove outdated Prisma typings and update client output path
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m20s
CI / test (pull_request) Successful in 1m48s
CI / build (pull_request) Successful in 1m48s
CI / secret-scanning (pull_request) Successful in 1m21s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m26s
CI / lint-and-type-check (pull_request) Failing after 1m42s
CI / workflow-summary (pull_request) Successful in 1m18s
24889c0373
- Delete fallback TypeScript typings for Prisma client to streamline type generation
- Update Prisma client output path for better compatibility with current project structure
ilia added 1 commit 2026-01-02 17:38:23 -05:00
chore: Clean up TypeScript configuration by removing outdated Prisma client path
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m20s
CI / lint-and-type-check (pull_request) Failing after 1m41s
CI / test (pull_request) Successful in 1m47s
CI / build (pull_request) Successful in 1m48s
CI / secret-scanning (pull_request) Successful in 1m20s
CI / dependency-scan (pull_request) Successful in 1m26s
CI / sast-scan (pull_request) Successful in 2m25s
CI / workflow-summary (pull_request) Successful in 1m18s
67914fcdc9
- Remove the obsolete path mapping for Prisma client in tsconfig.json to streamline the configuration
ilia added 1 commit 2026-01-02 21:04:37 -05:00
chore: Update CI workflow to include a trigger comment
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m20s
CI / lint-and-type-check (pull_request) Failing after 1m42s
CI / test (pull_request) Successful in 1m47s
CI / build (pull_request) Successful in 1m48s
CI / secret-scanning (pull_request) Successful in 1m22s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m26s
CI / workflow-summary (pull_request) Successful in 1m18s
49715f558f
- Add a comment to clarify the CI trigger mechanism for better understanding
ilia added 1 commit 2026-01-03 10:09:04 -05:00
chore: Update Prisma client output path for improved project structure
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m21s
CI / lint-and-type-check (pull_request) Failing after 1m42s
CI / test (pull_request) Successful in 1m48s
CI / build (pull_request) Failing after 1m47s
CI / secret-scanning (pull_request) Successful in 1m22s
CI / dependency-scan (pull_request) Successful in 1m26s
CI / sast-scan (pull_request) Successful in 2m29s
CI / workflow-summary (pull_request) Successful in 1m19s
62cbcb8c26
- Set the output path for the Prisma client to align with the current project directory structure, enhancing compatibility and organization.
ilia added 1 commit 2026-01-03 10:16:24 -05:00
chore: Add postinstall script for Prisma client generation and remove outdated client symlink
All checks were successful
CI / skip-ci-check (pull_request) Successful in 1m21s
CI / lint-and-type-check (pull_request) Successful in 1m44s
CI / test (pull_request) Successful in 1m49s
CI / build (pull_request) Successful in 1m50s
CI / secret-scanning (pull_request) Successful in 1m22s
CI / dependency-scan (pull_request) Successful in 1m29s
CI / sast-scan (pull_request) Successful in 2m23s
CI / workflow-summary (pull_request) Successful in 1m19s
2169e5d184
- Introduce a postinstall script to automatically generate the Prisma client after installation
- Remove the outdated symlink for the Prisma client to streamline project structure and avoid confusion
ilia merged commit a8548bddcf into main 2026-01-03 10:19:59 -05:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ilia/mirror_match#1
No description provided.