BACKLOG · SQUARELY · BACKEND

Squarely PR #47 - merge + deploy backend timezone fix?

Stale 41-day PR on the iOS backend. Single file, +32/-8, well-scoped. Sat unmerged because no founder-visible gate existed; this page IS the gate.

PR #47 (fix/backend-localdate-parsing) fixes a quiet correctness bug in the Squarely iOS backend: when the iOS app calls Firebase Cloud Functions via raw URLSession (bypassing the Firebase SDK), request.data arrives empty and the function falls through to a UTC-based getTodayDateString(). Result: the daily puzzle resets at UTC midnight (8pm Eastern) instead of the user's local midnight. The fix adds a getRequestData() helper that reads request.data first and falls back to parsing the raw {"data": {...}} wrapper from URLSession-style POST bodies; all functions in squarely-backend/functions/src/index.ts now use the helper. The PR has sat 41 days not because it was wrong but because the original cron deploy gate was never built. This page is the gate.

The ask

Merge PR #47 and deploy the Firebase functions. One file changed (squarely-backend/functions/src/index.ts), +32/-8. Deploy is one command: cd squarely-backend && firebase deploy --only functions. PR has sat 41 days behind a missing gate; founder greenlight here is what unsticks it.

What the fix does

Why this matters now

The daily-mechanic launch decision was just APPROVED-then-DEFERRED earlier today (see cross-ref below). The deferred piece - the 5-vs-3 difficulty fork - assumes the daily puzzle resets at local midnight. Today, it doesn't. With current production behavior, the daily puzzle rolls over at UTC midnight, which is:

In other words: the daily-mechanic launch cannot be considered live-correct until this PR ships. It's not optional polish - it's the prerequisite for the launch decision the founder just approved in principle.

Risk

DimensionRead
Blast radiusLow. One file (index.ts), +32/-8 lines. Helper is additive; existing request.data path is preserved as the first branch of the helper.
RollbackTrivial. firebase functions:rollback or re-deploy previous commit. Functions are stateless; no DB migration.
VerificationSingle curl confirms the fix in <5 seconds. Returns wrong date today, correct date after deploy.
DownstreamiOS app already sends localDate via the URLSession path. Backend ignoring it is the bug; backend honoring it is what the iOS code was always written to expect. No coordinated iOS release needed.
Auth / billing / data shapeUntouched. Helper only changes how the request envelope is parsed; response shape unchanged.

Why it's been stale

PR #47 was opened 2026-04-11 and has sat 41 days. The PR isn't wrong - it's a clean surgical fix with a verification recipe attached. It sat because there was no founder-visible merge-gate. The original plan called for a cron deploy gate; that gate was never built. Without a surface, the PR fell off the queue. This decision page is the replacement gate: a click-back lock-in instead of a scheduled cron.

Cross-reference

Paired decision: 2026-05-11 daily-mechanic launch decision (approved in principle, 5-vs-3 difficulty fork deferred). PR #47 is the timezone-correctness prerequisite for that launch.

Lock in

Approve - merge + deploy

Ray merges PR #47 to main and runs firebase deploy --only functions. Verifies the curl returns the expected localDate. This unblocks the daily-mechanic launch decision that was deferred earlier today - once the timezone fix is live, the 5-vs-3 difficulty fork becomes pickable. Use the field for any deploy notes (e.g. "deploy at 9pm ET after my next push").

Approve + send
Archive - close PR without merging

Discard PR + close. Nothing breaks immediately (UTC midnight reset is the current behavior, and current users tolerate it). But this also blocks the daily-mechanic launch from being correct for any user east of UTC. Choose this only if the daily-mechanic launch is being shelved or rescoped. Use the field for the reason.

Archive + send
Split - approve concept, iterate implementation

The bug-and-direction is right, but you want the implementation different - e.g. centralize the helper in a shared utils module instead of inlining it in index.ts, or add a unit test for the URLSession parsing path before merging. Name what; Ray re-files as v1.1.

Split + send
Defer - park until

Hold the merge until a date or catalyst. Note: deferring this also implicitly defers the daily-mechanic launch's correctness story.

Defer + send