|
| 1 | +# Daily Challenges – Core Backend |
| 2 | + |
| 3 | +Extracted from `weekly-challenges.md`. |
| 4 | + |
| 5 | +## Goal |
| 6 | +Implement the database schema, generation logic, and Tauri commands for daily challenges. |
| 7 | + |
| 8 | +## Requirements |
| 9 | + |
| 10 | +### Database |
| 11 | +New tables: |
| 12 | +- `daily_challenges` – one row per day, auto-generated at first access |
| 13 | +- `challenge_history` – archived completed/failed challenges (shared with future weekly challenges) |
| 14 | + |
| 15 | +```sql |
| 16 | +CREATE TABLE daily_challenges ( |
| 17 | + id INTEGER PRIMARY KEY AUTOINCREMENT, |
| 18 | + challenge_date TEXT NOT NULL, -- "YYYY-MM-DD" |
| 19 | + challenge_type TEXT NOT NULL, -- "quick_win", "performance", "efficiency", "participation" |
| 20 | + challenge_description TEXT NOT NULL, |
| 21 | + challenge_target INTEGER NOT NULL, |
| 22 | + challenge_target_games INTEGER DEFAULT 1, |
| 23 | + hero_id INTEGER, -- NULL for non-hero challenges |
| 24 | + metric TEXT, -- "wins", "kills", "gpm", "last_hits", "deaths", "hero_damage" |
| 25 | + status TEXT NOT NULL DEFAULT 'active', -- active, completed, failed |
| 26 | + created_at INTEGER NOT NULL, |
| 27 | + completed_at INTEGER, |
| 28 | + UNIQUE(challenge_date) |
| 29 | +); |
| 30 | + |
| 31 | +CREATE TABLE challenge_history ( |
| 32 | + id INTEGER PRIMARY KEY AUTOINCREMENT, |
| 33 | + challenge_type TEXT NOT NULL, -- 'daily' (or 'weekly' later) |
| 34 | + period_start_date TEXT NOT NULL, |
| 35 | + challenge_description TEXT NOT NULL, |
| 36 | + status TEXT NOT NULL, -- completed, failed |
| 37 | + completed_at INTEGER, |
| 38 | + target_achieved INTEGER |
| 39 | +); |
| 40 | +``` |
| 41 | + |
| 42 | +### Challenge Types & Templates |
| 43 | +Use a fixed template list with hero/stat filled from player history: |
| 44 | + |
| 45 | +**Quick Win (easy):** |
| 46 | +- "Win 1 game today" |
| 47 | +- "Win 1 game with [Hero]" (hero from last 10 games) |
| 48 | + |
| 49 | +**Performance (medium):** |
| 50 | +- "Get [N]+ kills in one game" (N = avg kills + 2, min 10) |
| 51 | +- "Achieve [N]+ GPM in one game" (N = avg GPM + 30, min 400) |
| 52 | +- "Finish with positive KDA in one game" |
| 53 | +- "Deal [N]+ hero damage in one game" (N calibrated to avg, min 15000) |
| 54 | + |
| 55 | +**Efficiency (medium):** |
| 56 | +- "Get [N]+ CS at 10 minutes" (N = avg CS@10 + 5, min 50) – requires parsed matches |
| 57 | +- "Die [N] times or less in one game" (N = avg deaths - 1, max 3) |
| 58 | + |
| 59 | +**Participation (easy):** |
| 60 | +- "Play 2 games today" |
| 61 | +- "Play a game with [Hero]" (hero not played in last 7 days) |
| 62 | + |
| 63 | +### Generation Logic |
| 64 | +- 60% Easy (quick_win / participation), 30% Medium (performance), 10% Hard |
| 65 | +- Check last 7 daily challenges to avoid repeating same type consecutively |
| 66 | +- For hero-specific challenges, pick from matches in last 10 games |
| 67 | +- Auto-generate when first accessed for the day; cache in DB |
| 68 | + |
| 69 | +### Daily Streak |
| 70 | +- Count consecutive days where `status = 'completed'` going back from yesterday |
| 71 | +- Return 0 if yesterday was not completed |
| 72 | + |
| 73 | +### Archive Logic |
| 74 | +- On each call to `get_current_daily_challenge`, check if any `active` challenges exist for past dates and mark them `failed`, archive to `challenge_history` |
| 75 | + |
| 76 | +### Tauri Commands |
| 77 | +```rust |
| 78 | +fn get_daily_challenge() -> Result<Option<DailyChallenge>, String> |
| 79 | +fn get_daily_challenge_progress() -> Result<Option<DailyChallengeProgress>, String> |
| 80 | +fn get_daily_streak() -> Result<i32, String> |
| 81 | +``` |
| 82 | + |
| 83 | +### DailyChallengeProgress struct |
| 84 | +```rust |
| 85 | +pub struct DailyChallengeProgress { |
| 86 | + pub challenge: DailyChallenge, |
| 87 | + pub current_value: i32, // e.g. wins so far today |
| 88 | + pub target: i32, |
| 89 | + pub completed: bool, |
| 90 | + pub games_counted: i32, // number of matches evaluated |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +## Acceptance Criteria |
| 95 | +- [ ] Tables created in `init_db` |
| 96 | +- [ ] Daily challenge auto-generated on first access each day |
| 97 | +- [ ] Old active challenges auto-archived as failed |
| 98 | +- [ ] Progress evaluated against today's matches (after midnight) |
| 99 | +- [ ] Challenge auto-marked completed when target met |
| 100 | +- [ ] Streak correctly calculated from history |
| 101 | +- [ ] All 3 Tauri commands working |
0 commit comments