2 Commits

Author SHA1 Message Date
isra el
9c0826016a refactor: group dashboard components into feature folders
The (components) directory held 28 loose files alongside six feature
folders, so the convention existed but was only half applied. Every new
feature added to the pile rather than to a place.

Grouped into account, billing, devices, api-keys, alerts, search and
community. Only nav-items and overview stay at the root, since both
compose across features rather than belonging to one.

Also merged the duplicate webhooks component trees. Components lived in
both dashboard/(components)/webhooks and dashboard/webhooks/(components),
and the second tree was reached by a cross-tree import from
webhooks-history. All three of its files are delivery-history specific
and had no other consumer, so they moved into webhooks-history and that
tree is gone. webhook-table also became deliveries-table, matching what
it renders.

Moves only, no logic changes: git records all 25 as renames, and no test
needed editing, which is the check that behaviour did not move with them.

Two files turned out to be dead code and are deliberately left in place
rather than deleted: black-friday-modal (seasonal, clearly parked) and
community-alert. Nothing imports either.

Verified: typecheck clean, build clean, 0 lint errors (21 warnings,
unchanged), 155 unit tests, 78 e2e.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 09:08:17 +03:00
isra el
c1942a4ba3 fix: repair two cache invalidations that silently matched nothing
Both bugs were hand-written query keys. lib/api/query-keys.ts exists to
prevent exactly this and neither site used it.

1. /auth/who-am-i was cached under two keys. Four call sites used
   ['whoAmI'] and seven used ['currentUser'], including the typed
   useCurrentUser hook. So the endpoint was fetched twice on any page
   using both, and invalidating one never invalidated the other:
   edit-profile-form refreshed ['currentUser'] and left the email
   verification banner reading stale data under ['whoAmI'], while
   use-onboarding had the mirror-image bug.

   verify-email/page.tsx additionally cached the whole axios response
   where the others cached the unwrapped user, so unifying the key meant
   normalising that shape too. One key demands one shape.

2. generate-api-key invalidated ['apiKeys', 'stats'], which no query
   uses. react-query matches by prefix, so it matched neither the key
   list (['apiKeys', status]) nor the dashboard stats (['stats']).
   Generating an API key refreshed nothing at all. It is now three
   invalidations against queryKeys, using a new apiKeysAll prefix so
   every status filter refreshes rather than just 'active'.

Also added accountDeletionRequestedAt to the User type. It is a real
field on the user schema and the deletion banner already reads it; only
the type did not know about it.

Both bugs are invisible on inspection, which is how they shipped, so the
regression tests were each confirmed to fail against the pre-change code
before being trusted.

Verified: build clean, 0 lint errors (21 warnings, unchanged), 155 unit
tests (from 153), 78 e2e.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 04:02:30 +03:00