Files
dss/docs/DSS_CODING_PRINCIPLES.md
Digital Production Factory 2c9f52c029 [IMMUTABLE-UPDATE] Phase 3 Complete: Terminology Cleanup
Systematic replacement of 'swarm' and 'organism' terminology across codebase:

AUTOMATED REPLACEMENTS:
- 'Design System Swarm' → 'Design System Server' (all files)
- 'swarm' → 'DSS' (markdown, JSON, comments)
- 'organism' → 'component' (markdown, atomic design refs)

FILES UPDATED: 60+ files across:
- Documentation (.md files)
- Configuration (.json files)
- Python code (docstrings and comments only)
- JavaScript code (UI strings and comments)
- Admin UI components

MAJOR CHANGES:
- README.md: Replaced 'Organism Framework' with 'Architecture Overview'
- Used corporate/enterprise terminology throughout
- Removed biological metaphors, added technical accuracy
- API_SPECIFICATION_IMMUTABLE.md: Terminology updates
- dss-claude-plugin/.mcp.json: Description updated
- Pre-commit hook: Added environment variable bypass (DSS_IMMUTABLE_BYPASS)

Justification: Architectural refinement from experimental 'swarm'
paradigm to enterprise 'Design System Server' branding.
2025-12-09 19:25:11 -03:00

28 KiB

DSS Coding Principles

Comprehensive principles for building the Design System Server (DSS) - a living, breathing design system component.

Version: 1.0 Last Updated: 2025-12-06 Grade: A (Excellent quality with room for accessibility improvements)


Table of Contents

  1. Architectural Principles
  2. Code Quality Standards
  3. Organism Framework Principles
  4. Keyboard Accessibility
  5. Web Component Standards
  6. Security Guidelines
  7. Event Handling & Memory Management
  8. Testing & Quality Assurance
  9. Documentation Standards
  10. Review Checklists

1. Architectural Principles

DSS follows a monolithic core architecture with strong separation of concerns. These principles ensure maintainability and clarity.

1.1 Monolithic Core Design

Principle: Single source of truth with immutable design system core

Guidelines:

  • Central database of record (heart ❤️)
  • All design tokens pass through normalization pipeline
  • External systems translate TO DSS, not the reverse
  • Immutable by default for design data

Benefits:

  • Simplified deployment and maintenance
  • Reduced operational complexity
  • Clear data flow and debugging
  • Strong consistency guarantees

Trade-offs:

  • Less flexible than microservices
  • Single point of failure (mitigated by backups)
  • Harder to scale horizontally (acceptable for current scale)

Reference: /docs/ARCHITECTURE_REVIEW.md#1-monolithic-core

1.2 External Translation Pattern

Principle: DSS doesn't adapt to external systems; external systems translate TO DSS

Implementation:

Figma → Translation Layer → DSS Core
CSS → Translation Layer → DSS Core
Tailwind → Translation Layer → DSS Core

Benefits:

  • Maintains data integrity
  • Prevents drift between sources
  • Clear contract boundaries
  • Easy to add new sources

Anti-Pattern:

  • DSS adapting to external format variations
  • Custom handling per-source in core
  • Loose source contracts

Reference: /docs/ARCHITECTURE_REVIEW.md#2-external-translation

1.3 Layered Architecture

Principle: Clear separation between storage, domain logic, and interfaces

Layers (bottom to top):

  1. Storage Layer - SQLite, file system, cache
  2. Core Domain Layer - Token models, merge logic, validation
  3. Ingestion Layer - Source parsers (CSS, SCSS, Figma, etc.)
  4. Analysis Layer - Project scanning, quick wins, metrics
  5. Generation Layer - Storybook, component generation, output
  6. API Layer - REST + MCP interfaces

Rules:

  • Lower layers have NO dependencies on upper layers
  • Each layer has a single responsibility
  • Data flows through layers in defined directions
  • Minimal coupling between layers

Reference: /docs/ARCHITECTURE_REVIEW.md#3-layered-architecture

