chore: initial project setup

Initialize Sneaky Klaus project with:
- uv package management and pyproject.toml
- Flask application structure (app.py, config.py)
- SQLAlchemy models for Admin and Exchange
- Alembic database migrations
- Pre-commit hooks configuration
- Development tooling (pytest, ruff, mypy)

Initial structure follows design documents in docs/:
- src/app.py: Application factory with Flask extensions
- src/config.py: Environment-based configuration
- src/models/: Admin and Exchange models
- migrations/: Alembic migration setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-22 11:28:15 -07:00
commit b077112aba
32 changed files with 10931 additions and 0 deletions

722
docs/BACKLOG.md Normal file
View File

@@ -0,0 +1,722 @@
# Sneaky Klaus - Product Backlog
## Overview
This backlog contains user stories for Sneaky Klaus, organized by epic. Stories follow the format:
> **As a** [role], **I want** [capability], **so that** [benefit].
Each story includes acceptance criteria to define "done."
---
## Epic 1: Admin Account Management
### 1.1 Initial Admin Setup
**As a** first-time user, **I want** to create an admin account during initial setup, **so that** I can manage gift exchanges.
**Acceptance Criteria:**
- Setup screen appears on first application access
- Requires email address and password
- Password must meet minimum security requirements
- After setup, user is logged in as admin
- Setup screen is not accessible after initial admin creation
---
### 1.2 Admin Login
**As an** admin, **I want** to log in with my email and password, **so that** I can access the admin dashboard.
**Acceptance Criteria:**
- Login form accepts email and password
- Invalid credentials show appropriate error message
- Successful login redirects to admin dashboard
- Session persists across browser refreshes
---
### 1.3 Admin Password Recovery
**As an** admin, **I want** to reset my password via email, **so that** I can regain access if I forget my password.
**Acceptance Criteria:**
- "Forgot password" link on login page
- Entering admin email sends reset link
- Reset link expires after reasonable time period
- Reset link can only be used once
- New password must meet security requirements
- Confirmation shown after successful reset
---
### 1.4 Admin Logout
**As an** admin, **I want** to log out of my account, **so that** I can secure my session.
**Acceptance Criteria:**
- Logout option available from admin interface
- Logout clears session
- Redirects to login page after logout
---
## Epic 2: Exchange Management
### 2.1 Create Exchange
**As an** admin, **I want** to create a new gift exchange, **so that** I can organize a Secret Santa event.
**Acceptance Criteria:**
- Form to create exchange with fields:
- Name (required)
- Description (optional)
- Gift budget/price range (required)
- Maximum participants (required, minimum 3)
- Registration close date (required)
- Exchange date (required)
- Timezone (required)
- Exchange created in "Draft" state
- Exchange appears in admin dashboard after creation
---
### 2.2 View Exchange List
**As an** admin, **I want** to see all my gift exchanges, **so that** I can manage them.
**Acceptance Criteria:**
- Dashboard shows list of all exchanges
- Each exchange displays: name, state, participant count, exchange date
- Exchanges sorted by exchange date (upcoming first)
- Visual indicator for exchange state
---
### 2.3 View Exchange Details
**As an** admin, **I want** to view full details of an exchange, **so that** I can see its current status and participants.
**Acceptance Criteria:**
- Clicking an exchange opens detail view
- Shows all exchange information
- Shows list of registered participants
- Shows current state
- Shows registration link (when applicable)
---
### 2.4 Edit Exchange
**As an** admin, **I want** to edit exchange details, **so that** I can correct mistakes or update information.
**Acceptance Criteria:**
- All fields editable when exchange is in Draft, Registration Open, or Registration Closed state
- Cannot edit after matching has occurred
- Changes saved immediately
- Confirmation message after save
---
### 2.5 Delete Exchange
**As an** admin, **I want** to delete an exchange, **so that** I can remove cancelled or test exchanges.
**Acceptance Criteria:**
- Delete option available for any exchange
- Confirmation required before deletion
- Deletion removes all associated data (participants, matches)
- Exchange no longer appears in dashboard
---
### 2.6 Generate Registration Link
**As an** admin, **I want** a shareable registration link for each exchange, **so that** I can invite participants.
**Acceptance Criteria:**
- Unique link generated for each exchange
- Link is copyable to clipboard
- Link is displayed when exchange is in appropriate state
- Link leads to registration page for that specific exchange
---
## Epic 3: Exchange State Management
### 3.1 Open Registration
**As an** admin, **I want** to open registration for an exchange, **so that** participants can join.
**Acceptance Criteria:**
- "Open Registration" action available from Draft state
- Exchange state changes to "Registration Open"
- Registration link becomes active
- Participants can now access registration form
---
### 3.2 Close Registration
**As an** admin, **I want** to close registration, **so that** I can prepare for matching.
**Acceptance Criteria:**
- "Close Registration" action available from Registration Open state
- Exchange state changes to "Registration Closed"
- Registration link no longer accepts new registrations
- Existing participants can still access their profile via magic link
---
### 3.3 Reopen Registration (Pre-Matching)
**As an** admin, **I want** to reopen registration before matching, **so that** I can allow late additions.
**Acceptance Criteria:**
- "Reopen Registration" action available from Registration Closed state
- Exchange state changes back to "Registration Open"
- New participants can register
- Existing participants retained
---
### 3.4 Reopen Registration (Post-Matching)
**As an** admin, **I want** to reopen registration after matching, **so that** I can add participants who were missed.
**Acceptance Criteria:**
- "Reopen Registration" action available from Matched state
- Warning displayed that existing matches will be cleared
- Confirmation required
- All matches cleared upon confirmation
- Exchange state changes to "Registration Open"
---
### 3.5 Mark Exchange Complete
**As an** admin, **I want** to mark an exchange as complete, **so that** it's clear the event has concluded.
**Acceptance Criteria:**
- "Mark Complete" action available from Matched state
- Exchange state changes to "Completed"
- Exchange moves to completed section in dashboard
- 30-day retention countdown begins
---
### 3.6 Automatic Exchange Completion
**As a** system, **I want** to automatically mark exchanges as complete after the exchange date, **so that** data retention policies are enforced.
**Acceptance Criteria:**
- Exchanges in Matched state auto-transition to Completed after exchange date passes
- 30-day retention countdown begins automatically
- Admin can still access completed exchange data during retention period
---
## Epic 4: Participant Registration
### 4.1 Access Registration Page
**As a** potential participant, **I want** to access the registration page via shared link, **so that** I can join an exchange.
**Acceptance Criteria:**
- Registration link opens registration page
- Page displays exchange name, description, budget, and exchange date
- Shows registration form if registration is open
- Shows appropriate message if registration is closed
- Shows appropriate message if exchange doesn't exist
---
### 4.2 New Participant Registration
**As a** potential participant, **I want** to register for an exchange, **so that** I can participate in Secret Santa.
**Acceptance Criteria:**
- Registration form with fields:
- Name (required)
- Email (required, valid email format)
- Gift ideas (optional, multi-line text)
- Opt-in for reminder emails (checkbox)
- Email uniqueness checked within exchange
- Confirmation message after successful registration
- Confirmation email sent to participant
---
### 4.3 Returning Participant Detection
**As a** returning participant, **I want** to be recognized when I click the registration link again, **so that** I don't accidentally create duplicate registrations.
**Acceptance Criteria:**
- After clicking registration link, option to enter email to check existing registration
- If email found, prompt to send magic link
- If email not found, show registration form
- Clear messaging about what's happening
---
### 4.4 Admin Self-Registration
**As an** admin, **I want** to register myself as a participant in an exchange I created, **so that** I can participate in my own Secret Santa.
**Acceptance Criteria:**
- Option for admin to add themselves as participant
- Uses admin's email by default (editable)
- Admin registered same as any other participant
- Admin clearly marked in participant list (for admin view only)
---
### 4.5 View Participant List (Pre-Matching)
**As a** registered participant, **I want** to see who else has registered, **so that** I know who's participating.
**Acceptance Criteria:**
- Participant list visible after logging in via magic link
- Shows display names only
- Does not show email addresses
- Does not indicate any match information
- Updates as new participants register
---
## Epic 5: Participant Authentication
### 5.1 Magic Link Request
**As a** registered participant, **I want** to request a login link via email, **so that** I can access my exchange information.
**Acceptance Criteria:**
- "Access my registration" or similar option on registration page
- Enter email to request magic link
- If email registered, magic link sent
- If email not registered, appropriate message shown (without revealing registration status for security)
- Magic link expires after reasonable time period
---
### 5.2 Magic Link Login
**As a** participant, **I want** to log in by clicking the magic link, **so that** I can access my information without a password.
**Acceptance Criteria:**
- Clicking valid magic link logs participant in
- Redirects to participant dashboard
- Magic link can only be used once
- Expired link shows appropriate message with option to request new link
---
### 5.3 Participant Session
**As a** logged-in participant, **I want** my session to persist, **so that** I don't have to log in repeatedly.
**Acceptance Criteria:**
- Session persists across browser refreshes
- Session expires after reasonable inactivity period
- Participant can manually log out
---
## Epic 6: Participant Self-Management
### 6.1 Update Profile
**As a** registered participant, **I want** to update my gift ideas, **so that** my Secret Santa has current information.
**Acceptance Criteria:**
- Edit option available when logged in
- Can update name and gift ideas
- Cannot change email (request admin help)
- Only available before matching occurs
- Confirmation after save
---
### 6.2 Withdraw from Exchange
**As a** registered participant, **I want** to withdraw from an exchange, **so that** I can opt out if my circumstances change.
**Acceptance Criteria:**
- "Withdraw" option available before registration closes
- Confirmation required
- Participant removed from exchange
- Confirmation email sent
- Admin notified (if notifications enabled)
---
### 6.3 Update Reminder Preferences
**As a** participant, **I want** to change my reminder email preferences, **so that** I can control notifications.
**Acceptance Criteria:**
- Option to enable/disable reminder emails
- Available before exchange completes
- Changes take effect immediately
---
## Epic 7: Exclusion Rules
### 7.1 View Participants for Exclusions
**As an** admin, **I want** to see all participants when configuring exclusions, **so that** I can set up appropriate rules.
**Acceptance Criteria:**
- List of all participants displayed
- Available after registration is closed
- Shows participant names clearly
---
### 7.2 Add Exclusion Rule
**As an** admin, **I want** to add exclusion rules, **so that** certain participants won't be matched together.
**Acceptance Criteria:**
- Interface to select two participants who shouldn't be matched
- Exclusion is bidirectional (A won't give to B, B won't give to A)
- Multiple exclusions can be added
- Visual confirmation of added exclusion
---
### 7.3 Remove Exclusion Rule
**As an** admin, **I want** to remove exclusion rules, **so that** I can correct mistakes.
**Acceptance Criteria:**
- List of current exclusions displayed
- Option to remove each exclusion
- Removal is immediate
- Confirmation shown
---
### 7.4 Exclusion Validation
**As an** admin, **I want** to know if my exclusions make matching impossible, **so that** I can adjust before attempting to match.
**Acceptance Criteria:**
- Warning displayed if exclusions may prevent valid matching
- Explanation of which exclusions are problematic
- Matching blocked if mathematically impossible
---
## Epic 8: Matching
### 8.1 Trigger Matching
**As an** admin, **I want** to trigger the matching process, **so that** participants are assigned their recipients.
**Acceptance Criteria:**
- "Match Participants" action available from Registration Closed state
- Minimum 3 participants required
- Matching algorithm runs respecting all exclusions
- Exchange state changes to "Matched" on success
- Admin notified of success
---
### 8.2 Matching Algorithm
**As a** system, **I want** to randomly match participants following Secret Santa best practices, **so that** the exchange is fair and secret.
**Acceptance Criteria:**
- No participant is matched to themselves
- All exclusion rules are honored
- Each participant gives exactly one gift
- Each participant receives exactly one gift
- Single cycle preferred (A→B→C→A) when possible
- Randomization ensures unpredictability
---
### 8.3 Matching Failure Handling
**As an** admin, **I want** to be informed if matching fails, **so that** I can resolve the issue.
**Acceptance Criteria:**
- Clear error message if matching impossible
- Explanation of why (e.g., "Too many exclusions")
- Suggestions for resolution
- Exchange remains in Registration Closed state
---
### 8.4 View Matches (Admin)
**As an** admin, **I want** to view all matches, **so that** I can troubleshoot issues or handle disputes.
**Acceptance Criteria:**
- Admin can see full match list
- Shows who is giving to whom
- Only visible to admin
- Available after matching
---
### 8.5 Re-Match Participants
**As an** admin, **I want** to trigger a fresh re-match, **so that** I can resolve issues with current assignments.
**Acceptance Criteria:**
- "Re-match" option available in Matched state
- Confirmation required (warns all matches will be cleared)
- New random matching performed
- New notification emails sent to all participants
- Old matches completely replaced
---
### 8.6 Manual Match Override
**As an** admin, **I want** to manually assign or change specific matches, **so that** I can handle special circumstances.
**Acceptance Criteria:**
- Interface to change individual assignments
- Validation prevents invalid states (no self-matching, everyone has exactly one recipient)
- Changes saved immediately
- Affected participants receive updated notification
---
## Epic 9: Participant Removal (Post-Registration Close)
### 9.1 Remove Participant (Admin)
**As an** admin, **I want** to remove a participant at any stage, **so that** I can handle dropouts.
**Acceptance Criteria:**
- Remove option available for any participant
- Confirmation required
- If before matching: participant simply removed
- If after matching: triggers re-match requirement
- Removed participant notified via email
---
### 9.2 Handle Post-Match Participant Removal
**As a** system, **I want** to handle participant removal after matching, **so that** the exchange can continue.
**Acceptance Criteria:**
- When participant removed after matching, admin notified
- Option to auto-rematch (system re-runs matching)
- Option to manually reassign affected matches only
- All affected participants notified of changes
---
## Epic 10: Notifications
### 10.1 Registration Confirmation Email
**As a** newly registered participant, **I want** to receive a confirmation email, **so that** I know my registration was successful.
**Acceptance Criteria:**
- Email sent immediately after registration
- Includes exchange name and date
- Includes magic link to access registration
- Includes confirmation of provided details
---
### 10.2 Match Notification Email
**As a** participant, **I want** to receive an email with my match assignment, **so that** I know who to buy for.
**Acceptance Criteria:**
- Email sent immediately after matching
- Includes recipient's name
- Includes recipient's gift ideas
- Includes gift budget
- Includes exchange date
- Includes magic link to view in app
---
### 10.3 Reminder Emails
**As a** participant who opted in, **I want** to receive reminder emails before the exchange, **so that** I don't forget to buy a gift.
**Acceptance Criteria:**
- Reminders sent only to opted-in participants
- Reminder schedule configurable by admin
- Includes recipient info and exchange date
- Includes magic link to view full details
---
### 10.4 Admin Notification: New Registration
**As an** admin, **I want** to be notified of new registrations, **so that** I can track participation.
**Acceptance Criteria:**
- Email sent when new participant registers
- Only if admin has enabled this notification
- Includes participant name and exchange name
---
### 10.5 Admin Notification: Participant Withdrawal
**As an** admin, **I want** to be notified when a participant withdraws, **so that** I can follow up if needed.
**Acceptance Criteria:**
- Email sent when participant withdraws
- Only if admin has enabled this notification
- Includes participant name and exchange name
---
### 10.6 Admin Notification: Matching Complete
**As an** admin, **I want** to be notified when matching completes, **so that** I know the exchange is ready.
**Acceptance Criteria:**
- Email sent after successful matching
- Only if admin has enabled this notification
- Includes exchange name and participant count
---
### 10.7 Configure Admin Notifications
**As an** admin, **I want** to configure which notifications I receive, **so that** I'm not overwhelmed with emails.
**Acceptance Criteria:**
- Settings page for notification preferences
- Toggle for each notification type
- Can set globally or per-exchange
- Changes take effect immediately
---
## Epic 11: Participant Dashboard
### 11.1 View My Assignment
**As a** matched participant, **I want** to view who I'm buying for, **so that** I can purchase an appropriate gift.
**Acceptance Criteria:**
- Dashboard shows assigned recipient's name
- Shows recipient's gift ideas
- Shows gift budget
- Shows exchange date
- Available after matching occurs
---
### 11.2 View Exchange Information
**As a** participant, **I want** to view exchange details, **so that** I have all the information I need.
**Acceptance Criteria:**
- Shows exchange name and description
- Shows gift budget
- Shows exchange date and timezone
- Shows registration status/state
---
### 11.3 View Participant List (Post-Matching)
**As a** participant, **I want** to see who's in the exchange, **so that** I know the group.
**Acceptance Criteria:**
- List of all participant names
- Does not reveal who is matched to whom
- Does not reveal who my Secret Santa is
---
## Epic 12: Data Retention
### 12.1 Automatic Data Purge
**As a** system, **I want** to automatically purge exchange data after 30 days, **so that** participant data isn't retained indefinitely.
**Acceptance Criteria:**
- Completed exchanges tracked with completion date
- 30 days after completion, all data purged automatically
- Purge includes: participants, matches, gift ideas, emails
- Admin notified before purge (e.g., 7 days warning)
---
### 12.2 View Data Retention Status
**As an** admin, **I want** to see when exchange data will be purged, **so that** I can export if needed.
**Acceptance Criteria:**
- Completed exchanges show days until purge
- Clear indication of purge date
---
## Epic 13: Responsive Design
### 13.1 Mobile-Friendly Participant Experience
**As a** participant on a mobile device, **I want** the interface to work well on my phone, **so that** I can easily register and view my assignment.
**Acceptance Criteria:**
- Registration form usable on mobile
- Dashboard readable on mobile
- Touch targets appropriately sized
- No horizontal scrolling required
---
### 13.2 Mobile-Friendly Admin Experience
**As an** admin on a mobile device, **I want** to manage exchanges from my phone, **so that** I can administer on the go.
**Acceptance Criteria:**
- Admin dashboard usable on mobile
- Exchange creation/editing works on mobile
- Participant management works on mobile
- All critical functions accessible
---
## Epic 14: Reminder Configuration
### 14.1 Configure Reminder Schedule
**As an** admin, **I want** to configure when reminder emails are sent, **so that** I can customize the experience.
**Acceptance Criteria:**
- Settings to define reminder intervals (e.g., 7 days, 3 days, 1 day before)
- Can be set per-exchange or as default
- Only affects participants who opted in
---
## Story Status Key
| Status | Description |
|--------|-------------|
| 📋 Backlog | Not yet started |
| 🔄 In Progress | Currently being worked on |
| ✅ Done | Completed and tested |
| 🚫 Blocked | Cannot proceed due to dependency |
---
## Notes
- Stories are roughly ordered by dependency and priority within each epic
- Epics 1-4 represent core MVP functionality
- Epics 5-6 complete the participant experience
- Epics 7-9 handle the matching complexity
- Epics 10-14 are supporting features that enhance the experience
- Story estimates and sprint assignments to be added during planning sessions