4.0 KiB
4.0 KiB
Web request audit
Initial request topology
App shell and auth
| Area | Request(s) | Current behavior | Waste / risk |
|---|---|---|---|
AppShell |
refreshAccessToken(), getUserProfile() |
Runs on authenticated shell mount. Profile is stored in UserSettingsContext. |
This should be the primary profile/settings source for child pages. |
LoginForm existing auth check |
refreshAccessToken(), getUserProfile() |
Valid existing session fetches profile to choose locale before redirect. | Acceptable, but could reuse stored auth language if persisted in future. |
LoginForm submit |
loginWithEmail(), getUserProfile() |
Login response lacks settings, so profile is fetched to choose locale. | Acceptable until backend returns language/settings in auth response. |
Duplicate profile/settings reads
| Page | Current request | Better behavior |
|---|---|---|
SettingsPage |
getUserProfile() + getPointsBalance() |
Reuse UserSettingsContext.userProfile; fetch only points. |
GeneralSettingsPage |
getUserProfile() |
Seed from UserSettingsContext.userProfile; fetch only if context missing. Update context after updateUserSettings(). |
ProfileDetailPage |
getUserProfile() |
Seed from UserSettingsContext.userProfile; fetch only if context missing. Update context after updateUserProfile() / avatar upload. |
ManualDivinationPage / AutoDivinationPage |
import getUserProfile but rely on context for profile; getUserProfile import appears unused |
Remove unused import and keep using context. |
Points and store reads
| Page | Current request | Better behavior |
|---|---|---|
Dashboard |
getPointsBalance(), getUnreadNotificationCount(), getAgentHistory() |
Points has TTL cache, but should dedupe in-flight. History can be shared with history list via short TTL cache. |
SettingsPage |
getPointsBalance() |
Keep cache, add in-flight dedupe and stale-while-revalidate option. |
StorePage |
getPointsBalance(), getPackages() |
Cache packages for a longer TTL because packages are stable configuration. Keep explicit invalidation after purchase/payment flows. |
ManualDivinationPage / AutoDivinationPage |
getPointsBalance() |
Reuse points cache/in-flight dedupe; consider prefetch when entering divination nav group. |
History and notifications
| Area | Current request | Better behavior |
|---|---|---|
Dashboard |
getAgentHistory() for latest four |
Add short TTL/in-flight cache for history summary; history list can reuse if still fresh. |
HistoryListPage |
getAgentHistory() full list |
Reuse cache populated by dashboard, then refresh in background. |
NotificationPage |
getNotifications(locale) |
Cache list briefly per locale. Invalidate/update locally after mark-read actions. |
| Dashboard unread badge | getUnreadNotificationCount() |
Cache briefly; invalidate/update after mark-read or mark-all-read. |
Priority plan
- Add a small typed cache helper in
web/src/lib/api.tsor adjacentweb/src/lib/api-cache.tsfor:- TTL cache
- in-flight promise dedupe
- explicit invalidation
- optional stale return with background refresh where UI can support it
- Apply first to profile/settings, points, packages, history summary/list, notification list/count.
- Refactor pages to use
UserSettingsContextfor profile reads. - Add prefetch hooks at AppShell/nav boundaries where it is cheap and safe.
- Browser-verify request count reductions on:
- login -> dashboard
- dashboard -> settings -> profile -> general
- dashboard -> manual/auto divination
- dashboard -> history
- dashboard -> store
Open implementation questions
- Whether to implement a minimal local cache helper or introduce a query library. Current repo has no query dependency, so default recommendation is a minimal helper first.
- Whether auth login response should eventually include profile language/settings to avoid immediate post-login profile fetch. This would be a backend contract change and is out of scope for the first frontend-only optimization pass.