# Code Review Checklist

Apply this checklist to every code change. Items are ordered by priority.

## 1. Comments

- [ ] **No single-line descriptive comments.** Comments that restate what the next line does are bloat. Remove them.
- [ ] Comments exist ONLY for complex algorithms requiring 4-5+ lines of explanation.
- [ ] No commented-out code left in the codebase.
- [ ] No TODO/FIXME without a linked issue or clear action plan.

## 2. Type Safety

- [ ] All public functions and methods have return type annotations.
- [ ] Uses `X | None` syntax, not `Optional[X]`.
- [ ] No `Any` unless genuinely unavoidable (external API boundaries).
- [ ] `TYPE_CHECKING` guard used for annotation-only imports.
- [ ] Pydantic models use proper field types and validators.

## 3. Naming

- [ ] Class names use PascalCase with appropriate domain suffix (*Service, *Resolver, *Action, etc.).
- [ ] Functions and variables use snake_case.
- [ ] Private members prefixed with `_`.
- [ ] Names are self-documenting — no abbreviations unless universally understood (id, url, etc.).
- [ ] Enum members use StrEnum with lowercase string values.

## 4. Error Handling

- [ ] Uses project exception hierarchy (subclasses of `UIRouterError`), not bare `Exception`.
- [ ] Exceptions carry relevant context (scene_id, action_type, field name, etc.).
- [ ] No silently swallowed exceptions (`except: pass`).
- [ ] `logger.exception()` used for error logging (preserves traceback).
- [ ] Error recovery is explicit — either re-raise or handle with clear logic.

## 5. Async Correctness

- [ ] All I/O operations are `async`.
- [ ] No blocking calls inside async functions (sync file I/O, `time.sleep`, etc.).
- [ ] `asyncio.create_task()` wrapped in `try/except RuntimeError` when event loop may not be running.
- [ ] Awaitable checks used when accepting both sync/async callables.

## 6. Class Design

- [ ] Schema/config uses Pydantic `BaseModel`, runtime state uses `@dataclass`.
- [ ] Dependencies injected via constructor, not created internally.
- [ ] No unnecessary inheritance — composition preferred.
- [ ] Mutable Pydantic defaults use `Field(default_factory=...)`.
- [ ] Protocols used for interface contracts, not ABC.

## 7. Imports

- [ ] Absolute imports only (no relative `from ..module`).
- [ ] Three groups: stdlib → third-party → local, separated by blank lines.
- [ ] `TYPE_CHECKING` guard for circular dependency prevention.
- [ ] No unused imports.

## 8. Testing

- [ ] New functionality has corresponding tests.
- [ ] Tests use fixture chain from `conftest.py` — no manual setup duplication.
- [ ] Helper functions (`_make_scene`, `_goto`, etc.) used for test data.
- [ ] Test classes group related tests logically.
- [ ] Test methods have English docstrings describing what is verified.
- [ ] No hardcoded magic values without explanation in test assertions.

## 9. Logging

- [ ] Uses `logger = logging.getLogger(__name__)`, not `print()`.
- [ ] Log calls use `%s` formatting, not f-strings.
- [ ] Appropriate log level: `debug` for flow, `info` for state changes, `warning` for recoverable issues, `error` for failures.
- [ ] Contextual data included in log messages.

## 10. Security & Safety

- [ ] No secrets or credentials in code or config.
- [ ] User input validated at system boundaries.
- [ ] Callback data decoded safely with proper error handling (`CallbackDecodeError`).
- [ ] No unbounded collections (check for max sizes on history, cache, etc.).

## 11. Code Quality

- [ ] No over-engineering — solution matches the actual requirement, nothing more.
- [ ] No premature abstractions — three similar lines are better than one unused helper.
- [ ] No backwards-compatibility shims for removed code.
- [ ] No dead code, unused variables, or unreachable branches.
- [ ] Passes `ruff check` with zero warnings.
