This repository was archived by the owner on Aug 23, 2026. It is now read-only.
Repository navigation
refactor(quality): Rector wave 7 — Date facade and today() (AID-541) - #194
Merged
Merged
Conversation
…AID-552) The last_blocked_at assertion re-evaluated now()->subDay() and compared its app-timezone date against the model's UTC ISO serialization. .env.testing runs Europe/Madrid, so between 00:00 and 02:00 local the two calendars disagree by one day and the test goes red — exactly the window where tonight's check-full ran (00:57). Latent since it was written; outside the window it always passed. Fix follows the sibling test in the same file: capture a single time origin once ($lastBlock = now()->subDay()->startOfSecond()), feed it to the factory AND the assertion, and pin the exact contract (toBe($lastBlock->toISOString())) instead of a substring. startOfSecond matches the database's second-precision storage. No clock freezing — that would hide the symptom, not remove the double evaluation. Reproduced on both sides of the window with setTestNow: the old assertion fails at 00:57 Madrid (searches 2026-07-17 inside 2026-07-16T22:57:14Z) and passes at noon; the new one passes in both. Unrelated to the Rector wave in the next commit — split out per the axis AID-499 pattern: a pre-existing test fix that unblocks a gate goes in its own commit with its own ticket. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Enable CarbonToDateFacadeRector and NowFuncWithStartOfDayMethodCallToTodayFuncRector; apply with cleared cache: 6 app/ files (the ticket said 4+2, but the 2 today() sites shared one file and two more Carbon sites surfaced on the full run — the dry-run listing had been truncated by a head cut when first sized). The ticket's headline risk — "changes the runtime class" — is refuted, not assumed away: no Date::use()/DateFactory configuration exists anywhere, so the Date facade fabricates Carbon\Carbon and the concrete runtime class does not change at all. Remaining checks: zero `instanceof Carbon` repo-wide; every converted value is consumed immediately (->toDateTimeString(), ->format(), ->greaterThan(), SQL comparison) so the object never escapes a boundary; today() ≡ now()->startOfDay() under the app's single timezone; and both forms honour Carbon::setTestNow(). The facade keeps Date::use() available as a future seam and is the Laravel idiom (per the CLAUDE.md anchor). Hand finish: CommandOutputParserTrait kept a dead `use Carbon\Carbon` (its only remaining "use" was a comment) — Pint's preset here does not enforce no_unused_imports, so the import and the now-lying comment were removed manually. Wave checklist: - resized with --clear-cache - both rules bite, attributably: Carbon::now() probe -> exit 2 naming ProbeCarbon.php (CarbonToDateFacadeRector); now()->startOfDay() probe -> exit 2 naming ProbeToday.php (NowFunc...TodayFuncRector) - idempotence: second rector+pint pass is a byte-level no-op - refactor:dry (cleared cache) exit 0 on the applied tree Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Seventh wave, split from AID-531 over temporal semantics. 6 app/ files (the ticket said 4+2: the two
today()sites share one file, and two more Carbon sites surfaced on the full run — the initial dry-run listing had been truncated by aheadcut when first sized).The headline risk is refuted, not assumed away
The ticket feared "changes the runtime class". No
Date::use()/DateFactoryconfiguration exists anywhere, so theDatefacade fabricatesCarbon\Carbon— the concrete runtime class does not change at all. Remaining checks, all verified repo-wide:instanceof Carbon->toDateTimeString(),->format(),->greaterThan(), SQL comparison) — the object never escapes a boundarytoday()≡now()->startOfDay()under the app's single timezone; both honourCarbon::setTestNow()Date::use()available as a future seam and is the Laravel idiomHand finish:
CommandOutputParserTraitkept a deaduse Carbon\Carbon(its only remaining "use" was a comment) — Pint's preset here does not enforceno_unused_imports, so import and now-lying comment were removed manually.First commit: deterministic midnight-window flake fixed (AID-552)
check-fullwent red at 00:57 local on a test untouched by this wave:CheckRecentBlockHistoryActionTestre-evaluatednow()->subDay()and compared its app-timezone date (.env.testingruns Europe/Madrid) against the UTC ISO serialization. Between 00:00–02:00 CEST the calendars disagree by one day — red only in that window, latent since written.Reproduced on both sides of the window with
setTestNow: old assertion fails at 00:57 Madrid (searches2026-07-17inside2026-07-16T22:57:14Z), passes at noon; the fixed one (single captured time origin +toBe($lastBlock->toISOString()), matching the sibling test's style) passes in both. Split into its own commit with its own ticket per the axis AID-499 pattern.Gates
Carbon::now()probe →rc=2namingProbeCarbon.php;now()->startOfDay()probe →rc=2namingProbeToday.phprefactor:dry(cleared cache) exit 0composer check-full→ exit 0, 1442 passed / 16 skipped, coverage 89.8%