--- description: MirrorMatch project rules (Next.js + Prisma + Auth + MinIO) globs: - "**/*.ts" - "**/*.tsx" - "**/*.md" --- ## Product rules - MirrorMatch is **invite-only**. All reads/writes must be scoped to a `Group` the user is a member of. - A **Set** has **2–10 Photos** and **2–4 Options**. - A Photo’s `points` is **1–10** (validate server-side). - A user can guess **once per photo**. - A photo uploader **cannot guess** their own photo for points. - Reveals are **manual by default**; optional auto-reveal when all Group members have guessed. ## Next.js rules - Use **App Router** patterns. - Do privileged operations (create set, upload, guess, reveal, invite) via **server actions** or route handlers. - Never trust client input; validate with **zod** on the server. ## Auth rules - Use Auth.js (next-auth) with Prisma adapter. - Gate pages using server-side session checks. - Treat users as identified by `user.id` from the session only. ## Storage rules - Store images in MinIO (S3) bucket; database stores only `storageKey`. - Access images via short-lived **presigned URLs**, generated server-side. - Never make buckets public. ## Database rules - Use Prisma migrations (`prisma migrate dev`) for schema changes. - Prefer enforcing uniqueness with DB constraints (e.g., one guess per user per photo).