chore(eslint): activate boundary sub-zones (TECH-WS3-BOUNDARIES-SUBZONES)
Adds the WS-3 §4.2 sub-zone classification to the apps/app
boundaries matrix:
- components-{shared,portal,organizer} alongside the legacy
components type. components/{auth,settings} are folded into
components-shared as the legacy cross-context home for MFA dialogs
+ PasswordRequirements (used by both organizer reset-password and
portal wachtwoord-instellen / profiel).
- composables-forms (src/composables/forms/**) — pure form-runtime
helpers reusable from organizer Form Builder later.
- stores-portal (src/stores/portal/**) — keeps the portal auth +
portal store walled off from the organizer auth surface.
- pages-{register,portal,platform,organizer} alongside the legacy
pages type — register pages cannot reach into stores or
components-portal/-organizer; portal pages cannot reach
components-organizer; organizer + platform pages cannot reach
stores-portal or components-portal.
Cross-context edges are forbidden (organizer ↛ portal,
shared ↛ portal/organizer). Two pragmatic exceptions are documented
inline:
- components-shared accepts the legacy auth/ + settings/ paths
until PR-B2 cleanup re-homes them under shared/{auth,settings}/.
- pages-register may read stores-portal because success.vue
optionally enriches with the portal user when authenticated.
PR-B2 may move success.vue into pages-portal so this drops.
Lint: 0 errors / 0 new warnings (only the pre-existing
boundaries v5→v6 deprecation warnings, which apply to all 19 rules
now). Tests: 23 / 162 pass. Typecheck clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -208,26 +208,45 @@ module.exports = {
|
||||
// The `lib → stores` edge is intentionally disallowed; lib/axios.ts
|
||||
// uses dynamic `await import('@/stores/...')` for its 4 store reads
|
||||
// so the static-import surface stays clean.
|
||||
// Sub-zone enforcement (components/{organizer,portal,shared}) is a
|
||||
// backlog item (TECH-WS3-BOUNDARIES-SUBZONES); it lands after the
|
||||
// §4.2 consolidation directory layout.
|
||||
//
|
||||
// WS-3 PR-B1 activated TECH-WS3-BOUNDARIES-SUBZONES: components and
|
||||
// pages now have organizer/portal/shared sub-zones (§4.2 charter).
|
||||
// The cross-context edges (organizer ↛ portal, shared ↛ portal/organizer)
|
||||
// are forbidden so a future portal-only refactor cannot leak into
|
||||
// the organizer surface and vice versa.
|
||||
//
|
||||
// FORWARD-FLAG: when src/plugins/1.router/ migrates to src/router/
|
||||
// in a later WS-3 PR, add `{ type: 'router', pattern: 'src/router/**' }`
|
||||
// to boundaries/elements and `{ from: 'router', allow: ['types',
|
||||
// 'utils', 'lib', 'plugins', 'stores'] }` to the rules.
|
||||
// in a later WS-3 PR (TECH-WS3-BOUNDARIES-ROUTER-ZONE), add
|
||||
// `{ type: 'router', pattern: 'src/router/**' }` to boundaries/elements
|
||||
// and `{ from: 'router', allow: ['types', 'utils', 'lib', 'plugins',
|
||||
// 'stores'] }` to the rules.
|
||||
'boundaries/element-types': ['error', {
|
||||
default: 'disallow',
|
||||
rules: [
|
||||
{ from: 'types', allow: ['types'] },
|
||||
{ from: 'utils', allow: ['types', 'utils'] },
|
||||
{ from: 'lib', allow: ['types', 'utils', 'lib'] },
|
||||
{ from: 'plugins', allow: ['types', 'utils', 'lib', 'plugins', 'stores'] },
|
||||
{ from: 'composables', allow: ['types', 'utils', 'lib', 'composables', 'stores'] },
|
||||
{ from: 'stores', allow: ['types', 'utils', 'lib', 'composables', 'stores'] },
|
||||
{ from: 'plugins', allow: ['types', 'utils', 'lib', 'plugins', 'stores', 'stores-portal'] },
|
||||
{ from: 'composables-forms', allow: ['types', 'utils', 'lib', 'composables-forms'] },
|
||||
{ from: 'composables', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal'] },
|
||||
{ from: 'stores-portal', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal'] },
|
||||
{ from: 'stores', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores'] },
|
||||
{ from: 'navigation', allow: ['types', 'utils', 'navigation'] },
|
||||
{ from: 'components', allow: ['types', 'utils', 'lib', 'composables', 'stores', 'components'] },
|
||||
{ from: 'layouts', allow: ['types', 'utils', 'lib', 'composables', 'stores', 'navigation', 'components', 'layouts'] },
|
||||
{ from: 'pages', allow: ['types', 'utils', 'lib', 'composables', 'stores', 'navigation', 'components', 'layouts'] },
|
||||
{ from: 'components-shared', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', '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'] },
|
||||
{ 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'] },
|
||||
|
||||
// success.vue conditionally enriches with the portal auth user
|
||||
// ("Welcome back, X") when authenticated. The page is still public-
|
||||
// accessible; the store read is optional. PR-B2 cleanup may move
|
||||
// success.vue into pages-portal so this exception can drop.
|
||||
{ from: 'pages-register', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'plugins', 'components-shared', 'stores-portal', 'layouts'] },
|
||||
{ from: 'pages-portal', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal', 'navigation', 'components-shared', 'components-portal', 'layouts', 'plugins'] },
|
||||
{ from: 'pages-organizer', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'navigation', 'components', 'components-shared', 'components-organizer', 'layouts', 'plugins'] },
|
||||
{ from: 'pages-platform', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'navigation', 'components', 'components-shared', 'components-organizer', 'layouts', 'plugins'] },
|
||||
{ from: 'pages', allow: ['types', 'utils', 'lib', 'composables', 'composables-forms', 'stores', 'stores-portal', 'navigation', 'components', 'components-shared', 'components-portal', 'components-organizer', 'layouts'] },
|
||||
],
|
||||
}],
|
||||
'boundaries/no-unknown': 'off', // External packages are fine.
|
||||
@@ -239,17 +258,33 @@ module.exports = {
|
||||
typescript: {},
|
||||
},
|
||||
|
||||
// Element-type assignment: first-match-wins. Order matters.
|
||||
// Element-type assignment: first-match-wins. Order matters — narrower
|
||||
// sub-zones declared before their broader parents.
|
||||
'boundaries/elements': [
|
||||
{ type: 'types', pattern: 'src/types/**' },
|
||||
{ type: 'utils', pattern: 'src/utils/**' },
|
||||
{ type: 'lib', pattern: 'src/lib/**' },
|
||||
{ type: 'plugins', pattern: 'src/plugins/**' },
|
||||
{ type: 'composables-forms', pattern: 'src/composables/forms/**' },
|
||||
{ type: 'composables', pattern: 'src/composables/**' },
|
||||
{ type: 'stores-portal', pattern: 'src/stores/portal/**' },
|
||||
{ type: 'stores', pattern: 'src/stores/**' },
|
||||
{ type: 'navigation', pattern: 'src/navigation/**' },
|
||||
|
||||
// components/shared/** is the canonical sub-zone. components/auth/**
|
||||
// and components/settings/** are folded in here as legacy cross-context
|
||||
// siblings (MFA dialogs + password-requirements widgets used by both
|
||||
// organizer reset-password and portal wachtwoord-instellen / profiel
|
||||
// flows). PR-B2 may rehome these under components/shared/{auth,settings}/.
|
||||
{ type: 'components-shared', pattern: 'src/components/{shared,auth,settings}/**' },
|
||||
{ type: 'components-portal', pattern: 'src/components/portal/**' },
|
||||
{ type: 'components-organizer', pattern: 'src/components/organizer/**' },
|
||||
{ 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', pattern: 'src/pages/**' },
|
||||
],
|
||||
'boundaries/ignore': [
|
||||
|
||||
Reference in New Issue
Block a user