Flow 1: Next Week (Next? Tab)
Flow 2: Current Week (Weekly Prompt)
Flow 3: Planning Sheet Steps
Flow 4: Duplicate Guard
Summary Table
Flow 1: Planning for Next Week (from "Next?" Tab)
Entry Point
User taps the planning button on the "Next?" tab
↓
Decision 1
Is today within the Planning Window?
Planning Window = last 2 days of the week (days 6 and 7, based on user's week-start setting)
Yes — In Planning Window
Decision 2A
Does a plan already exist for next week?
No Plan Exists
Result
Button: "Plan Your Next Week"
Green/unlocked. No PIN needed. Opens planning sheet directly.
Plan Already Exists
Result
Button: "Re-plan Next Week"
Yellow/locked. PIN required. Old plan is deleted and replaced with new selections.
No — Outside Planning Window
Result
Button: "Unlock Next Week's Plan"
Yellow/locked. PIN required. After PIN, user must provide a reason ("Why do you want to plan early?").
↓
Decision 3 (if locked)
Does the user enter the correct PIN?
Correct PIN
Action
Planning Sheet opens
Goes to Flow 3 (Planning Sheet Steps). If PIN was used outside planning window, Reason screen is included.
Wrong PIN
Blocked
Access denied
User cannot proceed. Must try again with the correct PIN.
↓
Save Behavior
All selected ideals are saved to NEXT week's start date
If re-planning: old next-week plan is deleted first, then new plan is written (Replace Mode).
Flow 2: Planning for Current Week (Automatic Weekly Prompt)
Trigger
App opens at the start of a new week
Evaluated automatically when the ideals list loads. Requires both items and planned records snapshots to be ready before any decision is made.
↓
Gate 1
Is any weekly-flow modal already on screen?
Checks: planning sheet, recap view, choice prompt. If any is active, skip to prevent overlapping modals.
Modal already showing
Blocked
Skip — a weekly flow modal is already active
↓
Gate 2
Has the weekly flow already been completed this week?
Set to true after: "Skip" is pressed, or plan is saved, or plan already existed and recap was dismissed.
Yes
Blocked
Already done for this week
↓
Gate 3
What day of the week is it?
Days 6-7 (last 2 days)
Blocked
Weekly prompt never shows
These days are the Planning Window for NEXT week, not current week.
↓
Gate 4
Was a plan already created for this week (from the "Next?" tab last week)?
Plan Already Exists
Step 1 (only step)
Last Week Review
User reviews how last week went. Shown once.
↓
Result
Flow marked complete
No "What do you wanna do?" prompt. No planning sheet. The plan from last week is already active.
↓
Gate 5
Has the prompt been opened 2 times already this week?
Counter increments when user taps "Pick". Maximum 2 per week.
Already opened 2 times
Blocked
Max appearances reached
↓
Gate 6 (first app open only)
Has the Last Week Review been shown this week?
Not yet shown
Step 1
Last Week Review
Shown once per week. Key is marked BEFORE showing (prevents race condition on re-trigger).
↓
Step 2
"What do you wanna do this week?" (Pick / Skip)
Appears after recap is dismissed.
Already shown (2nd app open)
Session Guard
Was the planning sheet already shown this session?
Prevents re-showing the choice prompt in the same session after the planning sheet was dismissed.
No (fresh session)
"What do you wanna do this week?" (Pick / Skip)
↓
User Choice
"What do you wanna do this week?"
"Pick"
Action
Full Planning Sheet opens
All 3 steps: Again? → Wishlist → Missed Anything?
No PIN. No Reason screen. Open count increments.
↓
If user saves: flow marked complete immediately (explicit, no Firestore dependency)
If user dismisses without saving: prompt can appear once more on next app open (up to 2 total)
"Skip"
Result
Flow marked complete
No planning this week. Won't prompt again.
↓
Race Condition Protections
Multiple safeguards prevent duplicate modals
1. Pre-marking: Recap key is marked BEFORE showing the sheet, not on dismiss.
2. Session guard: hasPresentedWeeklyPlanningPromptThisSession prevents re-showing choice prompt after planning sheet dismiss in the same session.
3. Late arrival correction: If planned records arrive from Firestore after the choice prompt is already showing, and a plan exists, the prompt is dismissed and flow is marked complete.
4. Snapshot gating: Flow only runs after both items AND planned records snapshots are confirmed. No arbitrary timers.
5. Explicit save marking: markWeeklyFlowComplete() is called directly on save, not relying on Firestore re-trigger.
Flow 3: Planning Sheet Steps (What Happens Inside)
Context
The Planning Sheet is opened from either Flow 1 (Next? Tab) or Flow 2 (Weekly Prompt)
↓
Step 1 — "Again?"
Carry over ideals from the previous period
What's shown: All active (non-wishlist) ideals from the reference week.
From Next? Tab: Shows THIS week's ideals to carry to next week.
From Weekly Prompt: Shows LAST week's ideals to carry to this week.
User can: Toggle each ideal on/off, change Category, set Target Count (1-6+), set Reminder (days + time).
Skipped when: A pre-existing plan already covers this week (but this path no longer opens the planning sheet — recap only).
↓
Step 2 — "Wishlist"
Add saved wishlist items to the plan
What's shown: All ideals with wishlistEnabled: true that aren't already in the target week.
User can: Select wishlist items, change Category, set Target Count, set Schedule.
From Next? Tab: "Create New Wishlist Item" button is available.
From Weekly Prompt: No create button.
Skipped when: No wishlist items exist.
Optional: User can skip this step entirely.
↓
Step 3 — "Missed Anything?"
Create brand new ideals
What's shown: Empty form to create new ideals from scratch.
User can: Enter Title, pick Category, set Target Count, set Reminder schedule.
Multiple: Tap "+" to add more new ideals.
Always shown: This step is always available.
↓
Decision
Was the Planning Sheet opened with a PIN (outside the planning window)?
Yes (PIN Used)
Step 4 — "Reason"
"Why do you want to plan early?"
User must write a reason. Only shown once per planning session. Only applies to Next? Tab flow.
↓
Save
All selections are saved to Firestore
For each selected existing ideal: A new copy is created with the target week's start date, new target count, and schedule.
For each wishlist item: The existing document is updated in-place (moved from wishlist to active).
For each new ideal: A new document is created.
Replace Mode (Next? Tab only): If re-planning, old next-week records are deleted before saving new ones.
Duplicate check: See Flow 4.
Weekly Prompt: markWeeklyFlowComplete() is called explicitly on save dismiss (not relying on Firestore snapshot).
Flow 4: Duplicate Guard System
How It Works
Every ideal has a "duplicate key" = lowercase(category) + lowercase(title)
Example: "Run" in "Fitness" and "RUN" in "fitness" have the same key → treated as duplicates.
↓
Check 1 — Within the Save Request
Are there multiple ideals with the same title + category in this save attempt?
Checks across all three lists: selected ideals, wishlist items, and new ideals.
Duplicates Found
Blocked
Save is rejected
Alert shows the conflicting items. User must fix (remove one, or change its category) before trying again.
↓
Check 2 — Against Target Week
Does an ideal with the same title + category already exist in the target week?
Weekly Prompt: Checks against current week's existing ideals.
Next? Tab (Re-plan): Skipped — old plan is replaced entirely.
Already Exists
Silently Skipped
Ideal is not added (no error)
After save completes, an alert shows: "Some ideals were not added because they already exist this week."
Does Not Exist
Ideal is saved successfully