US10: Premium Subscription#101
Conversation
- Add score fields (player1Score, player2Score) to BracketMatch type - Add tournamentWinner field to BracketResponse - Implement PUT /api/tournaments/:id/matches/:matchId/score endpoint - Add submitMatchScore function to store with validation - Update getTournamentBracket to include tournament winner - Add comprehensive test suite with 14 test cases covering: - Score submission and validation - Bracket advancement and winner determination - Real-time updates - Score history preservation - Edge cases (byes, completed matches) - All 73 tests passing
- Add Replay type to types.ts with all required fields - Create replay storage in store.ts with Maps for replays and replaysByTournament - Implement createReplay, getReplayById, getReplaysByTournament, validateReplayFileSize functions - Create src/routes/replays.ts with POST /api/replays and GET /api/replays/:id - Add GET /api/tournaments/:id/replays endpoint in tournaments.ts - Implement 2GB file size limit validation - Add authentication checks (organizer-only upload) - Ensure organizers can only upload to their own tournaments - Replays accessible publicly without authentication - Add comprehensive test suite with 14 tests covering all edge cases - All 96 tests passing
- Add searchReplays function to store.ts with filtering and pagination - Support filtering by game (case-insensitive), event_id, and player_name - Implement pagination with default page size of 20, max 100 - Return paginated results with metadata (total, page, pageSize, totalPages) - Results sorted in reverse-chronological order by default - Add GET /api/replays route to replays.ts - Handle edge cases for invalid pagination parameters - Performance tested for datasets up to 100 replays (< 500ms) - Add comprehensive test suite with 21 tests - All 117 tests passing
- Add startDate, venue, city optional fields to Tournament interface - Update createTournament to accept new location/date fields - Add searchEvents function to store.ts with filtering by game and city - Filter out past events by default (events with startDate < now) - Sort results by startDate ascending (soonest first) - Create EventResponse interface with entrantCount - Create src/routes/events.ts with GET /api/events endpoint - Add events router to app.ts - Performance optimized for large datasets (< 400ms) - Add comprehensive test suite with 17 tests - All 134 tests passing
- Add getPointsForPlacement function with tiered points system (1st=100, 2nd=75, 3-4th=50, 5-8th=25, participation=10) - Create getLeaderboard function to aggregate stats across finalized tournaments - Filter by game (required, case-insensitive) - Support player_id query to return specific player's rank - Implement pagination with default page size 20, max 100 - Sort by points descending with tiebreakers (total wins, total tournaments, userId) - Only include finalized tournaments in calculations - Create LeaderboardEntry and LeaderboardResponse interfaces - Create src/routes/leaderboard.ts with GET /api/leaderboard endpoint - Add leaderboard router to app.ts - Add comprehensive test suite with 14 tests - All 148 tests passing
- Added Follow interface to types.ts with followerId, followingId, createdAt - Implemented follow storage with Maps for follows, followersByUser, followingByUser in store.ts - Created store functions: createFollow, deleteFollow, getUserFollowing, getUserFollowers, isFollowing - Added POST /api/follows endpoint to create follow relationships - Added DELETE /api/follows/:id endpoint to remove follows with proper authorization - Added GET /api/users/:id/following endpoint with pagination - Added GET /api/users/:id/followers endpoint with pagination - Prevents self-follows and duplicate follow attempts (409 status) - All endpoints require authentication - All 20 test cases passing - Full test suite: 168 tests passing
- Added Subscription interface to types.ts with status, priceId, expiryDate, clientSecret - Implemented subscription storage with Maps for subscriptions and subscriptionsByUser in store.ts - Created store functions: createSubscription, getSubscriptionById, getUserSubscription, activateSubscription, cancelSubscription, hasActivePremiumSubscription - Added POST /api/subscriptions endpoint to create subscriptions (organizer only) - Added POST /api/subscriptions/webhook endpoint for Stripe webhooks (payment success/failure, cancellation) - Added GET /api/subscriptions/:userId endpoint to view subscription status - Added DELETE /api/subscriptions/:id endpoint to cancel subscription - Added requirePremium middleware to gate premium features - Added /api/premium/features test endpoint demonstrating premium feature gating - Prevents duplicate active/pending subscriptions (409 status) - Handles subscription expiry automatically - Mock Stripe payment intent format for testing - All 20 test cases passing - Full test suite: 188 tests passing
Claude automated code reviewSummary — Automated review was skipped. Reason — Claude API call failed: 429 {"type":"error","error":{"type":"rate_limit_error","message":"This request would exceed your organization's rate limit of 50,000 input tokens per minute (org: f492fb18-9da7-43e0-828c-1403e9d53b6a, model: claude-haiku-4-5-20251001). For details, refer to: https://docs.claude.com/en/api/rate-limits. You can see the response headers for current usage. Please reduce the prompt length or the maximum tokens requested, or try again later. You may also contact sales at https://claude.com/contact-sales to discuss your options for a rate limit increase."},"request_id":"req_011Cag9yyui6FCbS7Uf44BGq"} Advisory only — a human reviewer still approves the merge. Re-run with |
Implement User Story 10: Premium Subscription
This PR adds premium subscription functionality with Stripe integration (mocked for testing), enabling organizers to upgrade accounts and access premium features.
Key Features:
Technical Implementation:
Machine Acceptance Criteria Verified:
✓ POST /api/subscriptions creates payment intent and returns client secret
✓ Subscription marked active via webhook processing
✓ Premium features return 403 for non-subscribers, 200 for subscribers
✓ Expired/cancelled subscriptions correctly revert to free tier
✓ GET /api/subscriptions/:user_id returns status and expiry date
✓ Webhook handling for payment_intent.succeeded, payment_failed, subscription.deleted
Tests: 20/20 passing
Note: Ready for production deployment pending real Stripe API key configuration.