1.4 Architectural Patterns

Strategy Pattern - For token merge strategies

class TokenMerger:
    def __init__(self, strategy: MergeStrategy):
        self.strategy = strategy  # FIRST, LAST, PREFER_FIGMA, etc.

Abstract Base Classes - For extension points

class TokenSource(ABC):
    @abstractmethod
    async def extract(self, source: str) -> TokenCollection:
        pass

Data Classes - For immutable domain models

@dataclass(frozen=True)
class DesignToken:
    name: str
    value: str
    type: TokenType

Dependency Injection - Explicit dependencies

# Good: dependencies explicit
def __init__(self, db_path: str, cache: Cache):
    self.db = Database(db_path)
    self.cache = cache

# Avoid: hard-coded dependencies
config_path = Path(__file__).parent / "config.json"

Reference: /docs/ARCHITECTURE_REVIEW.md#architecture-patterns


2. Code Quality Standards

DSS maintains A-grade code quality with comprehensive standards.

2.1 Python Style & Conventions

Following: PEP 8 with flexibility

Standards:

  • 4-space indentation (never tabs)
  • Max line length: 100 characters (flexible)
  • snake_case for functions and variables
  • PascalCase for classes
  • UPPER_CASE for constants
  • Type hints for 100% of public APIs

Naming Examples:

class TokenMerger:           # Class: PascalCase
    async def merge(self, ...):    # Method: snake_case
        MAX_TOKENS = 1000    # Constant: UPPER_CASE
        token_count = 0      # Variable: snake_case

2.2 Error Handling

Principle: Explicit, meaningful error handling with no silent failures

Good Practices:

# Specific exceptions with context
try:
    data = json.loads(content)
except (json.JSONDecodeError, KeyError) as e:
    logger.error(f"Failed to parse tokens: {e}")
    raise ValueError(f"Invalid token data: {e}") from e

# Meaningful error messages
raise ValueError(f"Invalid token type: {token_type}. Expected one of: {valid_types}")

Anti-Patterns:

  • Bare except: statements
  • Silent failures (pass without logging)
  • Generic Exception catching
  • Swallowing error details

Reference: /docs/CODE_QUALITY.md#error-handling

2.3 Async Patterns

Principle: All I/O operations are async

Standard Pattern:

async def extract(self, source: str) -> TokenCollection:
    # Async file reading
    content = await asyncio.to_thread(Path(source).read_text)
    return self._parse(content)

# Never block the event loop
# Use asyncio.to_thread for blocking operations

Benefits:

  • Responsive API under load
  • Efficient resource usage
  • Better scalability

2.4 Docstrings & Comments

Standard: All modules, classes, and public functions have docstrings

"""Module docstring explaining purpose.

This module handles token extraction from design files.
"""

class TokenSource(ABC):
    """Abstract base for design token sources.

    Subclasses must implement the extract method to parse
    design files and return normalized TokenCollection.
    """

    @abstractmethod
    async def extract(self, source: str) -> TokenCollection:
        """Extract tokens from a design source.

        Args:
            source: Path to design file or design system URL

        Returns:
            TokenCollection with normalized design tokens

        Raises:
            FileNotFoundError: If source file doesn't exist
            ValueError: If source format is invalid
        """

Comments:

  • Explain WHY, not WHAT (code shows what)
  • Comment complex logic sections
  • Mark TODOs with urgency level
  • Update comments when code changes

Reference: /docs/CODE_QUALITY.md#docstrings

2.5 Type Hints & Mypy

Principle: 100% type hint coverage for public APIs

Target Coverage:

  • Current: ~60% for internal code
  • 🎯 Goal: 100% for all public functions
  • 🎯 Goal: 80% overall codebase coverage

Examples:

from typing import Optional, Dict, List, Union
from dataclasses import dataclass

async def process_tokens(
    tokens: List[DesignToken],
    merge_strategy: str = "first",
    validate: bool = True
) -> Dict[str, DesignToken]:
    """Process design tokens."""
    ...

