Refactor/dashboard feature structure - #348
Merged
El-swaggerito merged 3 commits intoJul 29, 2026
Merged
Conversation
Integrates Axionvera#347 (shared MetricCard primitive) with the feature-folder refactor. The rewritten AnalyticsMetrics and GovernanceStats land on their new paths under features/, and baseline.test.ts keeps the structural regression suite instead of the placeholder assertion. Co-authored-by: Cursor <cursoragent@cursor.com>
The mock added in Axionvera#347 targeted the pre-refactor path. Navbar imports GlobalSearch from the @/features/search barrel, so the mock has to intercept that module. Co-authored-by: Cursor <cursoragent@cursor.com>
6 tasks
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.
Summary
Restructures the dashboard around explicit feature folders and a clear shared-component
boundary. Domain UI, shared primitives and the app shell previously sat intermixed under
src/components/, which made it hard to tell what was reusable and what belonged to asingle screen.
Every domain component now lives in
src/features/<domain>/components/and is consumedthrough an
index.tsbarrel, so a feature exposes a deliberate public API instead of deepfile paths.
src/components/keeps only genuinely shared code, split intoui/(presentational primitives),
layout/(the app shell, the one sanctioned composition rootthat may import features) and
errors/(error boundaries). All 51 moves were made withgit mvto preserve file history.The change is structural: no component logic, props or rendered output were altered.
Two duplications tracked in the cleanup checklist are resolved along the way:
/governanceroute —src/pages/governance/index.tsxrendered a mockgovernance stack that shadowed the real wallet-connected page at
src/pages/governance.tsx.The mock route and its supporting files (
GovernanceDashboard.tsx,governanceModel.ts,proposals.ts,types.ts) are removed; the on-chainProposaltype inutils/contractHelpersGovernanceis now the single governance domain type.AnalyticsDashboard— they were never the same thing. Thehooks-based one keeps its name and stays wired into the widget registry; the
service-layer one that takes an
addressand fetches a period report is renamedAnalyticsReportPanel. Both now live infeatures/analytics/components/.It also fixes a case collision between
docs/ARCHITECTURE.mdanddocs/architecture.md.Git tracked both, which is unrepresentable on case-insensitive filesystems and produced
phantom modifications on Windows checkouts; only the lowercase file remains.
Diff shape: 51 renames, 37 modifications, 11 additions, 10 deletions across 109 files.
Closes #331
Type of change
feat/— new feature or enhancementfix/— bug fixdocs/— documentationrefactor/— restructuring, no logic changechore/— maintenance or dependenciesQuality gates
See CONTRIBUTING.md.
npm run lintpassesnpm run typecheckpasses — 4 pre-existing errors remain, all intests/hooks/useVault.test.ts, untouched by this PR (see notes)npm testpasses — 100 of 101 suites pass (655 tests); the sametests/hooks/useVault.test.tsfails for the same pre-existing reasonCleanup checklist
Confirm against
docs/dashboard-cleanup-checklist.md.src/folder; no near-synonym folder added. Thelogic/UI split is respected:
src/<domain>/keeps domain logic andfeatures/<domain>/components/holds that domain's UI.home (
features/for domain UI,components/for shared) and is exported throughits
index.tsbarrel.fetch()added or moved; the API layer is untouched by this PR.existing on-chain
Proposaltype instead of the parallel mock type that was removed.tests/baseline.test.ts. One suite was deletedbecause its subject no longer exists, not to make CI pass (see notes).
docs/structure.mddocuments the layout rules; the READMEstructure table, component table and route table are updated, as are
docs/ANALYTICS.md,docs/RBAC.mdand the cleanup checklist.Notes for reviewers
A deleted test suite, called out explicitly.
tests/components/GovernanceDashboard.test.tsxis removed because the component it exercised (the mock
GovernanceDashboard) is removedwith the duplicate route. The suite only asserted against hardcoded mock proposals, so
there is no behaviour left to cover. No test was deleted or skipped to get CI green.
tests/baseline.test.tsnow contains 20 real assertions. It previously held aplaceholder
expect(true).toBe(true)so the empty suite would not fail. It now encodes therules in
docs/structure.mdas fitness functions: no loose files directly undersrc/components/, shared components may not import fromfeatures/, features are consumedthrough barrels, and no two page files resolve to the same route. These fail if the layout
regresses.
Merged with #347 rather than rebased. #347 landed while this work was in progress and
rewrote
AnalyticsMetrics.tsxandGovernanceStats.tsx, both of which this PR moves. Git'srename detection applied those rewrites onto the new paths, and the two genuine conflicts
were resolved in favour of the newer code:
GovernanceStatskeeps the sharedMetricCardprimitive from #347. A rebase was deliberately avoided because replaying onto that tree
requires checking out both casings of the architecture doc at once.
One real integration fix. #347 added a
jest.mocktargeting@/features/search/GlobalSearch, a path this PR moves. The mock now intercepts the@/features/searchbarrel, which is whatNavbaractually imports.Suggested follow-up, out of scope here.
tests/hooks/useVault.test.tscallsuseVault({ walletAddress })while the hook takes no arguments, having moved to acontext-based API. That accounts for all 4 remaining type errors and all 4 remaining test
failures. Neither this PR nor #347 touches the hook, its context or the test, and it is
worth its own issue rather than an unrelated drive-by fix here.
I remain open to any corrections or feedback you may have.