[AZ-511] classColors carve-out to src/class-colors/ (closes F3)

Move src/features/annotations/classColors.ts to its own component directory
src/class-colors/ with a proper barrel; update the 4 consumer imports to go
through the barrel; remove the F3-pending exemption from STC-ARCH-01 and from
the architecture test fixture; clean up the 5 coupled doc/script touchpoints.
Closes baseline finding F3 and retires the 5-coupled-places carry-over surface
logged in LESSONS.md 2026-05-12.

- Add `class-colors` to scripts/check-arch-imports.mjs COMPONENT_DIRS so deep
  imports past the new barrel are caught symmetric to every other component.
- Replace the architecture test "exemption WORKS" fixture with the stronger
  "deep import into class-colors NOW FAILS" assertion (Risk 4 mitigation).
- module-layout.md: Layout Rules + Per-Component Mapping (11_class-colors,
  06_annotations, 03_shared-ui) + Verification Needed #1 + shared/class-colors
  block all updated to reflect the new home.
- 11_class-colors/description.md: Caveats §7 + Module Inventory updated.
- architecture_compliance_baseline.md: F3 marked CLOSED with full pre-resolution
  context preserved (mirrors AZ-485/F4 + AZ-486/F7 pattern); F4 carry-forward
  exemption note retired.
- 04_verification_log.md: open questions #1 + #8 marked RESOLVED.
- Build passes with no circular-import warnings (AC-4); fast suite 231/13
  skipped green (AC-5); static profile green (AC-3 — zero exemptions remain).

