61 lines
4.0 KiB
Markdown
61 lines
4.0 KiB
Markdown
|
|
# 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
|
||
|
|
|
||
|
|
1. Add a small typed cache helper in `web/src/lib/api.ts` or adjacent `web/src/lib/api-cache.ts` for:
|
||
|
|
- TTL cache
|
||
|
|
- in-flight promise dedupe
|
||
|
|
- explicit invalidation
|
||
|
|
- optional stale return with background refresh where UI can support it
|
||
|
|
2. Apply first to profile/settings, points, packages, history summary/list, notification list/count.
|
||
|
|
3. Refactor pages to use `UserSettingsContext` for profile reads.
|
||
|
|
4. Add prefetch hooks at AppShell/nav boundaries where it is cheap and safe.
|
||
|
|
5. 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.
|