Archive code-review-fix change and sync specs to main

- Synced 14 capability delta specs to main specs
- Created 6 new main specs: api-authentication, error-boundary, input-validation, security-headers, shared-types
- Updated 8 existing specs with security, validation, and performance requirements
- Archived change to openspec/changes/archive/2026-02-20-code-review-fix/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marko Djordjevic 2026-02-20 08:54:59 +01:00
parent adb93a2d2e
commit 925e7284e3
32 changed files with 691 additions and 4 deletions

View file

@ -1,97 +0,0 @@
## ADDED Requirements
### Requirement: Accessibility on interactive elements
All interactive elements (buttons, dropdowns, modals) SHALL have `aria-label` attributes describing their function. Toggle buttons SHALL use `aria-pressed`. The keyboard shortcuts modal SHALL have `role="dialog"` and `aria-modal="true"`.
#### Scenario: Button has aria-label
- **WHEN** a toolbar button renders
- **THEN** it has an `aria-label` attribute describing its action (e.g., "Draw span annotation")
#### Scenario: Modal has dialog role
- **WHEN** the keyboard shortcuts modal opens
- **THEN** it has `role="dialog"` and `aria-modal="true"`
### Requirement: Focus trapping in modals
Modal dialogs (keyboard shortcuts, confirmation dialogs) SHALL trap focus within the modal while open. Tab and Shift+Tab SHALL cycle through focusable elements within the modal.
#### Scenario: Focus trapped in modal
- **WHEN** a modal is open and the user presses Tab
- **THEN** focus cycles through focusable elements within the modal only
### Requirement: Dark theme on settings pages
The annotation-types and span-label-types settings pages SHALL use theme-aware CSS variables instead of hardcoded light colors. They SHALL render correctly in both light and dark themes.
#### Scenario: Settings page in dark mode
- **WHEN** the theme is set to dark and user navigates to annotation-types page
- **THEN** the page renders with dark background and light text (no hardcoded white backgrounds)
### Requirement: next/font for Google Fonts
The application SHALL use `next/font/google` to load Google Fonts instead of CSS `@import` in `globals.css`. This prevents render-blocking font loading.
#### Scenario: Font loaded via next/font
- **WHEN** the application loads
- **THEN** Google Fonts are loaded via `next/font/google` (not via CSS `@import url()` in globals.css)
### Requirement: Confidence slider debounce
The confidence threshold slider in PredictionPanel SHALL debounce chart re-renders. The slider SHALL update the displayed value immediately but only trigger chart updates after 150ms of inactivity (or on `onPointerUp`).
#### Scenario: Dragging slider does not re-render chart per pixel
- **WHEN** the user drags the confidence slider
- **THEN** the chart re-renders at most once every 150ms (not on every pixel movement)
### Requirement: ChartSelector closes on outside click
The custom chart selector dropdown SHALL close when the user clicks outside of it.
#### Scenario: Click outside closes dropdown
- **WHEN** the chart selector dropdown is open and the user clicks elsewhere on the page
- **THEN** the dropdown closes
### Requirement: Dead code removal
The following dead code SHALL be removed:
- `src/lib/db/migrate.ts` (SQLite migration code)
- `get_db_session()` in `services/ml/app/db.py` (unused session leak)
- Dead filter code (TODO comment, no-op) in `page.tsx`
- Dead `inference*` package reference in `pyproject.toml`
#### Scenario: No dead migration code
- **WHEN** `src/lib/db/migrate.ts` is searched for
- **THEN** the file does not exist
#### Scenario: No unused db session function
- **WHEN** `services/ml/app/db.py` is inspected
- **THEN** `get_db_session()` function is absent
### Requirement: Deprecated Python API replacements
The ML service SHALL replace deprecated Python APIs:
- `@app.on_event("startup")` replaced with lifespan pattern
- `declarative_base()` replaced with `class Base(DeclarativeBase)`
- `datetime.utcnow()` replaced with `datetime.now(datetime.UTC)`
#### Scenario: No deprecated startup event
- **WHEN** `services/ml/app/main.py` is inspected
- **THEN** startup logic uses the FastAPI lifespan pattern (not `@app.on_event`)
#### Scenario: No deprecated utcnow
- **WHEN** `datetime.utcnow()` is searched for in the ML service
- **THEN** zero matches are found (all replaced with `datetime.now(datetime.UTC)`)
### Requirement: Unused import cleanup
Components SHALL not have unused imports. Specifically, `Toolbox.tsx` SHALL remove unused `TrendingUp` and `ChevronUp` imports.
#### Scenario: No unused imports in Toolbox
- **WHEN** `Toolbox.tsx` is inspected
- **THEN** only imported symbols that are used in the component are present
### Requirement: Tooltip component functional or removed
The `ui/tooltip.tsx` component SHALL either be implemented using Radix Tooltip or removed if unused.
#### Scenario: Tooltip is functional
- **WHEN** the Tooltip component is used
- **THEN** it renders an actual tooltip on hover (not a no-op passthrough)
### Requirement: SpanAnnotationList confidence check for zero
The confidence display in SpanAnnotationList SHALL use `!= null` instead of a falsy check, so that a confidence value of `0` is correctly displayed.
#### Scenario: Confidence zero displayed
- **WHEN** a span annotation has confidence value `0`
- **THEN** the list displays "0%" (not hidden as if confidence is absent)