docs(ui): define UI folder structure + file naming, wire into agent config - #31812
Conversation
…entions The UI tree has grown to 5,305 files with 77 top-level component folders (667 in common/ alone) and 526 flat utils, with no documented grouping scheme. File naming has forked: 830 bare .tsx vs 456 .component.tsx, 411 .interface.ts vs 4 .types.ts. Document a layer-first structure that keeps components/, pages/, rest/, utils/, hooks/ as top-level layers and adds domain/feature grouping inside each, so `governance/glossary` is one coordinate across layers. Keeping layers at the top preserves the custom ESLint rules in eslint-rules/, which resolve a file's layer from the first path segment after src/. Also correct three stale claims in the handbook: - src/routes/ and src/store/ do not exist; routers live in components/AppRouter/ and Zustand stores in src/hooks/ - index.ts barrels were recommended in two places despite the no-internal-barrel-imports rule reporting them - the assets/icons/index.ts icon barrel is the exact case that rule exists to prevent Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
| > them yet — `tsconfig.json` has no `baseUrl`, and `vite.config.ts` aliases only `@`. Before using | ||
| > absolute imports in application code, add `"baseUrl": "./src"` to `tsconfig.json` and matching | ||
| > entries to the Vite `resolve.alias` block. Until then, application code must keep using relative | ||
| > paths; only tests can use the absolute form. |
There was a problem hiding this comment.
💡 Quality: "vite.config.ts aliases only @" is inaccurate
The handbook states "vite.config.ts aliases only @", but vite.config.ts:218-238 defines several resolve.alias entries (lodash, process, Quill, @, ~antd, antd, @deuex-solutions/react-tour, luxon). The intended point — that @ is the only alias mapping a source path (src) and bare-layer imports won't resolve in Vite — still holds, but the literal claim is wrong. Consider rewording to "@ is the only alias mapping into src" to keep the doc precise.
Reword to reflect that Vite has other package aliases but only @ maps into src.:
> `tsconfig.json` has no `baseUrl`, and `@` is the only Vite `resolve.alias` entry that maps
> into `src` (`@` → `src`); no alias resolves bare layer paths like `components/…`.
Was this helpful? React with 👍 / 👎
✅ Playwright Results — workflow succeededValidated commit ✅ 553 passed · ❌ 0 failed · 🟡 0 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky PerformanceBlocking targets: ✅ met · Optimization targets: 🟡 in progress Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting. 🕒 Full workflow signal wall (to summary) 50m 44s ⏱️ Max setup 4m 18s · max shard execution 16m 15s · max shard-job elapsed before upload 19m 31s · reporting 4s 🌐 215.50 requests/attempt · 2.83 app boots/UI scenario · 11.28% common-shard skew Optimization targets still in progress:
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
DEVELOPER_HANDBOOK.md was referenced only from the UI README, so no
agent-facing config pointed at it. Worse, five AI-facing docs mandated
the legacy naming (`ComponentName.component.tsx` /
`ComponentName.interface.ts`) that the handbook supersedes for new code,
so an agent following the rules and an agent following the handbook
would produce different filenames.
Point every agent entry point at the handbook and reconcile the naming
guidance:
- .claude/rules/frontend-react.md — auto-loads on UI *.{ts,tsx}; now
carries the domain/feature placement rule and the new naming table
- CLAUDE.md — added to "Repo coding conventions" (AGENTS.md symlinks it)
- docs/index.md — indexed in the UI reference table
- skills/openmetadata-workflow/SKILL.md — the UI component row now reads
the handbook first
- skills/agents/frontend-reviewer.md — reviews placement and naming
- .github/copilot-instructions.md, openmetadata-ui/UI_PR_REVIEW_GUIDELINES.md
Every one states that legacy `.component.tsx`/`.interface.ts` files must
NOT be renamed, so reviewers don't generate rename churn across the 5,305
existing files.
check_harness.py reports the same 5 pre-existing warnings, no new ones;
frontend-react.md is 94 lines, under the 100-line rule budget.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Code Review 👍 Approved with suggestions 0 resolved / 1 findingsDefines a domain/feature folder structure and unified file naming conventions in the UI developer handbook to prevent tree divergence. Consider addressing the minor Vite configuration alias description in the text. 💡 Quality: "vite.config.ts aliases only
|
| Compact |
|
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source
🚦 Removed from the merge queue —
|
Describe your changes:
I rewrote
openmetadata-ui/src/main/resources/ui/DEVELOPER_HANDBOOK.mdto define adomain/feature folder structure and a single file-naming scheme, because the UI tree has grown
to 5,305 files with 77 top-level component folders (667 in
common/alone) and 526 flatutils/entries, with no documented grouping rule — and naming has forked in the process (830bare
.tsxagainst 456.component.tsx, 411.interface.tsagainst 4.types.ts). I thenwired the handbook into every agent-facing entry point, since it was previously referenced only
from the UI
README.mdwhile five AI-facing docs still mandated the legacy naming it supersedes.No source files change — this is documentation and agent configuration only.
Type of change:
High-level design:
Layer-first, domain-grouped.
components/,pages/,rest/,utils/,hooks/,constants/andinterface/stay as top-level layers; domain and feature grouping goes insideeach one, so
governance/glossaryis a single coordinate that resolves in every layer:Five domains (
discovery,governance,observability,insights,platform), withcross-cutting features (
lineage,data-contract,entity,activity-feed) at the domain levelunder one stated test: if two domains would both claim a feature, it has no domain. That rule
exists so adding a folder doesn't reopen a taxonomy argument on every PR.
Alternative rejected — feature-first (
src/domains/<domain>/<feature>/owning its owncomponents, pages and api). It colocates a feature better, but
eslint-rules/openmetadata-imports.mjshardcodes
SOURCE_LAYERS(lines 18-29) andgetLayer()(lines 71-83) resolves a file's layer fromthe first path segment after
src/. A new top-level root falls outside that set, silently no-oppingall ten custom import rules —
no-cross-page-imports,no-rest-ui-imports,no-hook-ui-imports,no-impure-pure-utils,no-internal-barrel-importsand the rest — for every new feature. Keepinglayers at the top keeps those rules live. The cost, stated in the handbook: a feature spans several trees.
Agent config (2nd commit). The handbook is useless to an agent that never reads it, and five
docs actively contradicted it. Each entry point now points at the handbook and carries the same
naming table:
.claude/rules/frontend-react.md(auto-loads on UI*.{ts,tsx}),CLAUDE.md(always loaded;
AGENTS.mdsymlinks it),docs/index.md,skills/openmetadata-workflow/SKILL.md,skills/agents/frontend-reviewer.md,.github/copilot-instructions.mdandopenmetadata-ui/UI_PR_REVIEW_GUIDELINES.md. Every one states that legacy.component.tsx/.interface.tsfiles must not be renamed, so reviewers don't generate renamechurn across 5,305 existing files.
Three corrections to existing guidance, verified against the tree:
src/routes/andsrc/store/were documented but do not exist. Routers live incomponents/AppRouter/(GlossaryRouter,DomainRouter,SettingsRouter); Zustand stores livein
src/hooks/(useApplicationStore,useSearchStore,useDomainStore).index.tsbarrels were recommended in two places despiteno-internal-barrel-importsreportingthem and
frontend-performance.mdexplaining why.assets/icons/index.tsicon re-export is the exact pathological case that rule exists to prevent.Known follow-up, flagged in §6 rather than silently assumed: the absolute-import convention does
not work in application code yet.
jest.config.js:112setsmoduleDirectories: ['node_modules', 'src']so it resolves under Jest, but
tsconfig.jsonhas nobaseUrlandvite.config.tsaliases only@.That is why exactly one file in the repo uses a bare-layer import and it is a
.test.tsx. Enabling itneeds
"baseUrl": "./src"plus matching Viteresolve.aliasentries — deliberately left out to keepthis PR documentation-only.
Tests:
Use cases covered
Not applicable — documentation and agent config only, no runtime code changed.
Unit tests
Not applicable — no logic changed.
Backend integration tests
Ingestion integration tests
Playwright (UI) tests
Manual testing performed
docs/formutils.md,playwright/PLAYWRIGHT_DEVELOPER_HANDBOOK.md, rootCLAUDE.md,components/AppRouter/withSuspenseFallback.tsx.src/routes/,src/store/,src/stores/do not exist;
src/context/(11 providers) is canonical over the straysrc/contexts/(1 file),which the handbook now notes.
yarncommand cited exists inpackage.json:ui-checkstyle:changed(line 65),lint(36),organize-imports:cli(52),license-header-fix(30).components/folders case-insensitively —no collisions on a case-insensitive filesystem.
ComponentName.component.tsx/ComponentName.interface.tsnow returns zero hits outside the explicit "legacy, do not rename" notes.python3 scripts/harness/check_harness.py— 5 warnings, all pre-existing onmainandunrelated; no new dead references, and
frontend-react.mdis 94 lines against its 100-line budget.UI screen recording / screenshots:
Not applicable — markdown documentation only, no rendered UI changes.
Checklist:
Fixes <issue-number>: <short explanation>— no issue linked, see note above.Fixes #<issue-number>above.🤖 Generated with Claude Code
Greptile Summary
The PR establishes a layer-first, domain/feature-based organization and unified naming conventions for new UI code, then propagates that guidance across contributor and agent documentation.
Confidence Score: 3/5
The PR does not appear safe to merge until the outstanding type-check command and route-constant placement guidance are corrected.
The handbook still bypasses the existing Yarn type-check script and directs route constants away from the shared registry consumed by routers, links, and breadcrumbs.
Files Needing Attention: openmetadata-ui/src/main/resources/ui/DEVELOPER_HANDBOOK.md, .claude/rules/frontend-react.md
Important Files Changed
Reviews (2): Last reviewed commit: "docs: wire the UI folder-structure handb..." | Re-trigger Greptile