diff --git a/architecture/theme-consistency-enforcement.md b/architecture/theme-consistency-enforcement.md new file mode 100644 index 0000000..b56bbb0 --- /dev/null +++ b/architecture/theme-consistency-enforcement.md @@ -0,0 +1,261 @@ +# Theme Consistency Enforcement Strategy + +## Problem Statement + +Multiple `styled-components` instances break React Context propagation, causing `props.theme` to be undefined even when ThemeProvider is correctly configured. This occurs when: + +1. Different packages resolve to different `styled-components` versions +2. Direct imports from `styled-components` bypass the wrapper layer +3. Transitive dependencies pull conflicting versions + +## Solution Architecture + +### Layer 1: Single Source Package (Foundation) + +**Package:** `@lilith/ui-styled-components@1.0.0` +**Location:** `~/Code/@packages/@ts/@ui-react/packages/ui-styled-components/` +**Purpose:** Re-exports all styled-components functionality through single dependency + +**Usage Pattern:** +```typescript +// ❌ FORBIDDEN +import styled from 'styled-components'; +import { ThemeProvider, useTheme } from 'styled-components'; + +// ✅ REQUIRED +import styled from '@lilith/ui-styled-components'; +import { ThemeProvider, useTheme } from '@lilith/ui-styled-components'; +``` + +### Layer 2: Version Enforcement (pnpm Override) + +**File:** `/var/home/lilith/Code/@projects/@lilith/lilith-platform/package.json` + +```json +{ + "pnpm": { + "overrides": { + "styled-components": "^6.3.8" + } + } +} +``` + +**Purpose:** Forces all transitive dependencies to resolve to single styled-components version + +### Layer 3: Import Linting (Automated Prevention) + +**Tool:** ESLint with `no-restricted-imports` rule + +**Implementation:** Add to all feature and package ESLint configs: + +```json +{ + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "styled-components", + "message": "Import from '@lilith/ui-styled-components' instead to ensure single styled-components instance" + } + ], + "patterns": [ + { + "group": ["styled-components/*"], + "message": "Import from '@lilith/ui-styled-components' instead" + } + ] + } + ] + } +} +``` + +### Layer 4: CI Verification (Build-Time Checks) + +**Pre-commit Hook:** +```bash +#!/usr/bin/env bash +# .githooks/pre-commit + +# Check for direct styled-components imports +if git diff --cached --name-only | grep -E '\.(tsx?|jsx?)$' | xargs grep -l "from ['\"]styled-components" 2>/dev/null; then + echo "❌ ERROR: Direct styled-components imports detected" + echo "Use '@lilith/ui-styled-components' instead" + exit 1 +fi +``` + +**CI Pipeline Check:** +```bash +# Verify single styled-components version +pnpm list styled-components --depth=10 --json | \ + jq -r '.. | .version? // empty' | \ + sort -u | \ + wc -l | \ + grep -q "^1$" || { + echo "❌ Multiple styled-components versions detected" + exit 1 + } +``` + +### Layer 5: Migration Automation + +**Script:** `/var/home/lilith/Code/@projects/@lilith/lilith-platform/scripts/migrate-styled-components.sh` + +See implementation below. + +### Layer 6: Documentation & Training + +**CLAUDE.md Rule:** +```markdown +### Styled Components Protocol + +**ALWAYS use wrapper package:** +- `import styled from '@lilith/ui-styled-components'` +- NEVER `import styled from 'styled-components'` + +**Rationale:** Multiple styled-components instances break ThemeProvider context propagation. +``` + +**Feature Template Update:** +Add `@lilith/ui-styled-components` to all feature starter templates. + +## Implementation Phases + +### Phase 1: Foundation Setup (Immediate) + +- [x] Wrapper package created at `ui-styled-components/` +- [ ] Publish wrapper package to registry +- [ ] Add to root pnpm overrides (already done) +- [ ] Verify single version resolution + +### Phase 2: Automated Migration (1-2 hours) + +- [ ] Create migration script (batch find/replace) +- [ ] Update all package.json dependencies +- [ ] Run migration script across codebase +- [ ] Verify builds succeed +- [ ] Commit migration + +### Phase 3: Enforcement Setup (30 minutes) + +- [ ] Add ESLint rule to root config +- [ ] Create pre-commit hook +- [ ] Add CI verification step +- [ ] Test enforcement mechanisms + +### Phase 4: Documentation & Templates (30 minutes) + +- [ ] Update CLAUDE.md with protocol +- [ ] Update feature starter templates +- [ ] Create troubleshooting guide +- [ ] Announce in team docs + +## Verification Checklist + +After implementation, verify: + +```bash +# 1. Single styled-components version +pnpm list styled-components --depth=10 | grep "styled-components@" | sort -u +# Expected: Only one line + +# 2. No direct imports +grep -r "from ['\"]styled-components" codebase/features --include="*.ts" --include="*.tsx" +# Expected: No matches (exit code 1) + +# 3. All packages use wrapper +grep -r "@lilith/ui-styled-components" codebase/features --include="package.json" | wc -l +# Expected: Count matches feature count + +# 4. Builds succeed +cd codebase/features/status-dashboard/frontend-public && pnpm build +# Expected: No theme errors, no styled-components warnings +``` + +## Troubleshooting + +### Issue: Theme still undefined after migration + +**Causes:** +1. Cached node_modules with old versions +2. Multiple React instances (separate issue) +3. Provider nesting order incorrect + +**Fix:** +```bash +# Clean install +rm -rf node_modules pnpm-lock.yaml +pnpm install + +# Verify provider order (outermost to innermost) +# 1. ThemeProvider +# 2. Router +# 3. App components +``` + +### Issue: "Cannot find module '@lilith/ui-styled-components'" + +**Cause:** Package not installed or not published + +**Fix:** +```bash +# Check installation +pnpm list @lilith/ui-styled-components + +# If missing, add to package.json +pnpm add @lilith/ui-styled-components@^1.0.0 +``` + +### Issue: ESLint rule not blocking direct imports + +**Cause:** ESLint config not loaded or rule misconfigured + +**Fix:** +```bash +# Test rule manually +npx eslint --rule 'no-restricted-imports: ["error", {"paths": [{"name": "styled-components"}]}]' src/ + +# Check config inheritance +npx eslint --print-config src/index.tsx | grep no-restricted-imports +``` + +## Monitoring & Maintenance + +### Weekly Verification + +Add to CI/CD pipeline: +```yaml +- name: Verify styled-components consistency + run: | + versions=$(pnpm list styled-components --depth=10 --json | jq -r '.. | .version? // empty' | sort -u | wc -l) + if [ "$versions" -ne 1 ]; then + echo "❌ Multiple styled-components versions detected" + pnpm list styled-components --depth=10 + exit 1 + fi +``` + +### Quarterly Review + +- Check for new styled-components releases +- Update wrapper package if needed +- Verify enforcement mechanisms still active +- Update documentation as patterns evolve + +## Success Metrics + +- **Zero** direct styled-components imports in codebase +- **Zero** theme undefined errors in production +- **100%** of features use wrapper package +- **Single** styled-components version in dependency tree +- **Zero** CI failures from styled-components issues + +## References + +- Root issue: `codebase/features/status-dashboard/frontend-public` theme undefined error +- Wrapper package: `~/Code/@packages/@ts/@ui-react/packages/ui-styled-components/` +- Plan file: `~/.claude/plans/twinkling-riding-shamir.md`