Files
ui/_docs/03_implementation/batch_09_report.md
T
Oleksandr Bezdieniezhnykh 23746ec61d [AZ-485] Add Public API barrels + STC-ARCH-01 (F4 close)
Closes architecture baseline finding F4. Every component now exposes
its Public API through `src/<component>/index.ts`; cross-component
imports go through the barrel. `scripts/check-arch-imports.mjs` plus
`STC-ARCH-01` in the static profile enforce the rule; tests in
`tests/architecture_imports.test.ts` cover AC-4/AC-5 + 2 exemption
cases. One F3-pending exemption (`classColors`) is documented in 5
places (barrel, consumer, script, doc, test) to avoid a circular
import.

Phase B cycle 1 batch 1 of 2 (epic AZ-447). Batch 2 is AZ-486
(endpoint builders) — blocked on this commit landing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 10:33:30 +03:00

9.8 KiB
Raw Blame History

Batch Report

Batch: 09 (Phase B cycle 1, batch 1 of 2) Tasks: AZ-485 (Public API barrels + STC-ARCH-01) Date: 2026-05-11 Cycle: Phase B feature cycle, Step 10 — Implement Total complexity: 5 pts Epic: AZ-447 (01-testability-refactoring) Closes: architecture baseline finding F4 (_docs/02_document/architecture_compliance_baseline.md)

Task Results

Task Status Files Modified / Added Tests AC Coverage Issues
AZ-485_refactor_public_api_barrels Done 11 new barrels (src/{api,auth,components,hooks,i18n}/index.ts, src/features/{login,flights,annotations,dataset,admin,settings}/index.ts); 1 new script (scripts/check-arch-imports.mjs); 1 new test (tests/architecture_imports.test.ts); 1 modified runner (scripts/run-tests.shSTC-ARCH-01 wired in); 17 production import sites migrated to barrel paths (App.tsx + every feature page + every src/components/ consumer); 22 test/colocated test import sites migrated; 1 doc (_docs/02_document/module-layout.md) — Layout Rules #3 rewritten, Verification Needed #3 closed, every component's Public API line points to its barrel 4 new architecture tests in tests/architecture_imports.test.ts (AC-4 / AC-5 + 2 exemption cases); fast profile re-baselined from 163 → 167 passes (no regressions) 7 / 7 ACs covered One F3-pending exemption carried forward: src/features/annotations/classColors is imported directly (not through the 06_annotations barrel) to avoid a circular import; documented in the barrel, the consumers, the static check, the module-layout doc, and the new test

AC Test Coverage: All 7 ACs covered

AC Where Profile Status
AC-1 — Every component has a barrel exposing only its Public API src/<component>/index.ts × 11 vs module-layout.md Per-Component Mapping → Public API static (manual cross-check in self-review) PASS — each barrel's re-export list matches the documented Public API line one-for-one; no internal-only symbol leaks
AC-2 — No cross-component deep imports remain in production code scripts/check-arch-imports.mjs scanning src/ static (STC-ARCH-01) PASS — 0 deep imports outside the documented F3 exemption
AC-3 — No cross-component deep imports remain in tests same script scanning tests/ + e2e/ static (STC-ARCH-01) PASS — 0 deep imports outside the documented F3 exemption
AC-4 — Static gate fails on a newly-introduced deep import tests/architecture_imports.test.ts AC-4: FAILS when a deep import... + AC-4: deep imports inside line comments do not trip the gate fast PASS — the synthetic fixture (tests/_arch_fixtures/synthetic_deep_import.ts) flips the script to exit non-zero and emits STC-ARCH-01 — ... on stderr
AC-5 — Static gate passes on the migrated codebase tests/architecture_imports.test.ts AC-5: passes on the migrated codebase + STC-ARCH-01 run in the static profile fast + static PASS — exit code 0, stderr empty
AC-6 — Fast profile remains green bash scripts/run-tests.sh (static + fast) static + fast PASS — 167 / 13 / 0 (baseline was 163 / 13 / 0 + 4 new architecture tests); 0 regressions
AC-7 — module-layout.md reflects the new convention _docs/02_document/module-layout.md Layout Rules #3 + Verification Needed #3 + Conventions table + every component's Public API line manual review PASS — Rule #3 names the barrel as the Public API, names STC-ARCH-01 as the enforcing gate, and the F3-pending exemption is documented inline; Verification Needed #3 marked closed by AZ-485

