Initial commit: Clean DSS implementation

Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm

Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)

Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability

Migration completed: $(date)
🤖 Clean migration with full functionality preserved
This commit is contained in:
Digital Production Factory
2025-12-09 18:45:48 -03:00
commit 276ed71f31
884 changed files with 373737 additions and 0 deletions

View File

@@ -0,0 +1,735 @@
{
"$schema": "dss-knowledge-v1",
"type": "coding_standards",
"version": "1.0.0",
"last_updated": "2025-12-08",
"description": "Immutable coding best practices for all DSS code. These standards are enforced via pre-commit hooks and guide all code contributions.",
"web_components": {
"principle": "All UI components MUST be Web Components using Custom Elements API",
"rules": [
{
"id": "WC-001",
"rule": "Shadow DOM Required",
"requirement": "MUST use attachShadow({ mode: 'open' }) for all components",
"exceptions": "None - this is non-negotiable for style encapsulation",
"rationale": "Prevents global CSS pollution and ensures component isolation",
"enforcement": "Pre-commit hook fails if component extends HTMLElement without Shadow DOM"
},
{
"id": "WC-002",
"rule": "Lifecycle Management",
"requirement": "MUST implement connectedCallback, disconnectedCallback, and attributeChangedCallback where appropriate",
"pattern": "Always clean up event listeners and subscriptions in disconnectedCallback",
"example": "disconnectedCallback() { if (this.unsubscribe) this.unsubscribe(); if (this.abortController) this.abortController.abort(); }"
},
{
"id": "WC-003",
"rule": "Observable Attributes",
"requirement": "Define observedAttributes static getter for reactive attributes",
"pattern": "static get observedAttributes() { return ['title', 'value', 'color']; }",
"rationale": "Enables reactive attribute changes without manual DOM manipulation"
},
{
"id": "WC-004",
"rule": "Component Registration",
"requirement": "Define custom element in component file using customElements.define()",
"pattern": "customElements.define('ds-component-name', ComponentClass);",
"naming": "All DSS components prefixed with 'ds-' to avoid conflicts"
}
]
},
"style_management": {
"principle": "Zero inline styles policy - all styles in Shadow DOM or external stylesheets",
"rules": [
{
"id": "STYLE-001",
"rule": "NO Inline Styles",
"requirement": "FORBIDDEN: style=\"...\" attributes in templates",
"exceptions": "ONLY dynamic computed values (e.g., transform: translateX(${x}px), width: ${percent}%)",
"enforcement": "Pre-commit hook fails if >10 inline styles detected",
"rationale": "Maintainability, separation of concerns, style encapsulation"
},
{
"id": "STYLE-002",
"rule": "Shadow DOM Styles",
"requirement": "All component styles in <style> block within shadowRoot.innerHTML",
"pattern": "this.shadowRoot.innerHTML = `<style>:host { display: block; } .card { padding: 16px; }</style><div class=\"card\">...</div>`;",
"best_practice": "Define styles at top of template for clarity"
},
{
"id": "STYLE-003",
"rule": "VSCode Theme Tokens",
"requirement": "MUST use CSS custom properties from VSCode theme",
"required_variables": [
"--vscode-foreground",
"--vscode-background",
"--vscode-sidebar-background",
"--vscode-button-background",
"--vscode-button-foreground",
"--vscode-button-secondaryBackground",
"--vscode-button-secondaryForeground",
"--vscode-focusBorder",
"--vscode-list-hoverBackground",
"--vscode-list-activeSelectionBackground",
"--vscode-list-activeSelectionForeground",
"--vscode-descriptionForeground",
"--vscode-widget-border",
"--vscode-errorForeground"
],
"rationale": "Ensures consistent theming with VSCode dark/light mode"
},
{
"id": "STYLE-004",
"rule": "Constructable Stylesheets",
"requirement": "Use for shared styles across multiple components",
"pattern": "const sheet = new CSSStyleSheet(); sheet.replaceSync(css); shadowRoot.adoptedStyleSheets = [sheet];",
"use_cases": ["Common button styles", "Typography system", "Layout utilities"]
},
{
"id": "STYLE-005",
"rule": "CSS Hover Effects",
"requirement": "Use :hover pseudo-class, NOT onmouseover/onmouseout",
"correct": ".card:hover { background: var(--vscode-list-hoverBackground); }",
"forbidden": "onmouseover=\"this.style.background='...'\" onmouseout=\"this.style.background=''\"",
"rationale": "Performance, maintainability, separation of concerns"
}
]
},
"event_handling": {
"principle": "Event delegation pattern - NO inline event handlers",
"rules": [
{
"id": "EVENT-001",
"rule": "NO Inline Events",
"requirement": "FORBIDDEN: onclick, onmouseover, onmouseout, onkeydown, onkeyup, etc. in HTML",
"enforcement": "Pre-commit hook fails if ANY inline event handlers detected",
"rationale": "Security (CSP compliance), maintainability, testability, separation of concerns"
},
{
"id": "EVENT-002",
"rule": "Event Delegation Pattern",
"requirement": "Single delegated listener per component using data-action attributes",
"pattern": "this.shadowRoot.addEventListener('click', (e) => { const action = e.target.closest('[data-action]')?.dataset.action; if (action && this[`handle${action}`]) { this[`handle${action}`](e); } });",
"html_example": "<button data-action=\"save\" type=\"button\">Save</button>",
"js_example": "handleSave(e) { /* implementation */ }"
},
{
"id": "EVENT-003",
"rule": "Custom Events for Communication",
"requirement": "Component communication via CustomEvent with composed: true",
"pattern": "this.dispatchEvent(new CustomEvent('ds-action', { detail: { action, data }, bubbles: true, composed: true }));",
"rationale": "composed: true allows events to bubble out of Shadow DOM boundaries"
},
{
"id": "EVENT-004",
"rule": "Event Listener Cleanup",
"requirement": "Always remove event listeners in disconnectedCallback",
"pattern": "this.abortController = new AbortController(); addEventListener('click', handler, { signal: this.abortController.signal }); // disconnectedCallback: this.abortController.abort();",
"alternative": "Store handlers as methods and call removeEventListener explicitly"
},
{
"id": "EVENT-005",
"rule": "Keyboard Navigation",
"requirement": "Support Tab, Enter, Escape, Arrow keys for interactive components",
"pattern": "this.shadowRoot.addEventListener('keydown', (e) => { if (e.key === 'Escape') this.close(); if (e.key === 'Enter') this.submit(); });",
"rationale": "Accessibility requirement for keyboard-only users"
}
]
},
"accessibility": {
"principle": "WCAG 2.1 Level AA compliance minimum",
"rules": [
{
"id": "A11Y-001",
"rule": "Semantic HTML",
"requirement": "MUST use semantic elements: <button>, <nav>, <main>, <aside>, <header>, <footer>, <article>, <section>",
"forbidden": "<div onclick=\"...\"> for interactive elements, <div class=\"button\">",
"correct": "<button type=\"button\">Click me</button>",
"rationale": "Screen readers rely on semantic HTML for navigation and interaction"
},
{
"id": "A11Y-002",
"rule": "Button Type Attribute",
"requirement": "ALL <button> elements MUST have type=\"button\" (or type=\"submit\" in forms)",
"pattern": "<button type=\"button\">Action</button>",
"rationale": "Prevents accidental form submission in HTML forms",
"enforcement": "Pre-commit hook warns about buttons without type attribute"
},
{
"id": "A11Y-003",
"rule": "ARIA Attributes",
"requirement": "Use when semantic HTML insufficient",
"required_patterns": [
"aria-label for icon-only buttons",
"aria-labelledby for complex widgets",
"aria-describedby for additional context",
"role for custom interactive elements"
],
"examples": [
"<button aria-label=\"Close dialog\" type=\"button\">×</button>",
"<div role=\"group\" aria-labelledby=\"tools-heading\">...</div>"
]
},
{
"id": "A11Y-004",
"rule": "Focus Management",
"requirement": "Keyboard navigation support for all interactive elements",
"css_pattern": ".btn:focus-visible { outline: 2px solid var(--vscode-focusBorder); outline-offset: 2px; }",
"js_requirements": [
"trapFocus() for modals",
"restoreFocus() on close",
"Skip links for main content",
"Focus first invalid field on validation error"
]
},
{
"id": "A11Y-005",
"rule": "Color Contrast",
"requirement": "Minimum 4.5:1 for normal text, 3:1 for large text",
"tool": "Use VSCode theme tokens which meet contrast requirements",
"testing": "Chrome DevTools Lighthouse audit"
},
{
"id": "A11Y-006",
"rule": "Screen Reader Testing",
"requirement": "Test all components with NVDA/JAWS (Windows) or VoiceOver (Mac)",
"checklist": [
"Navigation order makes sense",
"All buttons have clear labels",
"Error messages announced",
"Status updates announced with aria-live"
]
}
]
},
"state_management": {
"principle": "Centralized state with reactive updates",
"rules": [
{
"id": "STATE-001",
"rule": "Context Store for Global State",
"requirement": "Use contextStore for application-wide state (projectId, teamId, userId)",
"pattern": "this.unsubscribe = contextStore.subscribeToKey('projectId', (newValue) => { this.projectId = newValue; this.render(); });",
"path": "admin-ui/js/stores/context-store.js"
},
{
"id": "STATE-002",
"rule": "Component Local State",
"requirement": "Component-specific state in this.state object",
"pattern": "this.state = { isLoading: false, data: null, error: null }; setState(updates) { Object.assign(this.state, updates); this.render(); }",
"best_practice": "Initialize state in constructor"
},
{
"id": "STATE-003",
"rule": "NO Direct DOM Manipulation",
"requirement": "State changes trigger re-renders, not direct DOM updates",
"forbidden": "document.getElementById('foo').textContent = 'bar'; element.style.display = 'none';",
"correct": "this.setState({ foo: 'bar', visible: false }); // render() handles DOM updates",
"rationale": "Maintains single source of truth, prevents state/view desync"
},
{
"id": "STATE-004",
"rule": "Subscription Cleanup",
"requirement": "Always unsubscribe in disconnectedCallback",
"pattern": "connectedCallback() { this.unsubscribe = store.subscribe(...); } disconnectedCallback() { if (this.unsubscribe) this.unsubscribe(); }",
"rationale": "Prevents memory leaks from orphaned subscriptions"
},
{
"id": "STATE-005",
"rule": "Immutable State Updates",
"requirement": "Create new state objects, don't mutate existing",
"correct": "this.state = { ...this.state, count: this.state.count + 1 };",
"forbidden": "this.state.count++; // direct mutation",
"rationale": "Enables change detection and debugging"
}
]
},
"code_organization": {
"principle": "Single Responsibility, clear structure, modular design",
"rules": [
{
"id": "ORG-001",
"rule": "File Size Limit",
"requirement": "Maximum 500 lines per file",
"action": "If larger, split into multiple modules",
"enforcement": "Quality check warns on files >500 lines",
"current_violation": "app.js at 4,347 lines must be decomposed"
},
{
"id": "ORG-002",
"rule": "Directory Structure",
"requirement": "Strict organization by type and purpose",
"structure": {
"admin-ui/js/components/": "Web components (*.js)",
"admin-ui/js/components/layout/": "Layout components (shell, header, sidebar)",
"admin-ui/js/components/metrics/": "Dashboard and metric components",
"admin-ui/js/components/tools/": "Tool-specific components",
"admin-ui/js/components/listings/": "List/table components",
"admin-ui/js/stores/": "State management",
"admin-ui/js/utils/": "Helper functions and utilities",
"admin-ui/js/core/": "Core modules (router, messaging, workflows)",
"admin-ui/js/workdesks/": "Team workdesk controllers",
"admin-ui/js/config/": "Configuration files"
}
},
{
"id": "ORG-003",
"rule": "Import Style",
"requirement": "Explicit named imports, no wildcards",
"correct": "import { hydrateComponent } from '../config/component-registry.js';",
"forbidden": "import * as registry from '../config/component-registry.js';",
"rationale": "Tree-shaking, explicit dependencies, better IDE support"
},
{
"id": "ORG-004",
"rule": "Export Style",
"requirement": "Named exports for utilities, default export for components",
"utility_pattern": "export function debounce(fn, ms) { ... } export function throttle(fn, ms) { ... }",
"component_pattern": "export default class MyComponent extends HTMLElement { ... }",
"rationale": "Convention clarity, supports tree-shaking"
},
{
"id": "ORG-005",
"rule": "Single Responsibility Principle",
"requirement": "One component = one concern, one file = one primary export",
"examples": [
"ds-metric-card.js: Displays a single metric card",
"ds-frontpage.js: Orchestrates dashboard layout",
"context-store.js: Manages global application state"
],
"anti_pattern": "utility-functions.js with 50 unrelated functions"
}
]
},
"error_handling": {
"principle": "Structured logging, user-friendly errors, graceful degradation",
"rules": [
{
"id": "ERROR-001",
"rule": "Centralized Logger",
"requirement": "Use logger utility for all logging",
"path": "admin-ui/js/utils/logger.js",
"methods": [
"logger.debug(msg, ...args): Development-only logging",
"logger.info(msg, ...args): Informational messages",
"logger.warn(msg, ...args): Warning conditions",
"logger.error(msg, ...args): Error conditions"
],
"pattern": "import { logger } from '../utils/logger.js'; logger.info('[ComponentName] Action completed', { data });"
},
{
"id": "ERROR-002",
"rule": "NO console.log in Production",
"requirement": "Replace all console.log/warn/error with logger methods",
"enforcement": "Pre-commit hook warns if >10 console statements",
"exceptions": "Core initialization logging in app.js only",
"migration": "console.log('foo') → logger.debug('foo')"
},
{
"id": "ERROR-003",
"rule": "User-Friendly Error Messages",
"requirement": "Error messages must be actionable and clear",
"good": "Failed to load projects. Please check your internet connection and try again.",
"bad": "Error: HTTP 500", "TypeError: Cannot read property 'id' of undefined",
"pattern": "Show what failed + why it might have failed + what user can do"
},
{
"id": "ERROR-004",
"rule": "Error Taxonomy",
"requirement": "Use structured error codes from messaging.js",
"codes": {
"E1xxx": "User errors (invalid input, forbidden actions)",
"E2xxx": "Validation errors (missing fields, invalid formats)",
"E3xxx": "API errors (request failed, timeout, unauthorized)",
"E4xxx": "System errors (unexpected, network, storage)",
"E5xxx": "Integration errors (Figma, external APIs)",
"S1xxx": "Success codes"
},
"usage": "notifyError('E3001', 'Failed to fetch projects', error);"
},
{
"id": "ERROR-005",
"rule": "Graceful Degradation",
"requirement": "Components must handle missing/invalid data gracefully",
"patterns": [
"if (!data) return this.renderEmptyState();",
"if (error) return this.renderError(error);",
"const items = data?.items ?? [];"
],
"anti_pattern": "Assuming data exists and causing cascading failures"
},
{
"id": "ERROR-006",
"rule": "Try-Catch for Async Operations",
"requirement": "Wrap all async operations in try-catch",
"pattern": "async loadData() { try { const data = await fetch(...); } catch (error) { logger.error('[Component] Failed to load', error); this.handleError(error); } }",
"rationale": "Prevents unhandled promise rejections"
}
]
},
"performance": {
"principle": "Optimize for user experience, measure and improve",
"rules": [
{
"id": "PERF-001",
"rule": "Lazy Loading",
"requirement": "Non-critical components loaded on-demand via hydrateComponent()",
"pattern": "await hydrateComponent('ds-screenshot-gallery', container);",
"benefits": "Faster initial load, reduced bundle size",
"applies_to": ["Tool components", "Heavy visualizations", "Rarely-used features"]
},
{
"id": "PERF-002",
"rule": "Virtual Scrolling",
"requirement": "Use for lists >100 items",
"libraries": ["lit-virtualizer", "virtual-scroller"],
"pattern": "import { VirtualScroller } from 'virtual-scroller'; new VirtualScroller(container, { items, renderItem });",
"applies_to": ["Token lists", "Component catalogs", "Log viewers"]
},
{
"id": "PERF-003",
"rule": "Debouncing and Throttling",
"requirement": "Debounce search inputs, throttle scroll/resize handlers",
"debounce_pattern": "this.searchDebounced = debounce(() => this.performSearch(), 300);",
"throttle_pattern": "this.onScrollThrottled = throttle(() => this.handleScroll(), 100);",
"use_cases": {
"debounce": "Search inputs, form validation, autosave",
"throttle": "Scroll handlers, resize handlers, mousemove tracking"
}
},
{
"id": "PERF-004",
"rule": "Avoid Unnecessary Re-renders",
"requirement": "Only re-render when state actually changes",
"pattern": "attributeChangedCallback(name, oldValue, newValue) { if (oldValue === newValue) return; this.render(); }",
"best_practice": "Compare old vs new state before rendering"
},
{
"id": "PERF-005",
"rule": "Bundle Size Monitoring",
"requirement": "Monitor and optimize JavaScript bundle sizes",
"targets": {
"individual_component": "<50KB",
"total_bundle": "<500KB",
"critical_path": "<200KB"
},
"tools": ["webpack-bundle-analyzer", "source-map-explorer"]
},
{
"id": "PERF-006",
"rule": "Minimize DOM Operations",
"requirement": "Batch DOM updates, use DocumentFragment for multiple inserts",
"pattern": "const fragment = document.createDocumentFragment(); items.forEach(item => fragment.appendChild(createNode(item))); container.appendChild(fragment);",
"anti_pattern": "items.forEach(item => container.appendChild(createNode(item))); // causes multiple reflows"
}
]
},
"security": {
"principle": "Secure by default, defense in depth",
"rules": [
{
"id": "SEC-001",
"rule": "NO Hardcoded Secrets",
"requirement": "FORBIDDEN: API keys, passwords, tokens, credentials in code",
"enforcement": "Pre-commit hook fails if secret patterns detected (apiKey, api_key, password, secret, token)",
"correct": "Use environment variables or secure configuration service",
"rationale": "Prevents credential leaks in version control"
},
{
"id": "SEC-002",
"rule": "Input Sanitization",
"requirement": "ALWAYS escape user input before rendering to DOM",
"utility": "ComponentHelpers.escapeHtml(userInput)",
"pattern": "<div>${ComponentHelpers.escapeHtml(project.name)}</div>",
"forbidden": "<div>${project.name}</div> // XSS vulnerability",
"rationale": "Prevents XSS attacks"
},
{
"id": "SEC-003",
"rule": "CSP Compliance",
"requirement": "NO eval(), NO new Function(), NO inline scripts",
"forbidden": [
"eval(code)",
"new Function('x', 'return x * 2')",
"<script>alert(1)</script> in templates"
],
"rationale": "Content Security Policy compatibility, prevents code injection"
},
{
"id": "SEC-004",
"rule": "HTTPS Only",
"requirement": "All external requests use HTTPS",
"enforcement": "No http:// URLs in fetch() calls",
"correct": "fetch('https://api.example.com/data')",
"forbidden": "fetch('http://api.example.com/data')",
"exceptions": "localhost development only"
},
{
"id": "SEC-005",
"rule": "Validate API Responses",
"requirement": "Always validate structure and content of API responses",
"pattern": "const data = await response.json(); if (!data || !Array.isArray(data.items)) throw new Error('Invalid response');",
"rationale": "Prevents errors from malformed/malicious responses"
},
{
"id": "SEC-006",
"rule": "Authentication Token Handling",
"requirement": "Store auth tokens securely, never in localStorage",
"correct": "sessionStorage (better: httpOnly cookies)",
"forbidden": "localStorage for sensitive tokens",
"rationale": "localStorage accessible to XSS attacks"
}
]
},
"testing_and_quality": {
"principle": "Automated quality gates, comprehensive testing",
"rules": [
{
"id": "TEST-001",
"rule": "Pre-commit Hooks",
"requirement": "MUST pass all quality checks before commit",
"script": "scripts/verify-quality.sh",
"thresholds": {
"inline_styles": "≤10 (exceptions for dynamic values only)",
"inline_events": "0 (zero tolerance)",
"console_statements": "≤10 (production code only)",
"file_size": "≤100KB per file",
"syntax_errors": "0 (zero tolerance)"
},
"bypass": "git commit --no-verify (not recommended, requires justification)"
},
{
"id": "TEST-002",
"rule": "Component Unit Tests",
"requirement": "Unit tests for all components",
"coverage": "Minimum 80% for critical paths",
"framework": "Web Test Runner or Vitest",
"test_cases": [
"Component renders correctly",
"Props/attributes update component",
"Event handlers work",
"Cleanup happens on disconnect"
]
},
{
"id": "TEST-003",
"rule": "Integration Tests",
"requirement": "Test critical user flows end-to-end",
"examples": [
"Project creation workflow",
"Token extraction from Figma",
"Component audit process",
"User authentication flow"
],
"tools": ["Playwright", "Cypress"]
},
{
"id": "TEST-004",
"rule": "Visual Regression Testing",
"requirement": "Screenshot comparison for UI changes",
"tools": ["Playwright screenshots", "Percy", "Chromatic"],
"process": "Capture baseline → Make changes → Compare → Approve/reject",
"applies_to": "All visible UI components"
},
{
"id": "TEST-005",
"rule": "Documentation",
"requirement": "JSDoc comments for public APIs and complex logic",
"pattern": "/**\n * Load project data from API\n * @param {string} projectId - The project identifier\n * @returns {Promise<Project>} The loaded project\n * @throws {Error} If project not found or network error\n */\nasync loadProject(projectId) { ... }",
"applies_to": ["Public component methods", "Utility functions", "Store APIs"]
},
{
"id": "TEST-006",
"rule": "Code Review Checklist",
"requirement": "All PRs reviewed against these standards",
"checklist": [
"✓ Shadow DOM used for all components",
"✓ No inline styles or event handlers",
"✓ Proper accessibility attributes",
"✓ Event listeners cleaned up",
"✓ User input sanitized",
"✓ Error handling implemented",
"✓ Tests added/updated"
]
}
]
},
"enforcement": {
"description": "How these standards are enforced in the development workflow",
"mechanisms": [
{
"type": "Pre-commit Hooks",
"file": ".git/hooks/pre-commit",
"action": "Runs scripts/verify-quality.sh automatically",
"can_bypass": "git commit --no-verify (requires justification)"
},
{
"type": "Quality Verification Script",
"file": "scripts/verify-quality.sh",
"checks": [
"Inline event handlers detection",
"Inline styles counting",
"Missing ARIA attributes",
"Console.log statements",
"JavaScript syntax validation",
"Hardcoded secrets detection",
"Shadow DOM usage statistics",
"File size warnings"
]
},
{
"type": "Immutability Protection",
"file": ".clauderc",
"protection": "This file listed in protected_core_files",
"requirement": "ALLOW_CORE_CHANGES=true to modify"
},
{
"type": "AI Agent Instructions",
"description": "AI assistants programmed to follow these standards",
"behavior": [
"Always use Shadow DOM for components",
"Never generate inline event handlers",
"Extract inline styles to style blocks",
"Add proper accessibility attributes",
"Use logger instead of console.log"
]
}
]
},
"migration_strategy": {
"description": "How to migrate existing code to these standards",
"phases": [
{
"phase": 1,
"name": "Foundation Fixes",
"duration": "Week 1",
"priority": "Critical",
"tasks": [
"Refactor tool-templates.js to generate compliant HTML",
"Create logger utility (admin-ui/js/utils/logger.js)",
"Update verify-quality.sh thresholds",
"Create migration guide with examples"
]
},
{
"phase": 2,
"name": "Component Migration - Batch A",
"duration": "Week 2",
"priority": "High",
"targets": [
"Layout components (ds-project-selector, ds-shell, ds-header)",
"Most violated: ds-screenshot-gallery, ds-network-monitor"
],
"pattern": "Add Shadow DOM → Extract styles → Replace inline events → Add ARIA"
},
{
"phase": 3,
"name": "Component Migration - Batch B",
"duration": "Week 3",
"priority": "High",
"targets": [
"Tool components (ds-activity-log, ds-test-results)",
"Admin/listings (ds-project-list, ds-token-list)"
]
},
{
"phase": 4,
"name": "Monolith Decomposition",
"duration": "Week 4",
"priority": "Critical",
"target": "app.js (4,347 lines → 7 modules)",
"modules": [
"app.js: Main orchestrator (<500 lines)",
"router.js: Hash routing",
"auth-manager.js: Authentication",
"api-client.js: Fetch wrapper",
"error-handler.js: Global errors",
"state-manager.js: State coordination",
"init.js: Initialization"
]
},
{
"phase": 5,
"name": "Quality Enforcement",
"duration": "Week 5",
"priority": "Medium",
"tasks": [
"Update thresholds (inline styles ≤10, events = 0)",
"Add ESLint/Stylelint rules",
"CI/CD integration",
"Developer training"
]
}
]
},
"reference_implementations": {
"description": "Examples of components that follow these standards",
"files": [
{
"file": "admin-ui/js/workdesks/base-workdesk.js",
"demonstrates": [
"Semantic HTML (buttons not divs)",
"Event delegation pattern",
"Extracted styles in style block",
"ARIA attributes",
"Focus management"
]
},
{
"file": "admin-ui/js/components/metrics/ds-frontpage.js",
"demonstrates": [
"Shadow DOM implementation",
"Zero inline styles",
"Lifecycle management",
"State subscription pattern",
"Event cleanup"
]
},
{
"file": "admin-ui/js/components/metrics/ds-metric-card.js",
"demonstrates": [
"Observable attributes",
"Shadow DOM encapsulation",
"Reactive rendering",
"Component composition"
]
}
]
},
"success_metrics": {
"description": "Measurable goals for DSS code quality",
"current_state": {
"shadow_dom_adoption": "23% (12/53 components)",
"inline_event_handlers": "20+",
"inline_styles": "1,288",
"console_statements": "100+",
"largest_file": "app.js at 4,347 lines / 156KB"
},
"target_state": {
"shadow_dom_adoption": "100% (53/53 components)",
"inline_event_handlers": "0 (zero tolerance)",
"inline_styles": "<10 (dynamic values only)",
"console_statements": "<10 (core only)",
"largest_file": "<500 lines per file"
},
"tracking": {
"method": "Pre-commit hook statistics",
"frequency": "Every commit",
"reporting": "Monthly code quality dashboard"
}
}
}