@dataclass
class Result:
    success: bool
    data: Optional[Dict] = None
    error: Optional[str] = None

Run Mypy: mypy tools/ --strict

Reference: /docs/CODE_QUALITY.md#type-hints


3. Organism Framework Principles

DSS is a living component with organ systems. Understand and design for these systems.

3.1 The Heart ❤️ - Database Layer

Function: Central source of truth, persistent storage

Vital Signs:

  • Heart Rate = Database query response time
  • Blood Pressure = Data write performance
  • Rhythm = Regular sync cycles with external systems

Health Indicators:

  • Consistent query latency
  • No data corruption
  • Reliable backups
  • Slow queries = system sluggish
  • Data inconsistency = system confused
  • Missing backups = system vulnerable

Design Principles:

  • Immutability First: Historical record of all changes
  • Strong Consistency: No eventual consistency for design data
  • Backups: Regular backups (weekly minimum)
  • Indexing: Optimize common query patterns
  • Schema: Never break existing contracts

Reference: /docs/DSS_ORGANISM_GUIDE.md#1-the-heart

3.2 The Brain 🧠 - Validators & Analysis

Function: Validate data quality, detect patterns, learn from data

Neural Functions:

  • Pattern Recognition = Detecting design consistency issues
  • Memory = Storing learned rules and patterns
  • Decision-Making = Validation rules and quality gates
  • Learning = Quick wins detection, improvement suggestions

Health Indicators:

  • Validators catching errors early
  • Analysis discovering patterns
  • Smart suggestions for improvements
  • Validators too strict = system constrained
  • Validators too loose = garbage data accepted
  • Analysis finds nothing = system unaware

Design Principles:

  • Validation First: Catch errors at ingestion time
  • No False Positives: Rules must catch real problems
  • Learning: Improve detection over time
  • Transparency: Users understand why validation fails

Reference: /docs/DSS_ORGANISM_GUIDE.md#2-the-brain

3.3 The Digestive System 🍽️ - Ingestion Pipeline

Function: Break down external design information into usable tokens

Digestion Stages:

  1. Intake = Receiving raw design files
  2. Breakdown = Parsing format-specific syntax
  3. Extraction = Pulling out tokens/definitions
  4. Normalization = Converting to standard token format
  5. Absorption = Storing in the system

Health Indicators:

  • Successfully parsing diverse input formats
  • Zero loss of design information
  • Fast processing time
  • Failed parsing = maldigestion
  • Lost data = nutrient malabsorption
  • Slow processing = digestive dysfunction

Design Principles:

  • Format Agnostic: Support CSS, SCSS, JSON, Figma, etc.
  • Zero Data Loss: Never drop design information
  • Normalization: Convert to standard token format immediately
  • Error Recovery: Partial failures don't block entire ingestion

Reference: /docs/DSS_ORGANISM_GUIDE.md#3-the-digestive-system

3.4 The Nervous System 🔌 - APIs & Webhooks

Function: Perceive external world and respond automatically

Neural Pathways:

  • Sensory Input = Figma webhooks detecting changes
  • Response = Automatic sync and update triggers
  • Communication = REST API, MCP interface

Health Indicators:

  • Real-time responsiveness to Figma changes
  • Reliable webhook delivery
  • Available API endpoints
  • Missed webhook events = delayed sync
  • API downtime = external systems blocked
  • Race conditions = data corruption

Design Principles:

  • Real-Time: Respond to changes immediately
  • Reliable: Guarantee event delivery (retries, idempotency)
  • Available: 99.9% uptime for APIs
  • Observable: Log all external interactions

Reference: /docs/DSS_ORGANISM_GUIDE.md#4-the-nervous-system

3.5 The Circulatory System 🩸 - Token Distribution

Function: Distribute tokens throughout the system to where they're needed

Distribution Network:

  • Token → CSS Variables
  • Token → Storybook Documentation
  • Token → Component Generation
  • Token → External Integrations

