Conversation
… hydration and explicit sync state handling across UI components, make profile sync non-blocking chore: bump app ver to 4.4.6
refactor: optimize leave data parsing, improve image upload reliability. feat: implement double-back-to-exit functionality on the dashboard using PopScope and improve navigation logic
…, and lifecycle optimizations This patch addresses critical deadlock issues, secures storage data persistence, enforces proper Riverpod contracts, and introduces several performance optimizations across features. Critical Fixes: - fix(secure-storage): implement self-healing mechanism to only purge on unrecoverable Keystore/Keychain corruption, rethrowing transient errors. - fix(provider): eliminate provider deadlocks by replacing the `Completer().future` anti-pattern with `Future.wait` on upstream dependencies. - fix(riverpod): correct lifecycle contract violations by migrating `ref.watch` from async contexts to `ref.read` and ensuring watches execute at the start of build methods. - fix(notification): add an in-flight concurrency guard to `toggleRead` to eliminate optimistic update race conditions. - fix(splash): isolate startup cache fields to `StartupFlowService` instance and invalidate on logout to prevent cross-session leakage. High Priority Fixes & Optimizations: - refactor(security): dry up duplicate transient error keyword matches into a static helper. - perf(dashboard): prevent redundant attendance fetches during background revalidation by reusing cached official reports. - fix(dashboard): shield disk cache from deletion when refresh operations fail due to transient connectivity errors. - chore(tracking): remove dead code, unused fields, and redundant blocks associated with `forceSync`. - fix(notification): implement `isFetchingNextPage` pagination guards to prevent redundant API queries on scroll events. - fix(leave): remove redundant loading state updates and expose fully awaitable futures on refresh. - fix(ezygo): switch from unstable `String.hashCode` to `Uri.encodeFull` for secure storage cache keys to prevent key collisions. - fix(score): validate cache payloads are explicitly instances of `List` before mutation to block malformed/error map payloads. Medium Priority Optimizations: - refactor(navigation): extract build-context closures into private instance methods to reduce allocation and GC pressure. - perf(security): cache the `Dio` instance in a private field to bypass container reads on every getter access. - refactor(dashboard): isolate IIFE metadata evaluations into a dedicated private mapper function. - perf(notification): bypass database queries on auth state updates if the underlying user ID has not changed. - perf(splash): conditionally restrict authenticated provider prewarming to logged-in sessions to prevent initialization errors.
- centralize notification invalidation in runUnifiedPullToRefresh - suppress forced syncs shortly after the startup sync - reuse the tracking official attendance report during dashboard refresh to avoid duplicate attendance fetches - make EzyGo auth/token handling fail fast on missing credentials - remove the redundant tracking course-code wrapper - make dashboard cache TTL explicit and parallelize cached-key cleanup - improve accessibility and scroll behavior in notifications - fix leave card clipping and theme usage for success colors - smooth splash shimmer animation - normalize error styling to theme-aware colors where applicable
- remove raw token exposure from save-token responses and align origin validation with shared host resolution - scope localStorage cleanup to GhostClass keys and keep passwords untrimmed during login - validate stored user settings before use in all code paths - make circuit-breaker status reflect Redis-backed state, not stale local memory - replace blank protected-layout gating with a visible loading state - tighten dashboard and scores loading, navigation, and accessibility behavior - invalidate class-dependent caches after profile class_id updates - clean up sync lifecycle naming and reduce redundant or high-cost requests - fix smaller UX, accessibility, and config inconsistencies surfaced by the audit
…t mocks, and add Supabase dev proxy configuration fix: handle null leave IDs and update leave application status logic with improved testing coverage fix: correct max marks in scores records refactor: implement robust academic term shifting with automated query invalidation and synchronized data fetching in DashboardClient
…e codebase Address multiple vulnerabilities, reliability bugs, and UX inconsistencies: - EzygoBatchFetcher: Convert static fields to instance fields to prevent cross-session leaks. Hash Ezygo bearer tokens using SHA-256 for cache keys. Clamp active request counts to guard against negative values from delayed request completions after queue clears. - Notifications & Provider: Implement robust state merge/revert logic in `markAllAsRead` to prevent TOCTOU races during database failures. Change `createdAt` from a raw string to `DateTime` to ensure timezone-accurate comparisons and relative formatting. - User Model: Migrate `UserProfile.hashCode` and `UserSettings.hashCode` from XOR-based hash codes to `Object.hash()` to prevent key collisions on nullable fields. - Splash Screen: Use safe type checks (`is _StartupSnapshot`) in `_canUseStartupCache` to avoid cast panics. Remove redundant prewarm calls. Combine breathing scale and shimmer animations into a single synced controller loop to reduce memory overhead. - Security & Keys: Convert RCEK map to instance fields in `JweInterceptor` to isolate Content Encryption Keys. Overwrite key entropy buffers in `EncryptedValue.clearEntropy()` using cryptographically secure random bytes rather than deterministic zeros. - Push Notifications: Cancel and clear deferred auth subscriptions and timers on initialization. Defer in-app toast display using `SchedulerBinding.instance.addPostFrameCallback` to avoid transition context races. Deduplicate FCM HTTP registration POST logic into a private helper. - Exam Scores: Wrap individual detail fetches in try-catch blocks to prevent a single exam failure from blocking the whole scores view. Verify auth state once in `build()` and pass the watched user directly to `_initialFetch()`. - Dashboard & API: Compare academic state using explicit string fields instead of reference equality. Move inline Supabase queries for class courses and instructors out of `DashboardNotifier` and into the centralized `ApiService` facade. - Login Screen: Remove redundant nested try-catch wrappers around analytics calls. Add a client-side 30-second cooldown timer after 3 consecutive failed login attempts. Replace manual check modal dialogs with standard TextFormField validators showing inline feedback. - Refresh Coordinator: Remove `rethrow` from the `syncCron` catch block so cron sync failures do not block the foreground dashboard/marks updates. fix(web): apply audit fixes for sync flow, request dedupe, and dashboard quality - make cron sync fail-open on protected pages so UI no longer hard-blocks on transient sync failures - keep profile sync as early gate for dashboard data loading to preserve profile-first behavior - add dashboard background-sync success toast only when sync reports actual changes - add cached-data status messaging when background sync fails on dashboard, tracking, and notifications - fix courses hook enabled default to true unless explicitly disabled - remove redundant post-submit refetch burst in AddRecordTrigger by relying on query invalidation - prevent duplicate scores fetches by hydrating per-exam query caches from batch exam details - remove duplicate dashboard full-screen loading overlay render - refactor dashboard helper logic for readability and maintainability; keep page orchestrator behavior intact - address dashboard cognitive-complexity lint warning with targeted decomposition and explicit component-level rationale feat(sync): optimize background sync, settings resolution, and load state - Updated GET `/api/profile` to check for academic conflicts (semester/year changes). - Backgrounds the profile sync asynchronously using `after()` if there is no conflict. - Bypasses backgrounding optimization and forces a synchronous blocking sync if an academic conflict exists or `force=true` is sent (ensuring single-refresh period healing). - Updated `getProfileBundle` to fetch and return the correct class period settings. - Updated `useSyncOnMount` to defer cron sync until the page is fully loaded and the CPU is idle (`requestIdleCallback`), adding proper handle cleanups on unmount. - Refactored `resolveSettingFromProfileQuery` to safely subscribe/resolve from the pending synced profile query or existing cache instead of immediately firing duplicate API requests on load. - Managed dashboard loading state via `hasSyncedAndLoaded` to show a clean loader in the body while queries refetch in the background, keeping the Navbar immediately visible. - Added test cases in `route.test.ts` to cover backgrounding logic, conflict blocking, and the forced synchronous path. - Added test cases in `use-sync-on-mount.test.tsx` to verify deferred loading execution.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR bumps GhostClass to v4.4.6 and ships a set of web + mobile reliability/performance improvements around sync behavior, course-code normalization, cookie security, and test coverage hardening.
Changes:
- Centralize course-code normalization (
normalizeCourseCode) and apply it across web hooks/components and server sync/validation paths. - Make initial EzyGo sync more resilient/non-blocking (web
useSyncOnMount+ profile API/backgrounding tweaks), plus circuit-breaker + logging changes. - Mobile: tighten caching/self-healing, improve refresh orchestration, add/extend widget + provider tests, and ship multiple UX refinements (calendar, scores, login).
Reviewed changes
Copilot reviewed 120 out of 123 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| workers/package.json | Bumps wrangler dependency. |
| workers/package-lock.json | Lockfile updates for wrangler/miniflare/workerd versions. |
| vitest.setup.ts | Updates useSyncOnMount mock shape (syncSettled/syncFailed). |
| src/types/react-intrinsic.d.ts | Adds JSX typing support for the inert attribute. |
| src/providers/user-settings.tsx | Validates prefetched disabled_courses via schema on load. |
| src/lib/validation/text.ts | Uses normalizeCourseCode for course-code validation transform. |
| src/lib/validate-env.ts | Rejects AUTH_LOCK_TTL=0 explicitly to avoid silent fallback mismatch. |
| src/lib/utils.ts | Adds normalizeCourseCode alias around formatCourseCode. |
| src/lib/user/sync.ts | Uses normalizeCourseCode when building course maps/catalog. |
| src/lib/user/profile-bundle.ts | Extends class select to include sem/year. |
| src/lib/security/csrf.ts | Uses shared isCookieSecure() for CSRF cookie secure flag. |
| src/lib/security/cookie-utils.ts | Introduces isCookieSecure() helper. |
| src/lib/security/auth-cookie.ts | Uses isCookieSecure() for auth cookie secure flag. |
| src/lib/redis.ts | Adds an in-memory Redis mock for Vitest runs to avoid network calls. |
| src/lib/logger.ts | Adds structured JSON logging in production mode. |
| src/lib/circuit-breaker.ts | Optimizes success path + makes getStatus() authoritative/async. |
| src/lib/tests/redis.test.ts | Adjusts env stubbing to cover new Redis test-path behavior. |
| src/lib/tests/circuit-breaker.test.ts | Updates tests for async getStatus(). |
| src/hooks/users/settings.ts | Resolves semester/year from cached profile when possible to reduce extra API calls. |
| src/hooks/users/profile.ts | Separates forced profile sync via distinct query key + cache handling tweaks. |
| src/hooks/users/tests/profile.test.tsx | Updates expectations for sync/force query params behavior. |
| src/hooks/use-sync-on-mount.ts | Refactors sync state to be globalThis-backed, adds failure/settled signals, defers sync scheduling. |
| src/hooks/use-dashboard-stats.ts | Refactors course-stat init + uses normalizeCourseCode. |
| src/hooks/courses/useCourseLookup.ts | Centralizes normalization via normalizeCourseCode. |
| src/hooks/courses/exams.ts | Increases staleTime for exam answers query. |
| src/hooks/courses/courses.ts | Defaults enabled to true unless explicitly disabled. |
| src/hooks/courses/attendance.ts | Adds optional semester/year params + uses normalized codes + controllable enabled. |
| src/hooks/tests/use-sync-on-mount.test.tsx | Updates tests for new sync return shape + adds load-event deferral test. |
| src/components/user/login-form.tsx | Removes redundant submit-time password validation + avoids double SR announcements; stops trimming password on submit. |
| src/components/attendance/course-card.tsx | Uses normalizeCourseCode for query keys. |
| src/components/attendance/attendance-chart.tsx | Uses normalizeCourseCode for stable course keys. |
| src/components/attendance/attendance-calendar.tsx | Normalizes codes + adjusts status aggregation + updates “today” ring styling. |
| src/components/attendance/AddRecordTrigger.tsx | Removes explicit refetch calls and relies on invalidation/onSuccess. |
| src/components/attendance/AddAttendanceDialog.tsx | Normalizes codes + tweaks button classes and selection UI behavior. |
| src/components/attendance/tests/attendance-chart.test.tsx | Mocks normalizeCourseCode for chart tests. |
| src/app/api/profile/route.ts | Adds sem/year to class fetch + backgrounds sync when no academic conflict. |
| src/app/api/profile/tests/route.test.ts | Adds branch coverage for new backgrounded vs blocking sync behavior. |
| src/app/api/logout/route.ts | Uses isCookieSecure() when clearing cookies. |
| src/app/api/health/ezygo/route.ts | Awaits async circuit-breaker status. |
| src/app/api/health/ezygo/tests/route.test.ts | Updates mocks to mockResolvedValue for async status. |
| src/app/api/auth/save-token/route.ts | Hardens origin validation via allowed-host logic + adds user metadata + removes ezygo_token from response. |
| src/app/api/auth/save-token/tests/route.test.ts | Adds proxy-host origin test + asserts ezygo_token not returned; resets allowed-host cache. |
| src/app/actions/user.ts | Uses isCookieSecure() for terms cookies. |
| src/app/actions/instructors.ts | Normalizes course codes on upsert. |
| src/app/actions/courses.ts | Normalizes course codes on insert. |
| src/app/(protected)/tracking/TrackingClient.tsx | Stops blocking UI on sync completion; adds “cached data” warning banner. |
| src/app/(protected)/tracking/tests/TrackingClient.test.tsx | Updates sync hook mocks to new return shape. |
| src/app/(protected)/tracking/tests/TrackingClient.coverage.test.tsx | Updates sync hook mocks to new return shape. |
| src/app/(protected)/tracking/tests/simple.test.tsx | Updates sync hook mocks to new return shape. |
| src/app/(protected)/notifications/NotificationsClient.tsx | Stops blocking UI on sync completion; adds “cached data” indicator; typing tweaks. |
| src/app/(protected)/notifications/tests/NotificationsClient.test.tsx | Updates sync hook mocks to new return shape. |
| src/app/(protected)/notifications/tests/NotificationsClient.minimal.test.tsx | Updates sync hook mocks to new return shape. |
| src/app/(protected)/leave-applications/LeaveClient.tsx | Normalizes EzyGo action types + ignores unacted placeholders for status. |
| src/app/(protected)/leave-applications/tests/LeaveClient.test.tsx | Adds tests for past-tense action types + placeholder ignore behavior. |
| src/app/(protected)/layout.tsx | Simplifies inert usage and shows loading component while CSRF initializes. |
| src/app/(protected)/dashboard/components/CourseGrid.tsx | Improves typing for course grid entries + normalizes codes + avoids any. |
| src/app/(protected)/dashboard/components/tests/CourseGrid.test.tsx | Updates mock courses to include names for new typing. |
| src/app/(protected)/dashboard/tests/DashboardClient.test.tsx | Updates sync mocks and adds test for attendance-loading UI state. |
| src/app/(protected)/dashboard/tests/DashboardClient.coverage.test.tsx | Updates query-client mock surface + sync mocks. |
| src/app/(protected)/dashboard/tests/DashboardClient.basic.test.tsx | Updates query-client mock surface + sync mocks. |
| public/openapi/openapi.yaml | Bumps OpenAPI version to 4.4.6. |
| public/manifest.webmanifest | Normalizes description punctuation. |
| package.json | Bumps app version to 4.4.6 + updates googleapis. |
| mobile/test/widgets/header_section_test.dart | Adds widget tests for academic-period navigation limit behavior. |
| mobile/test/services/stealth_headers_service_test.dart | Updates secure-storage mock to include new method. |
| mobile/test/services/security_service_coverage_test.dart | Adds coverage for cache-clearing on cert/handshake failures + transient fallback. |
| mobile/test/services/secure_storage_service_test.dart | Adds tests for transient vs unrecoverable secure-storage self-healing logic. |
| mobile/test/services/auth_profile_settings_coverage_test.dart | Updates secure-storage mock to include new method. |
| mobile/test/providers/notification_provider_test.dart | Adds tests for TOCTOU-safe revert/merge behavior on mark-all-read failures. |
| mobile/test/providers/auth_provider_analytics_test.dart | Updates expected cache-clear call count + stubs new storage method. |
| mobile/test/navigation_shell_interaction_test.dart | Adds back-button intercept test for calendar tab. |
| mobile/test/models/score_test.dart | Adds tests for maximum mark precedence/fallback behavior. |
| mobile/test/logic/ezygo_batch_fetcher_test.dart | Adds test ensuring fetcher instance state isolation. |
| mobile/pubspec.yaml | Bumps mobile version to 4.4.6+1. |
| mobile/lib/widgets/security_lockdown_listener.dart | Always clears storage and offers a close-app action on security failure. |
| mobile/lib/widgets/dashboard/header_section.dart | Adds “max academic period” guard + toast messaging. |
| mobile/lib/widgets/common/pill.dart | Changes tap handling for disabled pills (see review comment). |
| mobile/lib/widgets/calendar/calendar_widgets.dart | Improves day-status resolution with disabled/override logic + “Today” legend and purple branding. |
| mobile/lib/widgets/calendar/calendar_session_card.dart | Moves disabled indicator to a dedicated tag under status. |
| mobile/lib/widgets/aesthetic_refresh_indicator.dart | Prevents accidental refresh on overscroll + tweaks thresholds. |
| mobile/lib/widgets/add_attendance_dialog.dart | Uses theme error color + improves selected-row check UI spacing. |
| mobile/lib/widgets/about/attestation_section.dart | Adds cached attestation state and “Verify Again” action with timestamp. |
| mobile/lib/services/startup_flow_service.dart | Adds startup cache/in-flight tracking fields. |
| mobile/lib/services/security_service.dart | Caches Dio instance + refines transient-vs-nontransient error classification. |
| mobile/lib/services/secure_storage.dart | Distinguishes transient vs unrecoverable errors; adds cached-key purge method. |
| mobile/lib/services/refresh_coordinator.dart | Adds notification invalidation and avoids rethrowing cron sync failures. |
| mobile/lib/services/push_notification_service.dart | Defers toast display to post-frame; adds deferred-auth subscription cleanup; refactors token registration. |
| mobile/lib/services/logger.dart | Ensures safeUnawait handler returns a value to satisfy catchError. |
| mobile/lib/services/jwe_interceptor.dart | Makes RCEK tracking instance-scoped instead of static. |
| mobile/lib/services/ezygo_service.dart | Requires EzyGo token for calls; introduces fetcher provider tied to auth boundaries. |
| mobile/lib/services/auth_service.dart | Normalizes token type; re-injects ezygo_token into bridge response for client needs. |
| mobile/lib/services/api_service.dart | Adds forced-sync grace period + adds Supabase fetch helpers for class courses/instructors. |
| mobile/lib/screens/tracking_screen.dart | Blocks on global sync state; integrates unified refresh + notification invalidation; copy tweaks. |
| mobile/lib/screens/scores_screen.dart | Blocks on global sync state; integrates unified refresh; uses shared error view; improves mark formatting. |
| mobile/lib/screens/profile_screen.dart | Prevents duplicate image picker invocations + adds picker error logging. |
| mobile/lib/screens/profile_dump_screen.dart | Uses firstOrNull and logs warnings instead of throwing on institution mismatch. |
| mobile/lib/screens/login_screen.dart | Adds cooldown after consecutive failures + moves validation into form validators + simplifies analytics logging. |
| mobile/lib/screens/accept_terms_screen.dart | Adds semantics for acceptance toggle for accessibility. |
| mobile/lib/providers/tracking_provider.dart | Removes sync blocker futures; waits on dependency futures; simplifies refresh behavior. |
| mobile/lib/providers/score_provider.dart | Removes sync blocker futures; improves per-exam failure tolerance; refines filtering stats. |
| mobile/lib/providers/leave_provider.dart | Removes sync blocker futures; hardens session parsing; simplifies refresh. |
| mobile/lib/providers/dashboard_provider.dart | Removes sync blocker futures; integrates new class fetch helpers; refactors course meta calc; safer revalidate and cache clearing semantics. |
| mobile/lib/providers/auth_provider.dart | Makes startup hydration non-blocking; invalidates startup flow on logout; purges caches on academic/class change. |
| mobile/lib/models/user.dart | Uses Object.hash for stable hashCode implementations. |
| mobile/lib/models/score.dart | Prioritizes settings max mark when non-zero; falls back correctly. |
| mobile/lib/models/leave.dart | Adds leaveId on leave sessions for robust mapping. |
| mobile/lib/logic/ezygo_batch_fetcher.dart | Makes caches/in-flight per instance; hashes token in cache keys; improves slot release and clearAll options. |
| mobile/lib/logic/error_handler.dart | Adds iOS/Android-specific exit handling. |
| mobile/lib/logic/encrypted_value.dart | Overwrites entropy buffers with random bytes on logout rather than zeros. |
| mobile/lib/logic/attendance_utils.dart | Refactors date parsing helper + tightens course code standardization. |
| mobile/lib/config/app_config.dart | Adds dev supabase origin override + bumps default app version + asserts on unencoded config in prod. |
| mobile/android/app/src/main/kotlin/com/devakesu/apps/ghostclass/MainActivity.kt | Implements tapjacking/obscured-window detection for Android. |
| mobile/android/app/src/main/AndroidManifest.xml | Disables back-invoked callback behavior at app level. |
| .example.env | Bumps versions + adds NEXT_PUBLIC_SUPABASE_DEV_PROXY_URL + bumps MIN_APP_VERSION. |
| .devcontainer/Dockerfile | Adjusts pinned-artifacts copy path. |
Files not reviewed (1)
- workers/package-lock.json: Language not supported
fix(circuit-breaker): refine local failure check logic fix(pill): disable tap action for disabled selectable pill
devakesu-admin
approved these changes
Jun 1, 2026
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Pull Request
Description
refactor: improve startup performance by enabling parallel background hydration and explicit sync state handling across UI components, make profile sync non-blocking
chore: bump app ver to 4.4.6
refactor: optimize pull-to-refresh logic
refactor: optimize leave data parsing, improve image upload reliability.
feat: implement double-back-to-exit functionality on the dashboard using PopScope and improve navigation logic
fix/perf(mobile): core architecture hardening, state management fixes, and lifecycle optimizations
This patch addresses critical deadlock issues, secures storage data persistence, enforces proper Riverpod contracts, and introduces several performance optimizations across features.
Critical Fixes:
Completer().futureanti-pattern withFuture.waiton upstream dependencies.ref.watchfrom async contexts toref.readand ensuring watches execute at the start of build methods.toggleReadto eliminate optimistic update race conditions.StartupFlowServiceinstance and invalidate on logout to prevent cross-session leakage.High Priority Fixes & Optimizations:
forceSync.isFetchingNextPagepagination guards to prevent redundant API queries on scroll events.String.hashCodetoUri.encodeFullfor secure storage cache keys to prevent key collisions.Listbefore mutation to block malformed/error map payloads.Medium Priority Optimizations:
Dioinstance in a private field to bypass container reads on every getter access.fix(mobile): reduce refresh redundancy and align UI behavior
fix(web): harden auth, settings, and dashboard flows
refactor: update attendance hooks and mobile calendar UI, enhance test mocks, and add Supabase dev proxy configuration
fix: handle null leave IDs and update leave application status logic with improved testing coverage
fix: correct max marks in scores records
refactor: implement robust academic term shifting with automated query invalidation and synchronized data fetching in DashboardClient
refactor(flutter): improve security, reliability, and UX across mobile codebase
Address multiple vulnerabilities, reliability bugs, and UX inconsistencies:
markAllAsReadto prevent TOCTOU races during database failures. ChangecreatedAtfrom a raw string toDateTimeto ensure timezone-accurate comparisons and relative formatting.UserProfile.hashCodeandUserSettings.hashCodefrom XOR-based hash codes toObject.hash()to prevent key collisions on nullable fields.is _StartupSnapshot) in_canUseStartupCacheto avoid cast panics. Remove redundant prewarm calls. Combine breathing scale and shimmer animations into a single synced controller loop to reduce memory overhead.JweInterceptorto isolate Content Encryption Keys. Overwrite key entropy buffers inEncryptedValue.clearEntropy()using cryptographically secure random bytes rather than deterministic zeros.SchedulerBinding.instance.addPostFrameCallbackto avoid transition context races. Deduplicate FCM HTTP registration POST logic into a private helper.build()and pass the watched user directly to_initialFetch().DashboardNotifierand into the centralizedApiServicefacade.rethrowfrom thesyncCroncatch block so cron sync failures do not block the foreground dashboard/marks updates.fix(web): apply audit fixes for sync flow, request dedupe, and dashboard quality
feat(sync): optimize background sync, settings resolution, and load state
/api/profileto check for academic conflicts (semester/year changes).after()if there is no conflict.force=trueis sent (ensuring single-refresh period healing).getProfileBundleto fetch and return the correct class period settings.useSyncOnMountto defer cron sync until the page is fully loaded and the CPU is idle (requestIdleCallback), adding proper handle cleanups on unmount.resolveSettingFromProfileQueryto safely subscribe/resolve from the pending synced profile query or existing cache instead of immediately firing duplicate API requests on load.hasSyncedAndLoadedto show a clean loader in the body while queries refetch in the background, keeping the Navbar immediately visible.route.test.tsto cover backgrounding logic, conflict blocking, and the forced synchronous path.use-sync-on-mount.test.tsxto verify deferred loading execution.fix(logger): improve JSON serialization for logging payloads
fix(circuit-breaker): refine local failure check logic
fix(pill): disable tap action for disabled selectable pill
Type of Change