Skip to content

Daily audio cron: extract decide_generation — table as code#651

Open
mircealungu wants to merge 1 commit into
masterfrom
wt/today-view-projection
Open

Daily audio cron: extract decide_generation — table as code#651
mircealungu wants to merge 1 commit into
masterfrom
wt/today-view-projection

Conversation

@mircealungu
Copy link
Copy Markdown
Member

Summary

Lifts the per-user generation decision (the table I keep drawing in chat
diagrams) into a single read-only function — one return per row.

def decide_generation(user, language, timezone_offset, today_local):
    sub = DailyAudioSubscription.find(user, language)
    if sub is None or not sub.enabled:                          return ("not-subscribed", None)
    if sub.lesson_type not in VALID_LESSON_TYPES:               return ("invalid-type",  sub)
    if not sub.scheduled_on(today_local):                       return ("not-due",       sub)
    if generator.today_lesson_exists(user, timezone_offset):    return ("exists",        sub)
    if DailyAudioLesson.waiting_paused_for(user, language.id):  return ("paused",        sub)
    return ("ready", sub)

The cron's main loop becomes a dispatch on kind, and generate_for_user does
only the heavy work (it no longer re-checks the gates — prepare_lesson_generation
still has its own existing-lesson check as belt-and-suspenders). Both dry-run
and real-run share the same decision, so the buckets can't drift between them.

Test plan

  • python -m tools.generate_daily_audio_lessons --dry-run --days 30 — same buckets as before.
  • --user-id <yours> real run still generates / skips as before.

Pairs with web#TBD (Today view's selectTodayView projection — same pattern on the client).

🤖 Generated with Claude Code

…-table row

The per-user generation decision (not-subscribed | invalid-type | not-due |
exists | paused | ready) was a cascade of guards spread across the loop body
and generate_for_user, with the dry-run branch re-checking the same gates as
the real-run branch. Lift it into decide_generation(user, language, …): one
read-only function with one return per row of the decision table. The main
loop becomes a dispatch on the kind, and generate_for_user does only the heavy
work (it's no longer the place where gates re-live). Behavior unchanged;
dry-run buckets match.

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

github-actions Bot commented Jun 5, 2026

ArchLens - No architecturally relevant changes to the existing views

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.

1 participant