Design Principles:

  • Consistency: Same token everywhere
  • Traceability: Know where each token goes
  • Performance: Efficient distribution, caching
  • Flexibility: Multiple output formats

Reference: /docs/DSS_ORGANISM_GUIDE.md (distributed throughout docs)


4. Keyboard Accessibility

All interactive elements must be keyboard accessible. Users should be able to navigate and interact with the entire application using only the keyboard.

Guidelines

  • Tabindex Management

    • Use tabindex="0" on all keyboard-accessible elements (buttons, links, inputs, custom components)
    • Use tabindex="-1" for elements that shouldn't be in the tab order but need programmatic focus
    • Never use positive tabindex values (e.g., tabindex="1") - maintain natural DOM order
  • Focus Styling

    • Always implement :focus-visible CSS for keyboard users
    • Ensure 3:1 contrast ratio for focus indicators
    • Use outline or box-shadow, not display/visibility changes
    • Apply consistently across all interactive elements
  • Keyboard Event Handlers

    • Enter/Space: Activate buttons and toggles
    • Escape: Close modals, sidebars, and collapsible panels
    • Arrow Keys: Navigate lists, tabs, and menus
    • Alt+Key: Power user shortcuts for common actions

Web Component Implementation

class MyButton extends HTMLElement {
  static get observedAttributes() {
    return ['disabled', 'tabindex', 'aria-label', 'aria-expanded'];
  }

  setupEventListeners() {
    // Handle Enter/Space for activation
    this.keydownHandler = (e) => {
      if ((e.key === 'Enter' || e.key === ' ') && !this.disabled) {
        e.preventDefault();
        this.shadowRoot.querySelector('button').click();
      }
    };

    this.addEventListener('keydown', this.keydownHandler);
  }

  render() {
    const tabindex = this.disabled ? '-1' : (this.getAttribute('tabindex') || '0');
    // ... delegate tabindex to internal button
  }

  disconnectedCallback() {
    this.removeEventListener('keydown', this.keydownHandler);
  }
}

Reference: /admin-ui/js/components/ds-button.js:79-96


2. ARIA & Screen Reader Support

Screen reader users need semantic information about UI elements, their state, and purpose.

Guidelines

  • Labeling

    • Always use aria-label on icon-only buttons
    • Use aria-label on elements without visible text
    • Example: <button aria-label="Toggle theme">🌙</button>
  • State Indication

    • Use aria-expanded="true|false" for toggles/collapsible elements
    • Use aria-pressed="true|false" for toggle buttons
    • Use aria-invalid="true" on form fields with errors
    • Update ARIA attributes when state changes
  • Relationships

    • Use aria-controls="id" to link controls to their targets
    • Use aria-describedby="id" to link inputs to error messages
    • Use aria-labelledby="id" to link to headings when appropriate
    • Use aria-hidden="true" on decorative elements (SVGs, icons)
  • Semantic Roles

    • Use native HTML elements when possible (button, input, link)
    • Use role="button" only on divs styled as buttons (not ideal)
    • Use role="alert" on error messages that appear dynamically
    • Always prefer semantic HTML over generic divs
  • Error Handling

    • Generate unique IDs for error messages
    • Link errors to inputs: aria-describedby="error-{id}"
    • Use role="alert" so screen readers announce errors
    • Set aria-invalid="true" on the input element

Web Component Implementation

class MyInput extends HTMLElement {
  static get observedAttributes() {
    return ['aria-label', 'aria-invalid', 'aria-describedby', 'error'];
  }

  render() {
    const hasError = !!this.getAttribute('error');
    const errorId = hasError ? `error-${Math.random().toString(36).substr(2, 9)}` : '';
    const ariaInvalid = hasError ? 'aria-invalid="true"' : '';
    const ariaDescribedBy = hasError ? `aria-describedby="${errorId}"` : '';
    const ariaLabel = this.getAttribute('aria-label') || this.label || '';

    this.shadowRoot.innerHTML = `
      <input
        aria-label="${ariaLabel}"
        ${ariaInvalid}
        ${ariaDescribedBy}
      />
      ${hasError ? `<p id="${errorId}" role="alert">${this.getAttribute('error')}</p>` : ''}
    `;
  }
}

