๐Ÿ“ฐ

What's New

Latest updates and improvements to Rebel Forecaster

v6.2.0Latest
2026-10-11
โœจNew
On-site check-ins for everyone โ€” Tap I'm here when you arrive and I left when you're relieved. The button shows on days you have a shift, your visits fill the Hours tab and time card, and the dashboard's Month-to-Date card compares your schedule with what really happened. Automatic check-ins by your phone stay in early access for pro testers
Month-to-Date breakdown โ€” Scheduled vs. worked hours, time you stayed late (with its extra pay), time you left early but were still paid, call shifts, call-backs and total time on site, with a "What's this?" explainer
Overtime for hand-entered shifts โ€” Tap a day you've logged in the Shift Logger and choose Add overtime (0.5h to 4h, or any amount). It's paid at that site's overtime rate and the day gets an orange dot
Overtime rate per site โ€” Set an Overtime $/hr for a location in Settings. Time past your scheduled shift end, and overtime you enter by hand, is paid at that rate instead of the regular one
Accountant report โ€” One tap on the Accountant tab makes a one-page PDF to send your accountant: the year's totals, quarterly estimated taxes with due dates, month by month, income by site and deposits by payer. On a phone it opens the share sheet so you can email it straight away
Edit your income tiers on the Plan tab โ€” Tap a tier to see what it covers, or use the pencil to change its name, amount and line items without leaving Targets. Open as many tiers as you like; they stay open next time
Out-early celebration โ€” Relieved early from a shift? The next time you open the app you get a quick celebration with the time you got back and any pay you kept anyway
Pending shifts at a glance โ€” Shifts you haven't confirmed yet show as striped fill on the Monthly tab, the dashboard bars and the rings (including the call ring), with "w/ pending" totals
Call shifts in the Pickup Planner โ€” Switch the planner to Call and pick 8, 12, 16 or 24-hour call shifts. Beeper pay follows the weekday or weekend rate for the day the call starts
"Nothing showing up?" helper โ€” If your calendar link works but no shifts come through, the app tells you why (empty calendar, shifts without times, or names that don't match), suggests names from your calendar, lets you test a word to see how many events have it, and can send Adam the details
Sign in with an email link โ€” Forgot which password you used? Get a one-time sign-in link by email instead
Year on your calendar โ€” The Targets summary shows your year's booked income, take-home after the tax set-aside, pending shifts, and what your usual pace would add for months not booked yet
๐Ÿ”„Changed
Targets, refreshed โ€” The Plan tab's Targets now match the dashboard: the same tier bar with striped pending and the surplus effect, one plain-English line ("$2,200 more, about 9h or 1 shift, reaches Fully Funded") based on your real rate and shift length, a tier checklist, and a year-by-month grid you can tap
What-If Lab removed โ€” The Plan tab is now the Pickup Planner plus Targets, built from your real schedule instead of sliders
Accountant variance โ€” Variance shows only once a month is over, in dollars and percent, colored by how close the forecast was (green within 5%, amber 5โ€“15%, red over 15%), with a legend. The Basic view now uses your logged deposits when you haven't typed an amount, and the CSV export includes every deposit and the variance %
Accountant records sync โ€” Deposits, call-backs and actual income you enter on the Accountant tab are saved to your account, so they match on every device
Pull to refresh โ€” The arrow turns as you pull, the rings spin while your shifts sync, and you see "Up to date" when it's done. The page refreshes in place instead of reloading
Burnout alert โ€” Now based on your confirmed work hours this month (the same hours as the dashboard), not a count of every calendar event
Live earnings ticker โ€” Once you use check-ins, the money ticker only runs while you're checked in
Staying on for call โ€” Staying past your shift into a call that starts right after it no longer counts as being relieved late
New default tier names โ€” New users start with Survival, Operational, Fully Funded and Freedom
"Calls held" is now "call shifts"
๐Ÿ›Fixes
Shift reminders and alerts weren't sending โ€” The daily reminder check was being blocked and never ran
Unconfirmed-shift reminder โ€” Now fires for pending shifts coming up in the next two weeks (it never did before)
Worked-hours calendar counted as schedule โ€” A second calendar used for on-site hours no longer counts as scheduled shifts in alerts
Email confirmation in a different browser โ€” Confirming your email from another browser or your mail app now works, with a clear "Sign in to get started" message
Blurred header on iPhone โ€” The top of the app no longer sits under the status bar blur in the home-screen app
Accountant table on phones โ€” The variance column was cut off on larger iPhones
Shift Logger day details on phones โ€” The day pop-up no longer runs off the right side of the screen, and each entry has its own Remove button
๐Ÿ“‹Migration
Run `database-overtime-rate.sql` (adds `overtime_rate` to locations) and `database-accountant-data.sql` (adds the `accountant_data` table). Both are already applied in production
v6.1.0
2026-10-03
โœจNew
On-site tracking (admins and pro testers) โ€” Your phone checks you in when you arrive at the hospital and out when you leave, using two shortcuts you add from Menu โ†’ On-site tracking. Visits run across midnight, a missed check-out is closed at your scheduled end and you're asked "Did you leave around 3:00 PM?", and there's an I'm here / I left button for days without the automation. Your phone does the location watching; the app only gets times. Android works through MacroDroid
Time card (admins and pro testers) โ€” Each day's scheduled shift next to when you were actually on site, with how late you were relieved ("+22m late", "12m early") and a summary like "Relieved late 9 of 16 days ยท avg 21 min"
On-site calendar (admins and pro testers) โ€” Subscribe once and your visits show on your phone's calendar next to your shifts, e.g. "OHOW Shift | 6:58 AM โ€“ 3:01 PM"
Live earnings โ€” While you're on a scheduled shift, a card shows what you've earned so far, ticking up every second, with a "+$" pop every quarter hour
Privacy receipt โ€” Tap "Synced" in the header to see when your calendar was last read, how many work events were kept, and how many other events were skipped and never saved
Calendar FAQ โ€” Plain answers to common worries ("Can you see my personal appointments?", "Can you change my calendar?") right where you connect a calendar
Try it with sample data โ€” Not ready to link a calendar? Explore a full sample dashboard first, then connect your calendar or enter shifts by hand
Calendar nudge for hand entry โ€” After a few hand-entered shifts, a card offers to let your calendar do the typing (your entered shifts stay saved)
First-use hints โ€” Short tips for things that aren't obvious (swipe to change months, tap or hover a ring, switch views, tap the center to flip stats). They show for your first few days, disappear once you've used the feature, and come back after a long break
Five load screens โ€” Calm, Monitor (ECG and vitals), Spin, Warp (hyperspace into a neon sign) and Arcade (READY PLAYER ONE), each with its own title style. New users see a different one each time; regulars get a short version with the occasional surprise
Anesthesia easter eggs โ€” Now and then the load screen says things like "Count back from 10โ€ฆ", "Milk of Amnesia" or "ABC: Airway, Breathing, Chair.", with special touches for CRNA Week, Halloween and the holidays
๐Ÿ”„Changed
A shorter dashboard โ€” The Dashboard tab now focuses on this month and today (about a third of the scrolling on a phone). The Pickup Planner moved to the top of the Plan tab, and "At a glance" and "Next 3 months" moved to the top of the Monthly tab. Entering shifts by hand? The planner stays on your dashboard
Pickup Planner on phones โ€” While you add shifts, a bar pinned to the bottom of the screen shows the impact live: shifts and hours added, your new workload zone, and the extra income, with a "+$" pop on every tap
Pickup Planner months โ€” The planner opens on the current month and has its own โ€น โ€บ arrows, separate from the dashboard's month
Tidier stats โ€” Shifts and days worked share one tile, the easter-egg line moved from under the hours bar into "Month at a glance", and the on-site stats (admins and pro testers) fold the hours difference and on-call time into Worked Hours, showing per-site tiles only when you worked 2+ sites
On-site pay counts toward your income tiers (admins and pro testers) โ€” Call-back pay and extra pay for staying late are added to the income tiers bar as they're recorded (shown as a striped "earned on site" piece and "incl. +$X on site"), so a call-back can push you into the next tier. The Accountant tab fills in recorded call-backs automatically; a manual entry for the same day isn't counted twice
Hours tab (admins and pro testers) โ€” Actual hours, the time card and on-site status now have their own tab
Today strip โ€” Earnings so far and your on-site status share one compact card at the top of the dashboard
Connecting a calendar โ€” Setup now asks where your shifts live (Apple, Google, QGenda, something else, or "my schedule isn't on a calendar") and shows a short guide for just that app. A note explains that one-tap Google sign-in is in the works with Google
Radial view โ€” Highlighting a ring hides the other rings' labels and the SURPLUS badge, hovering a ring works on laptops, and changing months resets the rings to the default view
No shifts matched? โ€” If your calendar is linked but no shifts match your keywords, the dashboard now says so and points you to your keywords or link
Clearer sync errors โ€” A failed calendar sync now shows the actual reason with a link to fix it
Calendar file upload removed โ€” Linking a calendar (or entering shifts by hand) replaces uploading a calendar file
๐Ÿ›Fixes
Menu links not opening โ€” Settings, What's New, Admin and other menu items sometimes did nothing when tapped
Call shifts counted as scheduled time โ€” On-site tracking could show a call shift as regular scheduled hours (e.g. 16h scheduled on a call day)
Friday call pay โ€” Friday calls (including Friday 3 PM โ€“ Saturday 7 AM after a day shift) now get the weeknight beeper rate. Calls that start on Saturday or Sunday get the weekend rate
Extra pay in the daily breakdown (admins and pro testers) โ€” Staying late now shows its extra pay in the "$" column (it only showed free money before)
NOW badge โ€” No longer overlaps the hours on the Monthly tab
Calendar step title โ€” New users saw the previous step's title on the calendar step of setup
๐Ÿ“‹Migration
Run `database-onsite-tracking.sql` to add the `onsite_codes` and `onsite_sessions` tables (already applied in production)
v6.0.0
2026-09-30
โœจNew
Radial view โ€” A ring-based dashboard view (formerly "Simple"). Swipe between months and the rings slide away and animate back in, while the center cycles through your key numbers every few seconds
Game-style callouts โ€” The dashboard bars now call out what's happening as it happens: RUNNING HOT, GRINDING, SURPLUS!, and more, with heat effects that build as your hours climb past healthy
Guaranteed hours โ€” Set the minimum paid hours per shift for a location (for sites that pay you even if you're sent home early). Actual Hours tracking (admins and pro testers) uses it to show "free money" (paid but not worked) and extra pay when you stay late, and labels call-back time with the call's location
Calendar link preview โ€” Before you connect a calendar, see exactly what the app will use: how many shifts it found, how many personal events it skipped, and your next few shifts
Your Data panel โ€” Settings โ†’ Calendar now shows what's stored for you (work shifts saved, personal events saved: always 0, last sync, link encryption) and how your calendar is handled, with a one-tap "Delete synced shifts" button
Guided location setup โ€” Your first work location walks you through each field with a live checklist. Added locations get hints and a "Copy pay setup" button that fills in rate, tax type, pay timing, guaranteed hours, call pay and differentials from your first location
Promo video โ€” The landing page opens with a short video of the real app (on sample data): calendar sync, both dashboard views, and the Pickup Planner, with sound effects behind a "Sound on" button
Guides โ€” Free articles on 1099 vs. W-2, CRNA call pay, and locum CRNA pay rates
๐Ÿ”„Changed
Future Forecaster is now the Pickup Planner โ€” Same tool, clearer name: tap open days to see what picking up extra shifts would do to your hours, income and goals
A fresh look, everywhere โ€” Segmented bars, glowing status dots, pop-tag badges and stat tiles carry through the dashboard, onboarding, Settings and admin, and emojis have been replaced with clean icons and dots
New header โ€” Sync status with a live dot, icon buttons for Admin, What's New, Help and Settings, a Light / Dark / Auto switch, an account menu behind your initial, and tabs styled like the Detail / Radial switch
Monthly tab redesigned โ€” The two charts are gone (hours and earnings rise and fall together, so they told the same story). Each year now has stat tiles and a 12-month strip colored by workload zone, and each month gets the dashboard's zone bar and a per-location breakdown
Onboarding makeover โ€” Step-by-step progress, playful badges, and plain-English copy throughout. Linking a calendar is marked as recommended, with a short explanation of why and how your data is handled
Work locations screen redesigned โ€” One card per location with a status badge, pills for type, tax status and extra shifts, and dashboard-style tiles for rate, pay timing and guaranteed hours
Connect-your-schedule screen โ€” Rewritten in plain English with step-by-step guides per calendar app and a clear "what we use / what we can't do" summary. One-tap Google connect is noted as coming soon
Landing page โ€” New "Built to run on your calendar" section explaining why the app runs on your calendar and how that data is protected
Admin dashboard โ€” Pop-tag callouts for new signups, trending activity, users to reach out to, and errors
Privacy Policy โ€” Calendar sections rewritten to match exactly how calendar data is handled now
๐Ÿ›Fixes
Month at a Glance flicker โ€” Messages no longer shuffle through every option while the dashboard loads (most noticeable on phones). The What-If Lab headings had the same issue
Light-mode readability โ€” Cyan and amber text that was hard to read on light backgrounds now uses deeper versions in light mode
Landing page accuracy โ€” "Connect your calendar" no longer implies one-tap Google sync, which isn't live yet
๐Ÿ”’Security
Only work events are kept โ€” Calendar feeds are filtered on the server as they're read: events without your work keywords are dropped in memory and never saved or shown. Personal events stored by earlier versions have been deleted
Encrypted calendar links โ€” Calendar links are now stored encrypted (AES-256-GCM). Existing links are encrypted automatically the next time each user's calendar syncs, and admin tools only ever see the calendar provider, never the link
Encrypted Google tokens โ€” Google Calendar sign-in tokens are encrypted the same way. Disconnecting now also revokes the app's access at Google, and the connect flow verifies a one-time code to block forged sign-in links
๐Ÿ“‹Migration
Run `database-guaranteed-hours.sql` to add `guaranteed_hours` to `locations` (already applied in production)
Run `database-privacy-cleanup.sql` to delete non-work calendar events saved by earlier versions (already run in production)
Set the `CALENDAR_URL_KEY` environment variable (32 random bytes, base64) in Vercel and `.env.local` (already set)
v5.4.1
2026-09-27
๐Ÿ”„Changed
TOS, Privacy Policy & About pages updated โ€” All three pages now reflect current features: manual entry mode, Google Calendar OAuth, call compensation, rate schedules, and usage analytics. Security descriptions simplified to focus on outcomes: data isolation, no tracking, no data selling
Admin badge layout fix โ€” Pro Tester, Manual, and calendar provider badges in the admin dashboard now render on a second line below the username instead of inline, preventing names from being truncated or hidden
Updated Privacy Policy โ€” Clarified calendar data handling and removed premature OAuth references
Mobile touch target fixes โ€” Increased tap targets across the dashboard to meet 44px accessibility minimum: BurnoutMeter month arrows, TargetsView nav arrows, WhatIfLab stepper buttons, hamburger menu, and ShiftCalculator day cells. Stats grid switched from 3-column to 2-column on mobile for readability, and minimum font sizes bumped from 8โ€“9px to 10px
Mobile formatting polish โ€” Bumped remaining sub-10px text across dashboard meta info, status badges, year summary labels, and tier bracket labels. Fixed BurnoutMeter header overlap on narrow screens by wrapping badges to a second row. Added scroll-fade hint on horizontally scrollable tables (What-If Lab, Accountant View). Clamped ShiftCalculator day popover to prevent edge overflow. Increased landing page carousel button padding and footer text size
v5.4.0
2026-09-27
โœจNew
Call Income Callout โ€” The BurnoutMeter now shows a compact callout when you have call shifts in the featured month: total call income, number of call shifts, percentage of gross income from call, and your effective hourly rate. Call hours add income without diluting your worked-hours rate
Pro Tester Access โ€” Admin can grant selected users access to beta features (like Actual Hours tracking) without giving them full admin privileges. Pro Tester badge appears next to user names in the admin dashboard
Pro Tester Badge in Admin โ€” Users with pro tester access show a purple "Pro Tester" badge in both the user list and signup funnel views for quick visibility
๐Ÿ”„Changed
Life Balance Meter Removed โ€” The work-vs-free-time stacked bar has been removed from the BurnoutMeter card. Every metric should change a decision โ€” this one didn't
Admin Dashboard Overhaul โ€” Consolidated duplicate Financial Insights, Market Signals, and Community Stats into a single Market & Financial section. Removed IP-based Access by Region (profile-based Top States is more reliable). Added Retention Cohorts heatmap and Feature Adoption panel showing data mode split, calendar provider breakdown, call comp / rate schedule / pro tester counts, and settings completion rates
๐Ÿ“‹Migration
Run `database-pro-tester.sql` to add the `pro_tester` column to `user_settings`
v5.3.0
2026-09-27
โœจNew
Manual Entry Mode โ€” New data mode that lets users log shifts by tapping days on a calendar instead of connecting an iCal feed. Choose your mode during onboarding or switch anytime in Settings โ€” your data is preserved when you switch back
Manual Mode Month Navigation โ€” Arrow buttons in the Shift Logger let you navigate forward and backward through months to log past or future shifts. The BurnoutMeter also supports free navigation in manual mode, creating stub months on the fly so you're never stuck
Mode Toggle in Settings โ€” Settings (Step 1) now shows a prominent two-panel card with your current mode highlighted by an "Active" badge and a one-tap switch to the other mode. Data retention messaging reassures users that manually logged shifts and calendar connections are kept when switching
๐Ÿ”„Changed
Save Button Moved Inline โ€” The manual mode save button now lives inside the Shift Logger calendar section instead of at the bottom of the card, so mobile users don't have to scroll past the stats panel to save
Settings Mobile Optimization โ€” Inner card padding, header spacing, and grid layouts are now responsive. Callback rate inputs stack on narrow screens, tier line-item note fields hide on mobile, and the iCal help box uses tighter padding
๐Ÿ›Fixes
Featured Month Reset After Save โ€” Saving shifts in a non-current month (e.g. October) no longer snaps the dashboard back to the current month. The featured month state now uses a functional update that preserves the user's selection
BurnoutMeter Navigation Disappearing โ€” Navigating to a month with no data in manual mode no longer hides the BurnoutMeter (and its nav arrows). The available month keys now always include adjacent months, and a stub MonthData is created for empty months
๐Ÿ“‹Migration
Run `database-manual-shifts.sql` to create the `manual_shifts` table and add the `data_mode` column to `user_settings`
v5.2.1
2026-09-23
๐Ÿ›Fixes
Paycheck Tracker checkboxes lost on app restart โ€” Marking extra shifts as paid in the "Owed to you" section now survives closing and reopening the app (or returning after the auth token expires). Root cause: `fetchPayStates` queried the shifts table without first refreshing the auth token. After ~1 hour of inactivity the access token expires, and Supabase RLS silently returns zero rows instead of an error โ€” so the component believed the database had no paid shifts and rendered everything unchecked. Fix: `fetchPayStates` now calls `getUser()` first, which forces a token refresh; if auth isn't ready it returns `null` (not an empty map), triggering a 3-tier retry: immediate โ†’ 2-second delay โ†’ auth-state-change listener with a 10-second timeout. Confirmed working with simulated expired tokens. (Thanks to the user who reported this persistently since June.)
Internal security hardening and credential rotation
v5.2.0
2026-09-14
โœจNew
Mobile Onboarding Fast Path โ€” New users on mobile can now get to the dashboard in as few as 4 taps. After entering your first keyword and rate, the wizard auto-advances to Step 2. Both Step 2 (Income Targets) and Step 3 (Calendar) can be skipped with one tap โ€” Step 2 pre-fills sensible CRNA defaults, and Step 3's skip button is now a full-sized button instead of tiny text
Desktop Setup Reminder โ€” Mobile users on Step 3 (Calendar URL) see a "Easier on a computer" banner with the option to email themselves a reminder to finish setup on desktop. Finding your Google Calendar secret URL requires desktop โ€” this bridges the gap
Rate Schedule History โ€” Locations can now have rate changes over time. Set a new rate with an effective date and past shifts calculate at the old rate while future shifts use the new one
๐Ÿ›Fixes
Magic link cross-device handling โ€” Clicking a setup reminder email on a different device (e.g., phone โ†’ computer) now gracefully falls back to a sign-in prompt instead of showing a confusing "password reset expired" error. After signing in, users land directly on the onboarding step they left off at
v5.1.0
2026-08-24
โœจNew
On-Call / Beeper Compensation โ€” Work keywords can now have a ๐Ÿ“Ÿ Call Compensation config: weeknight and weekend flat beeper pay, callback hourly rate, and minimum-hour rules (e.g. 2hr first callback, 1hr subsequent). Calendar events matching configurable call keywords (like "call", "beeper") are automatically classified as call shifts and paid at the flat beeper rate instead of regular hourly. Callback income is entered manually per month in the Accountant view
Callback Entry in Accountant View โ€” When a location has call comp configured, each month's expanded detail row shows a ๐Ÿ“Ÿ Callbacks section where you can log the number of callbacks, total hours worked, and the location. Billable hours are computed using the minimum-hour rules and the income flows into monthly actuals
Collapsible Month Rows (Accountant View) โ€” In Advanced mode, each month row is now expandable. Click to reveal deposit entries and callback entries inline, replacing the old standalone "Add Deposit" section at the bottom
Beeper Income Visibility โ€” Call shift count and beeper income are now displayed on the main dashboard (Confirmed Income and Shifts stat cells), in the Monthly table (hours and income columns), and in the Accountant expanded month detail
๐Ÿ”„Changed
Rolling Load card removed โ€” The trailing 30-day/7-day rolling hours card has been removed from the main dashboard
๐Ÿ›Fixes
Paycheck Tracker checkboxes not persisting โ€” Marking extra shifts as paid now survives tab switches and page reloads. The paid state was being overwritten by a stale database fetch on component remount; the fix merges database and localStorage states and always saves to localStorage as a backup. (Thanks to a user for the report.)
๐Ÿ“‹Migration
Run `database-call-comp.sql` to add call compensation columns (`call_weeknight_beeper`, `call_weekend_beeper`, `call_callback_rate`, `call_first_callback_min_hrs`, `call_subsequent_callback_min_hrs`, `call_keywords`) to the `locations` table
v5.0.2
2026-06-10
๐Ÿ›Fixes
Paycheck Tracker pay dates โ€” Expected-pay dates for extra shifts ran one payroll late (e.g. an Apr 25 extra predicted Jun 5 instead of May 22). The calculation is now pay-period-based: a payday pays the period ending N days before it, and extras land a set number of payrolls after that period's regular payroll. Two shifts in the same period now always share the same expected date. (Thanks to a user for the detailed report.)
๐Ÿ”„Changed
Payroll schedule settings โ€” "Pays N paydays after the shift" replaced with two clearer controls: "Period ends N days before payday" (default 6) and "Extras pay N payrolls after regular hours" (default 1 โ€” i.e. the next payroll). Existing saved settings migrate automatically.
v5.0.0
2026-06-10
โœจNew
Paycheck Tracker ("Owed to you") โ€” New card at the top of the Accountant tab tracks extra/late-paying shifts from worked to paid. Set a payroll schedule (recent payday + frequency + how many paydays after the shift it pays out) and each extra shift gets an "expected by" date, a late warning when overdue, and a checkbox to mark it paid. A running total shows what you're owed. (Thanks to a user for the idea.)
Extra keyword toggle โ€” Work keywords in Settings can now be flagged as "Extra" shifts; flagged keywords feed the Paycheck Tracker. Falls back to title matching ("extra"/"beeper") when nothing is flagged
Shifts table โ€” Matched calendar events are now materialized as per-shift database rows (facts refresh on every sync; pay status survives), the foundation for manual shift entry, per-shift overrides, and change alerts
Rolling Load card โ€” Trailing 30-day and 7-day hours plus consecutive-days streak on the dashboard; unlike the monthly meter, the window slides instead of resetting on the 1st
Forecast ranges โ€” 3-month projection cards now show confirmed -> confirmed+pending ranges for gross, take-home, and hours instead of a single point estimate
๐Ÿ”„Changed
Full visual redesign โ€” Light theme is now the default: warm cream background, white cards with soft shadows, burnt orange brand color on buttons/tabs/labels, and Bricolage Grotesque display font. Dark mode remains available via the theme toggle
Navigation simplified โ€” Targets and What-If Lab merged into a single "Plan" tab with a sub-toggle
v4.15.0
2026-05-09
โœจNew
Blended vs Primary Worksite Rate โ€” When users have 2+ work locations, step 1 of onboarding now asks whether to calculate hours using a blended average of all sites or a single primary worksite rate. The choice persists in `rate_mode` / `primary_work_keyword` columns and drives all recommended hour calculations in step 2
Surplus Highlight Card โ€” The Income Targets dashboard now shows a prominent teal-gradient card when income exceeds the top tier, making surplus earnings immediately visible instead of buried in overflow text on the bar
๐Ÿ”„Changed
Onboarding Tier Names โ€” Default income tiers renamed from Survival / Operational / Fully Funded to Non-Negotiables / Comfortable / Goal / Surplus. Users can rename tiers to anything they want โ€” custom names carry through to the dashboard
Onboarding Workload Zone Labels โ€” Zone labels now directly mirror tier names: "Cover Non-Negotiables", "Reach Comfortable", "Hit Goal" instead of generic "Light Month", "Comfortable", "Typical Month"
Onboarding Step 2 Copy โ€” Intro text and tier descriptions rewritten with a forecast/weather theme. Tier descriptions guide users through layering expenses from non-negotiables up to investing/retirement goals
Ghost Placeholder Workload Zones โ€” Lower workload zone fields (t_min, t_comf, t_avg) now show recommended hours as grey placeholder text derived from income tiers and hourly rate. Users can click into any field to override
Dashboard Tier Descriptions โ€” Tier card descriptions now adapt to tier names (e.g. "Bills that never wait" for Non-Negotiables) with position-based fallbacks for custom names
๐Ÿ›Fixes
Google OAuth State Loss โ€” Connecting Google Calendar no longer loses all onboarding progress. Keywords and settings are now saved to the database before the OAuth redirect
Persistent Validation Errors โ€” "Add at least one Work keyword" error no longer persists across step navigation
Ghost Placeholders Not Showing โ€” Fixed issue where previously-saved default threshold values (60/80/120) masked the ghost placeholder behavior for returning users
๐Ÿ“‹Migration
Run `database-rate-mode.sql` to add `rate_mode` and `primary_work_keyword` columns to `user_settings`
v4.14.0
2026-05-07
โœจNew
Quarterly Tax Deadline Banner โ€” Dashboard now shows a dismissable alert 14 days before each federal estimated tax payment deadline (Apr 15, Jun 15, Sep 15, Jan 15). Urgency escalates from calm at 14 days, to amber warning at 3 days, to red alert on the due date. Includes a direct "Pay on IRS.gov" link. Dismiss is per-quarter so future deadlines still appear
Cross-Platform Install Prompt โ€” The existing iOS Safari "Add to Home Screen" prompt now also supports Android and Chrome desktop via the native `beforeinstallprompt` API. Android/Chrome users see a one-tap "Install App" button instead of manual instructions
๐Ÿ›Fixes
Settings Save Fallback for Pre-Migration Databases โ€” The settings API now gracefully handles databases that haven't run the shift differentials migration. If the insert fails due to missing diff columns, it retries without those fields and returns a `diffColumnsAvailable: false` flag instead of losing the user's data. Includes rollback protection that restores previous locations if the insert fails
Google OAuth Consent Screen โ€” Added missing email, profile, and openid scopes to the Google Cloud Console Data Access configuration. Resolves the "unverified app" warning screen some users encountered during sign-in
v4.13.0
2026-04-13
โœจNew
Shift Differentials per Location (W-2 only) โ€” W-2 hospital jobs can now break out night, weekend, and holiday premium pay on top of the base rate. The "Shift differentials" panel only appears on work keywords marked W-2, since this is a hospital-employment concept (1099 locum gigs pay a flat contracted rate). Each W-2 work keyword has an optional panel with four inputs (weeknight, weekend day, weekend night, holiday), a configurable night-window (default 7 PM โ€“ 7 AM), and a toggle for US federal holidays. The parser walks every shift in 5-minute slices and classifies each slice by day-of-week + time-of-day, so a shift that straddles the night window or crosses midnight is calculated correctly. Highest applicable diff wins โ€” holiday > weekend > weeknight (no double-stacking). Existing users see no change until they enter rates. Use case: a Truman night at $80 base + $100 weekend-night diff = $180/hr on Sat night, $80 + $30 = $110/hr on a weeknight
Per-Shift Pay Breakdown โ€” Each shift now carries a `payBreakdown` object (base hours ร— base rate, plus hours and amount for each diff tier) so the dashboard can show exactly how each paycheck was assembled
๐Ÿ“‹Migration
New columns on the `locations` table: `weeknight_diff_rate`, `weekend_day_diff_rate`, `weekend_night_diff_rate`, `holiday_diff_rate`, `night_start_hour`, `night_end_hour`, `holidays_enabled`. All default to 0/false. Run `database-shift-differentials.sql` to apply
v4.12.1
2026-04-13
โœจNew
Install to Home Screen Prompt โ€” iPhone Safari users now see a dismissable "Install Rebel Forecaster" banner on the dashboard and in onboarding, with a step-by-step guide to adding the app to their home screen. Auto-hides for users who already installed, aren't on iOS Safari, or dismissed it (re-appears after 30 days)
๐Ÿ›Fixes
Recurring Shifts Across Timezones โ€” Fixed a critical bug where recurring shifts with overnight or evening start times (e.g. 7pmโ€“7am) landed on the wrong day of the week when the sync ran on the production server. Affected anyone whose iCal feed declared events in a US timezone and used RRULE with BYDAY (Apple Calendar's "every 4 weeks" and similar). Days you had deleted from a recurring series are now properly excluded
DST Drift on Recurring Events โ€” Recurring shift times no longer drift by an hour after a daylight saving transition. A 7pm shift in January will now still be 7pm after March's time change, instead of silently shifting to 8pm
EXDATE Respects Timezone โ€” Exception dates (deleted occurrences in Apple Calendar) are now matched using the event's declared timezone instead of the server's timezone, so exclusions work correctly for everyone regardless of where the sync is running
App Icon โ€” PWA homescreen icon is now a clean white-on-black circular logo instead of the black-on-white logo with a white square background
v4.12.0
2026-04-12
โœจNew
Push Notifications (PWA) โ€” Rebel Forecaster is now installable as a Progressive Web App. Enable push notifications from Settings to get alerts on your phone or desktop โ€” no app store required
Notification Types โ€” Six configurable alert categories: sync health (stale calendar), burnout threshold warnings, quarterly tax reminders, shift gap detection, unconfirmed shift reminders, and monthly digest
Notification Preferences โ€” Per-notification toggle switches in Settings let you choose exactly which alerts you want. Disable any you don't need
Test Notification โ€” Send yourself a test push from Settings to verify everything is working
Service Worker โ€” Background service worker handles push delivery, click-to-open, and basic offline caching for static assets
๐Ÿ”„Changed
Public Landing Page โ€” Root URL now shows a clean public landing page with app description and sign-in/create account buttons instead of redirecting straight to login. Required for Google OAuth brand verification
Onboarding: iCal Fields โ€” iCal URL inputs and help text are now hidden when Google Calendar is connected (no more confusing "ghost text" in empty placeholder fields). Fields reappear if you have both Google and iCal URLs
Onboarding: Placeholder Text โ€” Primary calendar URL placeholder changed from a URL that looked like real data to "Paste your iCal URL here"
Privacy Policy โ€” Updated to include Google Calendar OAuth details (read-only access, token storage, revocation)
v4.11.0
2026-04-11
โœจNew
Google Calendar OAuth โ€” Connect your Google Calendar with one click. Read-only access via OAuth 2.0 โ€” we can only view your events, never modify them
Dashboard Empty State โ€” New rich card shown when no calendar is connected, with Google Calendar and iCal/Apple/QGenda connection options and a compact file-drop fallback
Google Connection Status โ€” Settings page shows connected Google account email with a disconnect button
๐Ÿ›Fixes
Double-Sync Race Condition โ€” Fixed a bug where the dashboard would trigger two concurrent calendar syncs on load, causing glitchy data display
Google-Only Sync โ€” Users with only Google Calendar (no iCal URL) can now sync properly. Fixed stale React closure that blocked sync after Google status check
v4.10.1
2026-04-03
๐Ÿ”„Changed
CORS Protection โ€” API routes now reject cross-origin requests from unknown domains. Only the production app and preview deploys are allowed through
Settings Input Validation โ€” All numeric settings (hour thresholds, tax rate, hourly rates, income goals) are now clamped to sane ranges server-side. Locations capped at 50 per user with keyword length limits
Error Message Cleanup โ€” API error responses no longer leak raw database details. Generic messages returned to clients, detailed errors logged server-side only
๐Ÿ›Fixes
Calendar URL Security โ€” Calendar URL input now explicitly blocks non-https protocols (javascript:, data:, file:, ftp:)
Ratings Validation โ€” Added max-length limits on facility names (255 chars) and comments (5,000 chars). All sub-ratings (compensation, management, etc.) are now validated to 1โ€“5 range
Request Timeouts โ€” Feedback and notification endpoints now abort after 10 seconds if the external service hangs, preventing Vercel function timeouts
v4.10.0
2026-04-03
โœจNew
What-If Lab โ€” Brand new "What-If Lab" tab for playing with income scenarios. Three preset lanes โ€” Survivor, Operator, and Rebel โ€” each projecting monthly and annual income based on adjustable shift parameters
Scenario Stepper Controls โ€” Tap any scenario card to expand interactive dials for shifts/week, hours/shift, call shifts, weekend shifts, OT hours, and hourly rate. Uses clean +/โˆ’ stepper inputs instead of sliders for precision on any device
Custom Rate Override โ€” Toggle from your blended average rate to a custom rate per scenario. Quick-pick buttons let you snap to any of your configured location rates instantly
Income Breakdown โ€” Expanded scenarios show how income splits across base shifts, call premium (15%), weekend premium (25%), and overtime (1.5x) with proportional bars
Side-by-Side Comparison โ€” Animated horizontal bars compare all three scenarios at a glance with tier zone markers overlaid
The Year Ahead Table โ€” 12-month outlook comparing monthly gross, take-home, hours, annual totals, tax set-aside, and landing zone across all scenarios
Zone Landing Visualization โ€” Each scenario shows which income tier it lands in with highlighted cards and a "YOU'RE HERE" indicator
Tax-Aware Projections โ€” All scenarios factor in your 1099/W-2 income ratio and tax rate to show realistic take-home estimates
๐Ÿ”„Changed
Mobile Header Cleanup โ€” Theme toggle (light/dark/auto) and Settings button are now hidden on mobile to reduce clutter. Both are accessible via the hamburger menu instead
Hamburger Menu Enhancements โ€” Added inline theme switcher and "Upload New File" option to the hamburger menu for mobile users
Upload Button Mobile โ€” "Upload new file" link on the dashboard is now hidden on mobile since it's available in the hamburger menu
Income Tracker Card Alignment โ€” Tier detail cards below the progress bar now align precisely with the zone bracket labels above them
What-If Lab Mobile Layout โ€” Scenario cards stack vertically on mobile with a horizontal layout (name/tagline left, money right) for better readability. Stepper controls are fully touch-friendly
v4.9.0
2026-04-02
โœจNew
Income Tiers โ€” Replace the single monthly income goal with customizable tiers (e.g. Survival, Operational, Fully Funded). Set as many as you need in Settings โ€” the dashboard shows progress against all of them
Tier Line Items โ€” Each tier can optionally include a breakdown of what it covers (distributions, insurance, retirement, etc.) with an auto-sum button that calculates the tier total from its line items
Targets Tab โ€” New dashboard tab between Monthly and Accountant. Shows tier detail cards with progress bars, current month pace projection, year-at-a-glance tier achievement grid, and annual summary stats
Pace Tracking โ€” Targets tab shows your daily income rate, projected month-end income, and which tier you're on track for โ€” with actionable insights like "On pace for Operational. $4K more would reach Fully Funded"
Year-at-a-Glance โ€” Color-coded 12-month grid showing which tier each month achieved, with hit ratios per tier and annual trend tracking
Annual Summary โ€” YTD income, monthly average, best month, top tier hit rate, and annual income projection based on your current pace
Multi-Tier Progress Bars โ€” BurnoutMeter, Future Forecaster, and 3-Month Projection all show tier markers and tier-aware progress instead of a single goal line
๐Ÿ”„Changed
Income Goal โ†’ Tiers โ€” Settings page replaces the single "Monthly Income Goal" input with a full tier editor supporting names, dollar amounts, and optional line-item breakdowns
Insights โ€” BurnoutMeter insights now reference tiers by name ("Survival hit, $4K to Operational") instead of a generic "income goal"
Projection Cards โ€” 3-month projection cards show tier context ("Operational โœ“ ยท $4K to Fully Funded") instead of a raw dollar gap
Backward Compatible โ€” Users who haven't set tiers keep their existing single income goal behavior unchanged
v4.8.0
2026-03-29
โœจNew
Unified Keyword System โ€” Locations and vacation keywords are now a single list. Each keyword has a type: Work, Paid PTO, Unpaid PTO, or Ignore. No more managing two separate lists
Ignore Keyword Type โ€” Events matching "Ignore" keywords (e.g. "Unavailable") are completely hidden from the dashboard. They don't count toward pay, burnout, or anything else
Unpaid PTO Type โ€” Events like QGenda "Unavailable" blocks can be tagged as unpaid PTO โ€” shows as time off with no income or burnout impact
Cycle-Through Type Selector โ€” Click the type badge on any keyword in Settings to cycle through Work โ†’ Paid PTO โ†’ PTO โ†’ Ignore
Legacy Migration โ€” Existing users' vacation keywords automatically merge into the unified list on their next settings save
๐Ÿ”„Changed
OnboardingFlow Step 1 โ€” Replaced separate "Locations" and "PTO Keywords" sections with one unified keyword list. Each row shows color picker (for Work), keyword input, rate (for Work/Paid PTO), W-2/1099 toggle (for Work/Paid PTO), and type badge
Settings API โ€” `/api/settings` now persists `keyword_type` for each location row in the `locations` table
Calendar API โ€” `/api/calendar` now loads all keyword types from `locations` table and builds unified keyword list for the parser
ICS Parser โ€” `parseICS()` accepts optional `unifiedKeywords` parameter; Ignore-type events are dropped before they reach calculations
LocationRate filtering โ€” Dashboard now filters to work-type keywords only when building `LocationRate[]` for downstream components
๐Ÿ›Fixes
"Unavailable" counted as shifts โ€” QGenda "Unavailable" events were being treated as work shifts because they had hours > 0 and matched no location. Now users can add "Unavailable" as an Ignore or Unpaid PTO keyword to exclude them
v4.7.0
2026-03-29
โœจNew
Configurable PTO / Vacation Keywords โ€” Users can now define custom keywords (e.g. "PTO", "TAFP", "Vacation") in Settings to identify time-off events in their calendar. No longer hardcoded to "vacation" only
Paid Vacation Toggle โ€” Each vacation keyword has a "Paid / Unpaid" toggle. Paid PTO counts income at the matched location rate but does NOT count toward burnout hours or work days
PTO Hourly Rate โ€” Each paid vacation keyword can have its own $/hr rate as a fallback when the event title doesn't match a location keyword
Timed PTO Support โ€” Vacation detection no longer requires all-day events. Timed PTO blocks (e.g. 8hr or 12hr TAFP events from QGenda/ShiftAdmin) are now properly recognized
Paid PTO Dashboard Display โ€” BurnoutMeter shows paid PTO days separately with a green callout. Time Off stat cell breaks down paid vs unpaid days
12h and 24h Shift Duration Buttons โ€” Future Forecaster simulator now offers 4h, 8h, 10h, 12h, and 24h shift options for scheduling systems that use longer shifts
Shift Detail Popover โ€” Click any worked or vacation day on the Future Forecaster calendar to see event name, hours, rate, income, and location details
๐Ÿ”„Changed
Vacation detection โ€” Moved from hardcoded `isAllDayEvent && summary.includes('vacation')` to configurable keyword matching that works with both all-day and timed events
ICS Parser โ€” `parseICS()` now accepts optional `vacationKeywords` parameter; defaults to `[{ keyword: 'vacation', paid: false }]` for backward compatibility
Calendar API โ€” `/api/calendar` now loads `vacation_keywords` from user settings and passes them to the parser
Settings API โ€” `/api/settings` now persists the `vacation_keywords` JSONB field
๐Ÿ›Fixes
All-day event timezone offset โ€” All-day events (vacation, TAFP weeks) were showing one day early because midnight UTC shifted to the previous day in US timezones. Fixed by anchoring date-only events to noon UTC
Keyword matching priority โ€” Events with multiple matching keywords (e.g. "OP APP - Extra 24 7a-7a" matching both "OP APP" and "Extra") now correctly pick the most specific keyword by choosing the one appearing latest in the event title, instead of the first match found
v4.6.0
2026-03-23
โœจNew
W-2 / 1099 Work Type per Location โ€” Each location now has a work type toggle (1099 or W-2) in onboarding, shown as a colored badge button. 1099 locations apply your tax rate to income; W-2 locations pass through at full gross since the employer handles withholding
Smart Take-Home Calculations โ€” New `takeHomeMonth()` calculation function that applies the tax rate only to 1099 location income and leaves W-2 income untouched. All dashboard components (BurnoutMeter, SummaryCards, MonthlyTable, ProjectionStrip, AccountantView, ShiftCalculator) now use this split
Per-Location Work Type in Data Model โ€” `MonthData` now tracks `income1099`, `incomeW2`, `potentialIncome1099`, `potentialIncomeW2`, and `locationWorkType` for accurate downstream calculations
๐Ÿ”„Changed
Future Forecaster โ€” Simulated take-home now respects work type: simulating shifts at a W-2 location does not deduct taxes from the projected take-home; 1099 locations still apply the tax rate
Onboarding tax rate label โ€” Updated from "Applied to gross income" to "Applied to 1099 income only" to reflect the new split behavior
Settings API โ€” `/api/settings` now persists the `work_type` field when saving location data
v4.3.0
2026-03-21
โœจNew
Anonymized Community Stats โ€” New `get_anonymous_stats()` PostgreSQL function that returns only aggregated data (averages, medians, distributions) with k-anonymity enforcement (kโ‰ฅ5 by default)
Facility Ratings system โ€” New `facility_ratings` table with 5-category star ratings (overall, compensation, work-life balance, management, staffing) plus optional anonymous comments
Ratings API (`/api/ratings`) โ€” Full CRUD for user's own facility ratings with upsert support (one rating per user per facility)
Stats API (`/api/stats`) โ€” Returns anonymized aggregate data from `get_anonymous_stats()` function, available to all authenticated users
FacilityRatings component โ€” Star-rating UI with facility name suggestions from existing locations, state selector, and comment field (component built but not yet wired into dashboard nav)
Database migration (`database-anonymized-stats.sql`) โ€” Full migration for facility_ratings table, RLS policies, indexes, and the aggregate stats function
What's New page (`/updates`) โ€” Public page that auto-generates release notes from CHANGELOG.md with version badges, emoji-coded sections, and formatted entries
Hamburger menu โ€” Top bar nav buttons now collapse into a dropdown menu that shows user info, version, sync time, and all nav links. Cleaner at all screen sizes
๐Ÿ”„Changed
Months Under Min / High-Load Months โ€” Now only looks forward from the current month. Past months no longer show up in these burnout warning cards
Top bar responsiveness โ€” Condensed nav buttons, moved version/user info into the dropdown menu. Hamburger menu always available
๐Ÿ”’Security
All public-facing stats enforce k-anonymity: data only shown when group has 5+ users, preventing re-identification
Facility ratings RLS: users can only manage their own ratings
`get_anonymous_stats()` is SECURITY DEFINER โ€” bypasses RLS to aggregate without exposing individual rows
No user IDs, emails, or names ever appear in anonymized stats output
v4.2.0
2026-03-21
โœจNew
About page (`/about`) โ€” Public page explaining mission, security practices, beta status, and contact info
Strong password requirements โ€” 8+ characters, uppercase, lowercase, and number required for signup and password reset, with live validation checklist
Month-by-Month year banner โ€” Rich dark summary bar with Hours, Confirmed $, Take-Home, Pending, Vacation stats
"Month-by-Month Breakdown" section label and updated column headers (Projected Income, Burnout Meter, Zone)
CHANGELOG.md โ€” This file
๐Ÿ”„Changed
Renamed "Rebel Forecast" โ†’ "Rebel Forecaster" across all pages (top bar, login, onboarding, browser tab title)
3-Month Projection cards โ€” Now show only real shift data (no more projected averages). Richer layout with take-home, hours, confirmed/pending breakdown, income goal gap, and status badges with colored borders
SummaryCards "Avg Monthly Income" โ€” Fixed rolling average to filter months with income first, then take top 6 (instead of slicing first then filtering, which caused "last 1 mo" bug)
SummaryCards "+Potential" line โ€” Combined into single line: "+$111,000 potential" instead of two separate lines
Future Forecaster โ€” Now only marks calendar days as "worked" if the event matches a known location keyword. Flights and personal events no longer count as shifts
๐Ÿ›Fixes
Flight events counted as shifts โ€” Events like "Flight 1 of 4 | DL1151" were showing as worked days in the Future Forecaster because any timed event with hours > 0 was treated as a shift. Now requires location keyword match
"last 1 mo" in Avg Monthly Income โ€” Rolling average logic was slicing to 6 months first, then filtering for income > 0, which could result in as few as 1 month. Fixed by filtering first
Middleware blocking /about โ€” Unauthenticated users were redirected to /auth when visiting /about. Added /about to middleware whitelist
๐Ÿ”’Security
Password minimum increased from 6 โ†’ 8 characters
Added uppercase, lowercase, and number requirements
Live validation checklist on signup and password reset forms
v4.1.0
2026-03-20
โœจNew
Enriched BurnoutMeter stat cells with multi-line detail (pending hours, potential totals, per-shift averages)
Enriched SummaryCards with take-home estimates, potential income section, annualized figures
Info icon (โ“˜) popup system on SummaryCards explaining each card's calculation logic
"Pending Only" status badge for months with 0 confirmed but pending hours in MonthlyTable
Mobile-responsive MonthlyTable redesign (card layout instead of cramped table)
Bigger "Rebel Forecast" title in top bar
๐Ÿ›Fixes
`md` โ†’ `monthData` variable bug in MonthlyTable.tsx that was blocking Vercel build
Next.js security vulnerability (14.2.3 โ†’ 14.2.35) โ€” package-lock.json was pinning old version
v4.0.0
2026-03 (Initial Build)
โœจNew
Full Next.js 14 + Supabase + TypeScript + Tailwind CSS app
Supabase auth (email/password signup, signin, password reset flow)
Calendar sync via iCal URLs with vacation detection and multi-day expansion
BurnoutMeter with SVG donut chart, zone bar, income goal needle
ShiftCalculator (Future Forecaster) with interactive calendar simulation
MonthlyTable with year grouping and expandable rows
SummaryCards with year-to-date stats
ProjectionStrip (3-Month Projection)
AccountantView for tax-focused reporting
Light/dark theme system with CSS variables
Location-colored shift calendar and stacked location bars
`pushit` shell script for one-command deploy
Onboarding flow for new users
Middleware for auth protection and password reset routing