# OPS-001C operation API and UI verification

Date: 2026-08-02

Status: `IMPLEMENTED — NOT VERIFIED`. API, real-SQLite HTTP, component and regression checks pass. In-app browser, MariaDB and production checks remain unavailable.

## Verified locally

- Local-auth owner APIs list/detail/cancel/retry operations and list/count/read/dismiss notifications.
- API DTOs omit idempotency keys, lease tokens, provider/model selection, private failure messages and result references.
- Invalid limits fail with 400; missing or cross-owner identifiers return 404; terminal conflicts return 409.
- Two disposable users against isolated SQLite each saw only their own operation. User A received 404 for User B's operation detail/cancel and notification read/dismiss; User A's own detail/cancel/read/dismiss/retry returned 200/204 as appropriate. Anonymous list returned 401.
- `/operations` renders loading, error, empty, progress, cancel, retry, read and dismiss states. A single busy guard prevents overlapping mutations.
- The shell bell uses persistent unread count and routes to `/operations`; reminder count remains independent. Bell and progress controls have accessible names.
- Polling is bounded to 15 seconds while the page is mounted and 60 seconds for the shell unread badge.

## Commands and results

- Focused operation controller/store tests: PASS — 12/12.
- Full backend suite: PASS — 544/544.
- Focused operations/shell component tests: PASS — 3/3.
- Full frontend suite: PASS — 47/47 suites, 156/156 tests.
- `npm run build`: PASS — Next.js compile and TypeScript.
- Isolated API on 5310 with two synthetic users and synthetic rows: PASS — owner and cross-owner matrix above; exact listener stopped.

## Corrected verification issues

- An npm regression command first ran from the repository root and failed because no root `package.json` exists; it was rerun from `job-tracker-ui` and passed.
- An initial runtime inherited the development connection string instead of `Data:Root`. Two exact synthetic accounts/sessions created there were removed, and a zero-count check passed. No unrelated local rows were changed.
- The isolated SQL seed initially used lowercase GUID text, which does not match EF's canonical SQLite GUID parameter representation. Those synthetic rows were replaced with uppercase GUID text before the passing HTTP matrix.
- The generated disposable Data Protection XML key was deleted and is not retained as evidence. The evidence database contains synthetic data only.

## Limitations

The browser administrator policy still denies localhost, so no real browser, responsive, theme, keyboard journey or screenshot is claimed. No MariaDB/production runtime, feature-specific operation producer, restart-during-active-work test or external provider was exercised. No worker or email delivery was enabled.