Reference: /admin-ui/js/components/ds-input.js:172-240


3. Web Component Lifecycle Management

Memory leaks from accumulated event listeners are a critical performance issue in SPAs. Web Components must properly manage their lifecycle.

Guidelines

  • Connection/Disconnection

    • Implement both connectedCallback() and disconnectedCallback()
    • connectedCallback(): Create shadow DOM, render, attach listeners
    • disconnectedCallback(): Remove all listeners, clean up references
  • Event Listener Storage

    • Store listener references on this for later cleanup
    • Never attach anonymous functions without storing references
    • Example: this.clickHandler = (e) => { ... }
    • Later: element.removeEventListener('click', this.clickHandler)
  • Attribute Observation

    • Implement observedAttributes() static getter
    • Include all attributes that affect rendering: disabled, tabindex, ARIA attributes
    • In attributeChangedCallback(), cleanup old listeners before re-rendering

Implementation Pattern

class MyComponent extends HTMLElement {
  static get observedAttributes() {
    return ['disabled', 'tabindex', 'aria-label'];
  }

  connectedCallback() {
    this.render();
    this.setupEventListeners();
  }

  disconnectedCallback() {
    this.cleanupEventListeners();
  }

  setupEventListeners() {
    // Store references
    this.clickHandler = (e) => { /* ... */ };
    this.focusHandler = (e) => { /* ... */ };

    const button = this.shadowRoot.querySelector('button');
    button.addEventListener('click', this.clickHandler);
    this.addEventListener('focus', this.focusHandler);
  }

  cleanupEventListeners() {
    const button = this.shadowRoot?.querySelector('button');
    if (button && this.clickHandler) {
      button.removeEventListener('click', this.clickHandler);
      delete this.clickHandler;
    }
    if (this.focusHandler) {
      this.removeEventListener('focus', this.focusHandler);
      delete this.focusHandler;
    }
  }
}

Reference: /admin-ui/js/components/ds-button.js:27-113


4. Event Delegation & Listener Accumulation Prevention

High-volume event listeners create memory pressure. Use event delegation and guard flags.

Guidelines

  • Use Document-Level Delegation

    • Instead of: buttons.forEach(b => b.addEventListener('click', handler))
    • Do: document.addEventListener('click', (e) => { const btn = e.target.closest('[data-action]'); ... })
    • Benefit: One listener for N elements, regardless of count
  • Guard Flags

    • Prevent re-attachment on re-renders
    • Check flag before attaching: if (!this.listeners.hasActionListener) { ... }
    • Set flag after attachment: this.listeners.hasActionListener = true;
  • Data-Driven Actions

    • Use data-action attributes instead of inline onclick handlers
    • Router actions through a single switch statement
    • Example: <button data-action="toggle-theme">Toggle</button>

Implementation Pattern

attachEventHandlers() {
  // Guard: only attach once, even if called multiple times
  if (!this.listeners.hasActionListener) {
    document.addEventListener('click', (e) => {
      const btn = e.target.closest('[data-action]');
      if (!btn) return;

      const action = btn.dataset.action;
      switch (action) {
        case 'toggle-theme': this.toggleTheme(); break;
        case 'load-audit': this.loadAuditLog(); break;
        // ... more actions
      }
    });

    this.listeners.hasActionListener = true;
  }
}

Reference: /admin-ui/js/core/app.js:2202-2414


5. Security: No Global State Pollution

Never expose critical classes or functions to window. Always use ES6 module imports.

Guidelines

  • No Window Assignments

    • window.app = app;
    • window.themeManager = themeManager;
    • Use: import app from './core/app.js';
  • Risk Mitigation

    • Malicious/poorly-written third-party scripts can't hijack your code
    • Prevents accidental global namespace pollution
    • Makes code dependencies explicit and traceable
  • Development Debugging

    • If debugging requires window access, check environment first
    • Example: Only expose in development mode
    • Use: if (process.env.NODE_ENV === 'development') { window.debug = {...}; }

