Skip to content

ORBIT0004 pre-existing exemption ledger: audit each UTC-instant site #431

Description

@thomasluizon

PR #427 introduced ORBIT0004 (raw DateTime.UtcNow for user-facing dates is a build error). The 52 pre-existing sites below (50 #pragma warning disable ORBIT0004 blocks; adjacent sites share a block) were measured with a real analyzer-enabled build and exempted because each is a deliberate UTC instant or a deliberate UTC-date bucket, not a user-facing date. Every pragma's WHY comment links this issue.

This ledger exists so each site keeps an explicit justification and can be re-audited. If any site's justification stops holding, fix the site and drop its pragma. One site found mischaracterized in review (ProfileController data-export filename) was already fixed properly with IUserDateService instead of a pragma and is not listed here.

Legend: instant = UTC moment used for expiry/TTL/cutoff/audit-timestamp math (timezone-correct by definition). bucket = UTC calendar-date used as a widened prefetch window or a UTC-keyed dedupe/aggregation key, with the per-user date still computed via TimeZoneInfo/IUserDateService downstream.

Orbit.Api

  • Controllers/SyncController.cs (2 sites, instant): sync-window guard against since and the ServerTimestamp field of the sync envelope; wire-protocol UTC instants.
  • OAuth/OAuthAuthorizationStore.cs (3 sites, instant): OAuth authorization-code CreatedAt stamp, code-expiry check, and expired-entry sweep cutoff.

Orbit.Application

  • Auth/Commands/RequestAccountDeletionCommand.cs (2 sites, instant): verification-code resend throttle elapsed math and VerificationEntry creation stamp.
  • Auth/Commands/SendCodeCommand.cs (4 sites, instant): same VerificationEntry throttle/TTL instants for send-code (including test-account and smoke-code paths).
  • Calendar/Commands/DismissCalendarSuggestionCommand.cs (1 site, instant): MarkDismissed(now) audit timestamp.
  • Habits/Commands/BulkCreateHabitsCommand.cs (1 site, instant): MarkImported(habitId, now) ImportedAtUtc audit timestamp for calendar suggestions.
  • Waitlist/Commands/JoinWaitlistCommand.cs (1 site, instant): 60-second resend-throttle elapsed math against the cached last-sent instant.

Orbit.Infrastructure

  • AI/AiUsageRecorder.cs (1 site, bucket): UTC-day key for the AiUsageDaily cost-aggregation row.
  • Persistence/OrbitDbContext.cs (1 site, instant): UpdatedAtUtc stamping for all tracked ITimestamped entities in SaveChangesAsync.
  • Services/AccountDeletionService.cs (3 sites: 2 instant, 1 bucket): scheduled-deletion due check, ProcessedRequest retention cutoff, and the 90-day UTC-date purge cutoff.
  • Services/AgentStepUpService.cs (3 sites, instant): step-up challenge cooldown boundary, challenge TTL, and CanVerify expiry check.
  • Services/AiUsageSummaryService.cs (1 site, bucket): UTC "yesterday" key for the daily AI-cost summary log.
  • Services/AuthSessionService.cs (5 sites, instant): session issue/refresh/revoke instants and refresh-token expiry math.
  • Services/BackgroundServiceHealthCheck.cs (2 sites, instant): liveness tick stamp and elapsed-since-last-tick math.
  • Services/GoalDeadlineNotificationService.cs (1 site, bucket): widened UTC streak-lookback prefetch window; per-user today comes from TimeZoneInfo.ConvertTimeFromUtc afterwards.
  • Services/GooglePlayBillingService.cs (2 sites, instant): Play subscription expiry fallback and validity comparison.
  • Services/HabitDueDateAdvancementService.cs (1 site, bucket): widened UTC "yesterday" prefetch window; per-user advancement uses the converted user clock.
  • Services/JwtTokenService.cs (1 site, instant): JWT Expires claim.
  • Services/PendingAgentOperationStore.cs (1 site, instant): pending-operation usability/expiry check.
  • Services/PendingClarificationStore.cs (2 sites, instant): clarification TTL stamp and expiry sweep.
  • Services/PlayNotificationCleanupService.cs (2 sites, instant): Play/Stripe processed-event retention cutoffs.
  • Services/ProactiveCheckinSchedulerService.cs (1 site, bucket): UTC-date dedupe key for SentProactiveCheckin; per-user send timing uses the converted user clock.
  • Services/ReminderSchedulerService.cs (6 sites, bucket): widened UTC-date prefetch windows (min/max local date across all timezones) and UTC-date dedupe keys; per-user reminder timing uses the converted user clock.
  • Services/SlipAlertSchedulerService.cs (1 site, bucket): UTC-date week key for SentSlipAlert dedupe.
  • Services/StreakFreezeAutoActivationService.cs (1 site, bucket): widened UTC "yesterday" prefetch window; per-user freeze decision uses the converted user clock.
  • Services/StripeBillingService.cs (1 site, instant): CurrentPeriodEnd fallback instant.
  • Services/SyncCleanupService.cs (2 sites, instant): tombstone and suggestion retention cutoffs.

Totals: 38 instant + 14 bucket = 52 sites in 27 files (ProfileController's former 53rd site was fixed, not exempted).

Origin: orbit-ui-mobile REBUILD.md 6.1.2 gap 2 (the old csharp-tz hook did not cover Orbit.Infrastructure/Orbit.Api). Enforcement: src/Orbit.Analyzers/UtcNowUserFacingDateAnalyzer.cs, CI-only visibility (local in-box csc skips it with CS9057).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions