Skip to content

[#882] Add streak check-in system with SIWE#901

Merged
realproject7 merged 3 commits intomainfrom
task/882-streak-checkin
Apr 21, 2026
Merged

[#882] Add streak check-in system with SIWE#901
realproject7 merged 3 commits intomainfrom
task/882-streak-checkin

Conversation

@realproject7
Copy link
Copy Markdown
Owner

Summary

  • New POST /api/airdrop/checkin — SIWE signature verification, streak update
  • New lib/airdrop/streak.tsgetStreakBoost(), dropOneTier(), getNextTier()
  • Moved getStreakBoost from points.ts to streak.ts (re-exported for backward compat)
  • One check-in per calendar day (UTC), 30-min minimum gap enforced
  • Consecutive days increment streak; missed days drop one tier (not hard reset)
  • Campaign window enforced — no check-ins outside campaign dates

Streak tiers

Streak Boost
0-6 +0%
7+ +5%
14+ +10%
30+ +20%
50+ +30%
100+ +50% (cap)

Files Changed

  • lib/airdrop/streak.ts — new streak helper module
  • lib/airdrop/points.ts — imports getStreakBoost from streak.ts
  • src/app/api/airdrop/checkin/route.ts — new check-in endpoint

Test plan

  • npm run typecheck passes
  • POST with valid SIWE signature — verify streak created/incremented
  • POST same day — verify 429 "Already checked in today"
  • POST within 30 min — verify 429 gap rejection
  • After 2+ missed days — verify streak drops one tier (not reset)
  • Verify dropOneTier(100) → 50, dropOneTier(45) → 30, dropOneTier(5) → 0

Fixes #882

🤖 Generated with Claude Code

- New POST /api/airdrop/checkin endpoint with SIWE signature verification
- New lib/airdrop/streak.ts with getStreakBoost, dropOneTier, getNextTier
- Move getStreakBoost from points.ts to streak.ts (re-exported for compat)
- One check-in per calendar day (UTC), 30-min minimum gap
- Consecutive days increment streak, missed days drop one tier (not reset)
- Returns streak count, boost %, next tier info, checkedInToday flag

Fixes #882

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plotlink Ignored Ignored Apr 21, 2026 0:17am

Request Review

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The endpoint and helper structure are close, but the missed-day streak-drop logic does not currently match the issue specification. In two edge cases it returns a higher streak than the ticket defines.

Findings

  • [high] dropOneTier(100) returns 50, but the issue explicitly says a missed day for a 100+ streak should set the streak to 100, not drop below the top tier threshold.
    • File: lib/airdrop/streak.ts:32
    • Suggestion: adjust dropOneTier() so exact-threshold top-tier values (100 and above) resolve to 100, while lower tiers still fall to the lower tier threshold.
  • [high] For missed days on streaks 1-6, the route forces the result back up to 1 via Math.max(newStreak, 1), but the issue says that range should drop to 0.
    • File: src/app/api/airdrop/checkin/route.ts:123
    • Suggestion: remove the floor-to-1 behavior for the missed-day branch so dropOneTier(1..6) can remain 0 as specified.

Decision

Requesting changes because the current missed-day behavior does not match the ticket rules for top-tier and low-tier streak drops.

Per spec: 100+ → 100, 50-99 → 50, ..., 1-6 → 0.
dropOneTier now snaps to the current tier's threshold (not below it).
Check-in route adds +1 for today's check-in after the drop.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

dropOneTier() now matches the spec, but the route still applies a post-drop increment that changes the missed-day result away from the ticket rules.

Findings

  • [high] The missed-day branch now does dropOneTier(existing.current_streak) + 1, which means a streak in 1-6 becomes 1 and a streak in 100+ becomes 101 after the check-in. The issue text says missed days should reset the streak counter to the lower tier threshold (1-6 -> 0, 100+ -> 100) and does not include an extra increment afterward.
    • File: src/app/api/airdrop/checkin/route.ts:121
    • Suggestion: set newStreak = dropOneTier(existing.current_streak) in the missed-day branch so the persisted streak matches the specified threshold reset behavior.

Decision

Requesting changes because the route still does not implement the missed-day streak reset exactly as described in the ticket.

Per spec, missed days set streak to the tier threshold exactly
(e.g. 1-6 → 0, 50-99 → 50). The check-in itself does not
increment the dropped value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Summary

The missed-day streak logic now matches the ticket rules. The helper snaps streaks to the specified tier threshold, and the route persists that dropped value without an extra increment.

Findings

  • No blocking findings in the updated patch.

Decision

Approving from a code-review standpoint. The blockers from my previous reviews are resolved, and the streak logic now aligns with the issue specification.

@realproject7 realproject7 merged commit 8486133 into main Apr 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Airdrop P2] Streak check-in system (SIWE)

2 participants