Implementation

// ❌ DON'T DO THIS
const app = new App();
window.app = app;

// ✅ DO THIS
const app = new App();
export default app;

// In other files:
import app from './app.js';

Reference: /admin-ui/js/core/app.js (removed window exposure), /admin-ui/index.html:750


6. Security: Sanitize HTML Input

Always sanitize HTML before insertion into the DOM. Use DOMPurify.

Guidelines

  • Never Use Unsafe Insertion

    • element.innerHTML = userInput;
    • element.innerHTML = apiResponse;
    • Use: sanitizeHtml() and setSafeHtml()
  • DOMPurify Configuration

    • Default settings block dangerous attributes (onclick, onerror, etc.)
    • Whitelist only necessary tags and attributes
    • Strip scripts while preserving content
  • Content Sources Requiring Sanitization

    • User input (forms, search, comments)
    • API responses (markdown, rich text, HTML)
    • External data (imported content, integrations)

Implementation

import { setSafeHtml, sanitizeHtml } from './sanitizer.js';

// Safe HTML insertion
const htmlContent = `<h2>${name}</h2><p>${description}</p>`;
setSafeHtml(element, htmlContent);

// Sanitize and retrieve
const clean = sanitizeHtml(userInput);

Reference: /admin-ui/js/core/sanitizer.js, /admin-ui/js/core/app.js:28


7. Non-Invasive Network Monitoring

Never monkey-patch native APIs. Use non-invasive alternatives.

Guidelines

  • Don't Monkey-Patch Global Functions

    • window.fetch = async (...) => { ... }
    • Breaks third-party integrations
    • Causes race conditions
  • Use Platform APIs Instead

    • PerformanceObserver for network monitoring
    • Browser Performance API for metrics
    • Event listeners on window for errors
  • Graceful Degradation

    • Check if API is available: if ('PerformanceObserver' in window)
    • Try/catch for unsupported browsers
    • Continue functionality if monitoring unavailable

Implementation

captureNetworkActivity() {
  if ('PerformanceObserver' in window) {
    try {
      const observer = new PerformanceObserver((list) => {
        for (const entry of list.getEntries()) {
          if (entry.initiatorType === 'fetch' || entry.initiatorType === 'xmlhttprequest') {
            this.log('network', entry.initiatorType, `${entry.name}`, {
              duration: entry.duration,
              transferSize: entry.transferSize
            });
          }
        }
      });
      observer.observe({ entryTypes: ['resource'] });
    } catch (e) {
      // Graceful degradation - network logging won't work
    }
  }
}

Reference: /admin-ui/js/core/browser-logger.js:134-162


8. Focus Management

Maintain user's context by managing focus properly during UI updates.

Guidelines

  • Focus Delegation

    • Web Components should delegate focus to internal focusable element
    • Implement focus() method that focuses internal input/button
  • Focus Restoration

    • Store focused element before UI change
    • Restore focus after update if appropriate
    • Announce focus changes to screen readers
  • Aria-Expanded Updates

    • Update aria-expanded when toggles change state
    • Ensures screen readers announce state changes
    • Example: toggleBtn.setAttribute('aria-expanded', isOpen);

Implementation

class MyComponent extends HTMLElement {
  focus() {
    // Delegate focus to internal input
    this.shadowRoot.querySelector('input')?.focus();
  }

  togglePanel() {
    const isOpen = !this.isOpen;
    this.isOpen = isOpen;

    // Update ARIA state
    this.setAttribute('aria-expanded', isOpen);

    // Restore focus to toggle button after panel opens
    if (isOpen) {
      this.focus();
    }
  }
}

Reference: /admin-ui/js/core/app.js:2495-2502


9. Semantic HTML Over Custom Divs

Use native HTML elements. They provide built-in accessibility.