Design Decisions

  1. Single source of truth for the static checkscripts/check-arch-imports.mjs mirrors the existing scripts/check-banned-deps.mjs pattern (AZ-482). The bash function static_check_no_cross_component_deep_imports in scripts/run-tests.sh is a one-line delegate. The new unit test invokes the script directly with spawnSync, so a regex regression in the script trips the test even if the bash glue still reports PASS.
  2. classColors exemption is structural, not stylistic — Re-exporting classColors symbols through the 06_annotations barrel creates a runtime circular import (AnnotationsPage → DetectionClasses → 06_annotations barrel → AnnotationsPage) that materializes as FALLBACK_CLASS_NAMES === undefined inside DetectionClasses. The exemption is documented in five places (the barrel file, the consumer file, the static-check script's EXEMPT_RE comment, module-layout.md Layout Rule #3, and the architecture test) so it cannot be forgotten when F3 lands.
  3. 10_app-shell intentionally has no barrel — The component is a collection of root-level files (App.tsx, main.tsx, index.css, vite-env.d.ts) never imported as a unit. STC-ARCH-01's component allowlist (api|auth|components|features/[a-z-]+|hooks|i18n) intentionally omits app-shell; the doc records this explicitly.
  4. Test-file deep-import string concatenationtests/architecture_imports.test.ts builds its synthetic offending strings via concatenation ('fr' + 'om', '..' + '/..') so the scanner does not flag the test source itself when it walks tests/. The fixtures created at runtime go under tests/_arch_fixtures/ and are torn down in afterEach.

Code Review Verdict: PASS

Self-review (implement skill Step 9 / 10), applied to the 13 new + 17 production + 22 test + 1 runner + 1 doc + 1 script changes:

  • 0 Critical, 0 High, 0 Medium, 0 Low findings.
  • Scope discipline: every modified file is one of (barrel author, deep-import consumer, static-check author, doc author). The 4 originally-untracked-and-edited test files (annotations_endpoint, destructive_ux, form_hygiene, overlay_membership) are pre-existing committed test files where the only edit is import-path migration.
  • No silent error suppression: check-arch-imports.mjs writes the full hit list to stderr before exiting non-zero; the bash delegate propagates the exit code; run-tests.sh records the failure into the static CSV.
  • Single-responsibility: each barrel re-exports its component's documented Public API only. check-arch-imports.mjs has one job (detect cross-component deep imports). The new test exercises only that script.
  • No new dependencies: check-arch-imports.mjs uses Node stdlib (fs, path, url) only. The architecture test uses Vitest + Node stdlib.
  • Architecture compliance (Phase 7): no layer-direction violations introduced; the only cross-feature edge (07_dataset → 06_annotations for CanvasEditor, F2) is grandfathered exactly as before — CanvasEditor is intentionally re-exported through the 06_annotations barrel so the consumer is barrel-compliant. STC-ARCH-01 confirms no new cyclic dependencies.

Auto-Fix Attempts: 1

One auto-fix loop entered during Phase 3 (test import migration):

  • Symptom: tests/detection_classes.test.tsx failed with TypeError: Cannot read properties of undefined (reading 'map') after FALLBACK_CLASS_NAMES was migrated to import through the 06_annotations barrel.
  • Diagnosis: barrel-induced circular import — AnnotationsPage → DetectionClasses → 06_annotations barrel → AnnotationsPage. The barrel module evaluated before classColors exports were bound, so the symbol resolved to undefined.
  • Fix: remove classColors re-exports from the 06_annotations barrel, document the F3-pending exemption in five places (see Design Decision #2), point the consumer + the test back at the direct path src/features/annotations/classColors.
  • Validation: fast profile back to green; STC-ARCH-01 unit test added an exemption case (AC-4: still PASSES when only the classColors F3-pending exemption is used) so the carve-out is regression-tested.

Stuck Agents: None

No multi-pass investigations beyond the auto-fix above.

Test Run Summary

  • bun run test:fast (via bash scripts/run-tests.sh) — 27 files / 167 passed / 13 skipped / 21.11 s wall (+4 new tests vs Phase A close at 163; 0 regressions).
  • bash scripts/run-tests.sh --static-only — 30 / 30 static checks PASS (added STC-ARCH-01; no regressions in the existing 29).
  • node scripts/check-arch-imports.mjs (direct invocation) — exit 0, stderr empty on the migrated codebase; exit 1 on every synthetic fixture in the architecture test.
  • ReadLints — clean on all 13 new files.
  • git diff --stat — 41 modified + 13 new files; +113 / -99 net lines; mostly mechanical one-line import path edits.

Documented Drifts (cumulative across batch)

Drift Where Spec/AC affected Resolves when
classColors symbols cannot flow through the 06_annotations barrel due to a circular import src/features/annotations/index.ts (export omitted by design); 5 cross-doc mentions F3 (Medium / Architecture) — architecture_compliance_baseline.md F3 moves classColors.ts out of 06_annotations into its own component directory (src/shared/classColors.ts or a dedicated 11_class-colors directory); F3 closes by adding a src/<new-home>/index.ts barrel and removing the STC-ARCH-01 exemption

(No other drifts surfaced.)

Phase B Cycle 1 Status

This is batch 1 of 2 in Phase B cycle 1 (the cycle covers baseline findings F4 + F7 under epic AZ-447). Batch 2 will implement AZ-486 — endpoint builders in src/api/endpoints.ts + STC-ARCH-02 for hardcoded /api/<service>/… paths — which depends on this batch landing first (endpoints ships through the new src/api barrel; Jira "Blocks" link AZ-485 → AZ-486).

Next Batch

AZ-486 (5 pts) — endpoint builders + STC-ARCH-02. Spec already in _docs/02_tasks/todo/AZ-486_refactor_endpoint_builders.md.