Batch report: _docs/03_implementation/batch_14_cycle3_report.md

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-13 03:08:36 +03:00
parent 70fb452805
commit c368f60853
19 changed files with 228 additions and 69 deletions
@@ -0,0 +1,74 @@
# Batch 14 — AZ-511 (classColors carve-out)
**Date**: 2026-05-13
**Cycle**: 3 — autodev Step 10 (Implement), batch 2 of 3 (fixes-first order: AZ-510 ✓ → AZ-511 → AZ-512)
**Tickets**: AZ-511 (Epic AZ-509)
**Verdict**: PASS
---
## Task Results
| Task | Status | Files Modified | Tests | AC Coverage | Issues |
|------|--------|----------------|-------|-------------|--------|
| AZ-511_classcolors_carve_out | Done | 12 files (1 mv, 1 new barrel, 4 consumer imports, 1 06_annotations barrel cleanup, 1 script, 2 tests, 4 doc updates) | 31 files / 231 passed / 13 skipped (full fast suite); static profile PASS; `bun run build` PASS with zero circular-import warnings | 6/6 ACs covered | None |
## AC Test Coverage: 6/6 covered
- AC-1 → `ls src/class-colors/` (`classColors.ts`, `index.ts`); `find src/features/annotations -name classColors.ts` empty
- AC-2 → `rg "from.*classColors" src` (no path-form imports remain)
- AC-3 → `tests/architecture_imports.test.ts` "AC-4: FAILS when a deep import bypasses the class-colors barrel" (replaces the prior exemption-WORKS fixture per Risk 4 mitigation)
- AC-4 → `bun run build` log (built in 3.83s, no circular warnings)
- AC-5 → `bunx vitest run` (231 passed)
- AC-6 → `rg "F3-pending\|physical location pending refactor\|EXCEPT classColors" _docs scripts src` returns nothing
## Code Review Verdict: PASS
- Report: `_docs/03_implementation/reviews/batch_14_review.md`
- 0 findings (Critical / High / Medium / Low)
- Resolved baseline finding **F3** (physical / logical owner split for `classColors.ts`); F4's "carried-forward exemption" note also retired
## Auto-Fix Attempts: 0
## Stuck Agents: 0
---
## Implementation Notes
### Changed Files
**Production code**:
- `src/class-colors/classColors.ts` — moved from `src/features/annotations/classColors.ts` (byte-for-byte; no API change).
- `src/class-colors/index.ts` — new barrel re-exporting `getClassColor`, `getPhotoModeSuffix`, `getClassNameFallback`, `FALLBACK_CLASS_NAMES`.
- `src/components/DetectionClasses.tsx``from '../features/annotations/classColors'``from '../class-colors'`.
- `src/features/annotations/CanvasEditor.tsx``from './classColors'``from '../../class-colors'`.
- `src/features/annotations/AnnotationsSidebar.tsx` — same.
- `src/features/annotations/AnnotationsPage.tsx` — same.
- `src/features/annotations/index.ts` — removed the 7-line "classColors symbols are NOT re-exported here" carry-over comment block.
**Scripts + tests**:
- `scripts/check-arch-imports.mjs``ARCH_IMPORTS_EXEMPT_RE` set to `null` (was the F3 deep-import regex); scanner now skips the exemption branch when null. Added `class-colors` to `COMPONENT_DIRS` so deep imports past the new barrel are caught symmetric to every other component.
- `tests/architecture_imports.test.ts` — replaced the "still PASSES when only the classColors F3-pending exemption is used" fixture with "FAILS when a deep import bypasses the class-colors barrel (AZ-511 regression guard)" — stronger replacement per spec Risk 4 mitigation.
- `tests/detection_classes.test.tsx``import { FALLBACK_CLASS_NAMES } from '../src/features/annotations/classColors'``from '../src/class-colors'`; carry-over comment block removed.
- `scripts/run-tests.sh` — updated the description block of `static_check_no_cross_component_deep_imports` to reflect zero exemptions and the new barrel.
**Documentation**:
- `_docs/02_document/module-layout.md` — Layout Rule #2 (one misplaced module remains: CanvasEditor; class-colors no longer counted), Layout Rule #3 (no exemptions today), Per-Component Mapping for `11_class-colors` (now owns `src/class-colors/**`), `06_annotations` (Owns no longer carves out classColors; Imports from now goes via barrel), `03_shared-ui` (Imports from notes the barrel), `## Shared / Cross-Cutting → shared/class-colors` (marked RESOLVED with back-pointer), Verification Needed #1 (RESOLVED), Verification Needed #3 (no exemption left).
- `_docs/02_document/components/11_class-colors/description.md` — Caveats §7 rewritten ("Physical location: `src/class-colors/`"), Module Inventory updated to list both files at the new home.
- `_docs/02_document/architecture_compliance_baseline.md` — F3 marked CLOSED 2026-05-13 by AZ-511 with full pre-resolution context preserved (mirrors AZ-485 → F4 / AZ-486 → F7 pattern); F4's "Carried-forward exemption" note retired.
- `_docs/02_document/04_verification_log.md` — open questions #1 and #8 marked RESOLVED (adjacent hygiene; the questions were the open-question form of F3 and verification needed #1).
### Resolved Finding
- **F3** (`_docs/02_document/architecture_compliance_baseline.md`): Physical / logical owner split for `classColors.ts` — closed by AZ-511. The 5-coupled-places carry-over surface logged in `_docs/LESSONS.md` 2026-05-12 is fully retired.
### Test Run
- Static profile: PASS (STC-ARCH-01 with no exemptions, STC-ARCH-02 unchanged, all other gates green)
- Fast profile: 31 files / 231 passed / 13 skipped (no test count change vs. AZ-510 baseline — quarantines unchanged)
- Build: `bun run build` succeeded in 3.83s; 198 modules transformed; no circular-import warnings involving class-colors / annotations / DetectionClasses
## Next Batch
**Batch 15 (cycle 3 / batch 3 of 3)** — AZ-512 admin edit detection class. Spec carries a BLOCKING cross-workspace verification at impl time: `admin/` must expose `PATCH /api/admin/classes/{id}`. Will pause at that gate.
@@ -0,0 +1,83 @@
# Code Review Report — Batch 14
**Batch**: AZ-511 (classColors carve-out to `src/class-colors/`)
**Cycle**: 3
**Date**: 2026-05-13
**Verdict**: PASS
---
## Phase 1: Context Loading
- Task spec: `_docs/02_tasks/todo/AZ-511_classcolors_carve_out.md` — physical file move + barrel + remove F3-pending exemption from 5 coupled places (script, arch test, 06_annotations barrel comment, module-layout, 11_class-colors description). Closes baseline finding F3.
- Architecture compliance baseline F3 (open) and the 2026-05-12 LESSONS.md entry "5 coupled places" gave the touchpoint inventory.
- Risk 4 mitigation in spec: replace the "exemption WORKS" fixture with a stronger "no exemption remains for class-colors" assertion.
## Phase 2: Spec Compliance
| AC | Mechanism | Evidence |
|----|-----------|----------|
| AC-1 — file at new location | `git mv src/features/annotations/classColors.ts src/class-colors/classColors.ts`; barrel at `src/class-colors/index.ts` | `ls src/class-colors/` shows both files; `find src/features/annotations -name classColors.ts` returns nothing |
| AC-2 — consumers via barrel | All 4 consumers import from `'../class-colors'` or `'../../class-colors'`: `DetectionClasses.tsx`, `CanvasEditor.tsx`, `AnnotationsSidebar.tsx`, `AnnotationsPage.tsx` | `rg "from.*classColors" src` returns no path-style imports |
| AC-3 — STC-ARCH-01 zero exemptions | `ARCH_IMPORTS_EXEMPT_RE = null` in `scripts/check-arch-imports.mjs`; scanner skips the exemption branch when null; `class-colors` added to `COMPONENT_DIRS` so deep imports into the new component are caught | `node scripts/check-arch-imports.mjs --mode=arch-imports` exits 0; `tests/architecture_imports.test.ts` has new "AC-4: FAILS when a deep import bypasses the class-colors barrel" fixture instead of the exemption-WORKS one |
| AC-4 — build no circular warnings | `bun run build` — 198 modules transformed, built in 3.83s; no "Circular dependency" warnings involving class-colors / annotations / DetectionClasses | Build log inspected; only pre-existing CSS/chunk-size warnings remain |
| AC-5 — full suite green | `bunx vitest run` — 31 files / 231 passed / 13 skipped (quarantines unchanged) | Test output captured |
| AC-6 — docs consistent | `module-layout.md` Layout Rule #2/#3 + Per-Component Mapping (`11_class-colors`, `06_annotations`, `03_shared-ui`) + `## Shared / Cross-Cutting` + Verification Needed #1/#3 updated; `11_class-colors/description.md` Caveats §7 + Module Inventory updated; `architecture_compliance_baseline.md` F3 marked CLOSED with task ref + F4 carry-forward exemption note retired; `06_annotations/index.ts` carry-over comment block removed; `scripts/run-tests.sh` description block updated; `04_verification_log.md` open questions #1 and #8 marked RESOLVED (adjacent hygiene) | `rg "F3-pending\|physical location pending refactor\|EXCEPT classColors" _docs scripts src` returns nothing |
**Constraints**:
- C1 atomic move + import update: single batch / single commit ✓
- C2 directory name kebab-case `src/class-colors/` (not `src/classColors/` or `src/shared/class-colors/`) ✓ — opens neither F6 design nor a camelCase outlier
- C3 barrel re-exports all 4 public symbols (`getClassColor`, `getPhotoModeSuffix`, `getClassNameFallback`, `FALLBACK_CLASS_NAMES`) ✓
- C4 understood the `EXEMPT_RE` shape before editing — replaced with `null` + a guarded `if (ARCH_IMPORTS_EXEMPT_RE && …)` so the scanner stays single-purpose ✓
No spec-gap findings.
## Phase 3: Code Quality
- **SOLID / SRP**: `src/class-colors/classColors.ts` is a pure-function module with one responsibility (class color/name/PhotoMode fallback); barrel `index.ts` is the standard 5-line re-export pattern.
- **No behaviour change**: `classColors.ts` is byte-for-byte identical to the prior file (same palette, same fallback names, same functions). Diff is path-only.
- **Comment cleanup**: the 7-line "classColors symbols are NOT re-exported here" carry-over block was removed from `src/features/annotations/index.ts` — now down to the surviving `CanvasEditor` cross-feature note (still warranted per F2).
- **Test fixture upgrade**: the replacement architecture test asserts the *stronger* contract (deep import into the new component fails), retaining regression coverage instead of just deleting the fixture.
No findings.
## Phase 4: Security Quick-Scan
- No secrets, no SQL, no eval / exec. Pure file move.
- No new external inputs.
No findings.
## Phase 5: Performance
- Bundle composition shifts by one chunk boundary; tree-shaking preserves the same set of exported symbols. Build size dist/assets/index-*.js: 923.59 kB (290.56 kB gzip) — within ±0.05% of pre-change baseline.
No findings.
## Phase 6: Cross-Task Consistency
Single-task batch — N/A.
## Phase 7: Architecture Compliance
| Check | Result |
|-------|--------|
| Layer direction | `src/class-colors/` is Layer 0; consumers in Layer 2 (`03_shared-ui`) and Layer 3 (`06_annotations`) import downward — allowed |
| Public API respect | All 4 consumers go through `src/class-colors/index.ts` barrel; STC-ARCH-01 has zero exemptions |
| New cyclic deps | None — the original concern (re-export through `06_annotations` barrel creates cycle) is structurally gone now that class-colors is its own component |
| Duplicate symbols | None |
| Cross-cutting in component dir | Class-colors is correctly its own component; not buried inside an unrelated feature dir |
`COMPONENT_DIRS` in `scripts/check-arch-imports.mjs` was extended with `class-colors` so future contributors who try to deep-import past the barrel are caught — symmetric to every other component.
### Baseline Delta
| Status | Finding | Notes |
|--------|---------|-------|
| Resolved | F3 — Physical / logical owner split for `classColors.ts` | Marked CLOSED in `architecture_compliance_baseline.md` with this task ref. F4 carry-forward exemption note also retired. |
| Carried over | F2, F5, F6, F8 (others outside this file's scope) | Untouched |
| Newly introduced | (none) | — |
## Verdict
**PASS** — no Critical / High / Medium / Low findings. All 6 ACs covered with explicit evidence; constraints honored; static + fast suites green (231 / 13 skipped); build green with zero circular-import warnings; F3 closed and the 5-coupled-places carry-over surface fully retired.