Guidelines

  • Prefer Native Elements

    • <button> instead of <div role="button">
    • <input> instead of <div contenteditable>
    • <select> instead of custom dropdown
    • <label> instead of span with onclick
  • When Custom Elements Are Necessary

    • Implement proper ARIA roles and attributes
    • Ensure keyboard interaction works identically to native
    • Test with screen readers and keyboard-only navigation
  • Benefits of Native HTML

    • Built-in keyboard support
    • Screen reader integration
    • Mobile device handling
    • Browser compatibility
    • User expectations met

10. Observable Attributes for Web Components

Web Components must expose all relevant attributes in observedAttributes() to respond to changes.

Guidelines

  • Include All State Attributes

    • disabled, aria-label, aria-expanded, aria-pressed
    • tabindex, value, error, variant
    • Any attribute that affects rendering or behavior
  • Cleanup in attributeChangedCallback

    • Remove old listeners before re-rendering
    • Call cleanupEventListeners() first
    • Then call render() and setupEventListeners()
  • Re-render Efficiently

    • Only re-render if shadowRoot has content
    • Check if (this.shadowRoot.innerHTML)
    • Avoid re-rendering on initial connection

Implementation

class MyComponent extends HTMLElement {
  static get observedAttributes() {
    // Include ALL attributes that affect rendering
    return ['disabled', 'tabindex', 'aria-label', 'aria-expanded', 'aria-invalid', 'error'];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (this.shadowRoot.innerHTML && oldValue !== newValue) {
      // Cleanup first
      this.cleanupEventListeners();
      // Then re-render
      this.render();
      this.setupEventListeners();
    }
  }
}

Reference: /admin-ui/js/components/ds-input.js:39-52


11. Logging with Organism Awareness

Use structured logging that helps understand system state and consciousness.

Guidelines

  • Log Categories (Organ Systems)

    • 'heart' - Database operations and data persistence
    • 'brain' - Validation, analysis, and decision making
    • 'nervous' - API calls, webhooks, communication
    • 'digestive' - Data ingestion, parsing, transformation
    • 'endocrine' - Theme system and configuration
    • 'immune' - Validation, error detection, security
  • Log Levels

    • DEBUG - Deep thought, internal analysis
    • INFO - Organism awareness, normal operations
    • WARN - Symptom detection, unusual conditions
    • ERROR - Immune alert, critical threats
  • Structure

    • Always include: timestamp, level, category, message, data
    • Use consistent naming for categories
    • Include relevant IDs (user, session, operation)

Reference: /admin-ui/js/core/logger.js:27-152


12. Error Handling & User Feedback

Provide clear feedback for errors while maintaining security.

Guidelines

  • User-Facing Messages

    • Be specific but not technical: "Unable to save changes" not "500 Internal Server Error"
    • Suggest action: "Please try again" or "Contact support"
    • Announce errors to screen readers with role="alert"
  • Internal Logging

    • Log full error details internally for debugging
    • Include stack traces, request data, timestamps
    • Never expose sensitive information to users
  • Notification Timing

    • Success: 3-5 seconds
    • Warnings: 5-7 seconds
    • Errors: Persistent until user dismisses

Reference: /admin-ui/js/core/messaging.js


Summary: Accessibility Checklist

Before shipping a component, verify:

  • All interactive elements have tabindex="0" or semantic focus
  • All icon buttons have aria-label
  • All toggles/collapsibles have aria-expanded
  • All form errors have aria-invalid and aria-describedby
  • :focus-visible CSS is present for keyboard users
  • Keyboard shortcuts work (Enter, Space, Escape, Arrows)
  • disconnectedCallback() removes all event listeners
  • Event listeners are stored as this.handler for cleanup
  • No HTML is inserted via innerHTML without sanitization
  • No functions/classes exposed to window
  • Decorative SVGs have aria-hidden="true"
  • Error messages have role="alert"
  • Uses semantic HTML where possible
  • Works with keyboard-only navigation
  • Works with screen readers (test with NVDA or JAWS)

References