feat(lint): add components-v2/pages-v2 boundary zones (no back-port)

Adds three new eslint-plugin-boundaries element zones and their matrix
rows so the GUI-redesign v2 surface is structurally isolated: v1 code
cannot import from v2 (back-porting forbidden), v2 can reach the
narrow FormField/Icon bridge via the components-foundation zone, and
pages-v2 can import from components-v2. Backed by a Vitest spec
running via the ESLint Node API (node environment; happy-dom's
document object breaks the case-police resolver). Adds a placeholder
src/components-v2/shared/X.vue so the resolver can classify the
import target during the test (unresolvable imports are not boundary-
checked by the plugin).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 09:46:31 +02:00
parent 9d5398e0a2
commit b1d3b9f53b
3 changed files with 81 additions and 0 deletions

View File

@@ -247,6 +247,13 @@ module.exports = {
{ from: 'components-shared', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'components-shared'] },
{ from: 'components-portal', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal', 'components-shared', 'components-portal'] },
{ from: 'components-organizer', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'components-shared', 'components-organizer'] },
// v2 zones. components-v2 may use the FormField/Icon bridge
// (components-foundation) but NOT any other v1 component zone.
// No v1 `from` rule lists components-v2/pages-v2 → back-porting
// is structurally impossible (RFC-WS-GUI-REDESIGN AD-G5).
{ from: 'components-foundation', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'components-foundation'] },
{ from: 'components-v2', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'components-v2', 'components-foundation'] },
{ from: 'pages-v2', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'navigation', 'components-v2', 'components-foundation', 'layouts', 'plugins'] },
{ from: 'components', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'components', 'components-shared', 'components-organizer'] },
{ from: 'layouts', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal', 'navigation', 'components', 'components-shared', 'components-portal', 'components-organizer', 'layouts'] },
@@ -287,12 +294,26 @@ module.exports = {
{ type: 'components-shared', pattern: 'src/components/{shared,auth,settings}/**' },
{ type: 'components-portal', pattern: 'src/components/portal/**' },
{ type: 'components-organizer', pattern: 'src/components/organizer/**' },
// GUI-redesign v2 zones (RFC-WS-GUI-REDESIGN AD-G5). Declared
// before the generic `components` catch-all. `components-foundation`
// is the ONLY sanctioned v1→v2 bridge (FormField + Icon — audited
// to live in the generic `components` zone, not components-shared).
// Two-entry form used: eslint-plugin-boundaries 6.0.2 does not honour
// micromatch brace expansion in `pattern` (the brace glob matched in
// isolation but the plugin's internal resolver did not produce the
// expected classification). RFC §14 fallback: two entries with the
// same `type` so both src/components/forms/** and src/components/Icon.vue
// are captured before the generic `components` catch-all.
{ type: 'components-foundation', pattern: 'src/components/forms/**' },
{ type: 'components-foundation', pattern: 'src/components/Icon.vue' },
{ type: 'components-v2', pattern: 'src/components-v2/**' },
{ type: 'components', pattern: 'src/components/**' },
{ type: 'layouts', pattern: 'src/layouts/**' },
{ type: 'pages-register', pattern: 'src/pages/register/**' },
{ type: 'pages-portal', pattern: 'src/pages/portal/**' },
{ type: 'pages-platform', pattern: 'src/pages/platform/**' },
{ type: 'pages-organizer', pattern: 'src/pages/{events,members,organisation,account-settings,dashboard,invitations}/**' },
{ type: 'pages-v2', pattern: 'src/pages-v2/**' },
{ type: 'pages', pattern: 'src/pages/**' },
],
'boundaries/ignore': [