feat(user): magic-link expired-token cleanup loop (ADR-0028 Phase A consequence) #65

Merged
arcodange merged 1 commits from vibe/batch1-task-b-magic-link-cleanup into main 2026-05-05 13:07:02 +02:00
Owner

Summary

Wires up a periodic cleanup goroutine that drives DeleteExpiredMagicLinkTokens (Phase A.3 method that was never called). Mirrors ADR-0021 JWT cleanup pattern.

Mistral Vibe authored (batch1 N=2 parallel with PR #64 OIDC config):

  • pkg/user/magic_link_cleanup.go (new) — MagicLinkCleanupRunner + StartCleanupLoop(ctx, interval) + runOnce(ctx)
  • pkg/user/magic_link_cleanup_test.go (new) — 4 unit tests (happy / error / cancel / zero-interval)
  • pkg/server/server.go — start the loop next to JWT cleanup
  • pkg/config/config.go — auth.magic_link.cleanup_interval (1h default) + env bind + getter

Claude trainer takeover : Mistral hit --max-price 1.50 right before commit. Code itself is Mistral's ; Claude only ran the commit/push/PR/merge sequence.

Test plan

  • go test ./pkg/user/... -count=1 → green (4 new tests)
  • go vet ./... clean
  • go build ./... clean
## Summary Wires up a periodic cleanup goroutine that drives DeleteExpiredMagicLinkTokens (Phase A.3 method that was never called). Mirrors ADR-0021 JWT cleanup pattern. **Mistral Vibe authored** (batch1 N=2 parallel with PR #64 OIDC config): - pkg/user/magic_link_cleanup.go (new) — MagicLinkCleanupRunner + StartCleanupLoop(ctx, interval) + runOnce(ctx) - pkg/user/magic_link_cleanup_test.go (new) — 4 unit tests (happy / error / cancel / zero-interval) - pkg/server/server.go — start the loop next to JWT cleanup - pkg/config/config.go — auth.magic_link.cleanup_interval (1h default) + env bind + getter **Claude trainer takeover** : Mistral hit --max-price 1.50 right before commit. Code itself is Mistral's ; Claude only ran the commit/push/PR/merge sequence. ## Test plan - go test ./pkg/user/... -count=1 → green (4 new tests) - go vet ./... clean - go build ./... clean
arcodange added 1 commit 2026-05-05 13:06:54 +02:00
Periodically delete magic-link tokens past their expires_at — the rows
accumulate without cleanup since the consume endpoint only marks them
consumed but never removes them, and DeleteExpiredMagicLinkTokens (added
in Phase A.3, PR #61) was never wired up.

Mirrors the JWT secret cleanup pattern (ADR-0021).

- pkg/user/magic_link_cleanup.go: MagicLinkCleanupRunner with
  StartCleanupLoop(ctx, interval) and an inner runOnce(ctx) for testability
- pkg/user/magic_link_cleanup_test.go: unit tests cover happy path,
  error propagation, ctx-cancel termination, zero-interval no-op
- pkg/server/server.go: start the loop right after the JWT cleanup loop
- pkg/config/config.go: auth.magic_link.cleanup_interval (default 1h),
  env DLC_AUTH_MAGIC_LINK_CLEANUP_INTERVAL, getter GetMagicLinkCleanupInterval

Mostly authored by Mistral Vibe in batch1-task-b worktree (parallel with
batch1-task-a OIDC config). Mistral hit --max-price 1.50 right before the
final commit step, Claude finished the ship via trainer takeover (Q-045
pattern, 2nd recurrence in two batches — to be addressed in Phase 1bis).
arcodange force-pushed vibe/batch1-task-b-magic-link-cleanup from 5bc97545f4 to 8041a8c04f 2026-05-05 13:06:54 +02:00 Compare
arcodange merged commit b6a6a2b3d7 into main 2026-05-05 13:07:02 +02:00
arcodange deleted branch vibe/batch1-task-b-magic-link-cleanup 2026-05-05 13:07:03 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange/dance-lessons-coach#65