---
phase: 16.2-bugsweeper
plan: 03
subsystem: testing
tags: [bugsweeper, sqlite, slint, debugging, http-api, rusqlite]

# Dependency graph
requires:
  - phase: 16.2-01
    provides: BugsweeperBackend trait, HTTP server infrastructure, query_ui bridge
  - phase: 16.2-02
    provides: get_cards, get_property, set_property, invoke_callback implementations
provides:
  - SqliteStore.query_raw: read-only SQL execution with SELECT validation and mutation keyword rejection
  - AppBugsweeperBackend.query_data: arbitrary SELECT queries returning JSON rows
  - AppBugsweeperBackend.get_discovery_state: Slint discovery state via query_ui
  - AppBugsweeperBackend.get_archive_state: per-card archive state from SQLite
  - AppBugsweeperBackend.get_app_config: non-secret config inspection endpoint
  - AppBugsweeperBackend.get_window_info: window diagnostics via query_ui
affects: [bugsweeper-agents, phase-17, phase-18]

# Tech tracking
tech-stack:
  added: []
  patterns: [read-only SQL validation at store level, secret-safe config reporting via has_* booleans]

key-files:
  created: []
  modified:
    - crates/service/src/db/sqlite.rs
    - crates/app/src/main.rs
    - crates/bugsweeper/src/server.rs

key-decisions:
  - "query_raw validates SQL at SqliteStore level: starts_with(SELECT) check + mutation keyword rejection (INSERT/UPDATE/DELETE/DROP/ALTER/CREATE/ATTACH/DETACH)"
  - "AppConfig.shopify_secret_ref is a non-optional String (not Option<String>) — has_shopify_token uses !is_empty() check"
  - "get_archive_state uses read_all_cards then per-card read_archive_state to avoid N+1 at the cost of multiple lock acquisitions — acceptable for debug-only endpoint"
  - "query_data runs directly on HTTP thread (no query_ui needed) since SqliteStore is Arc<Mutex<Connection>> which is Send+Sync"

patterns-established:
  - "Secret-safe config reporting: expose has_X booleans, never actual token values"
  - "query_ui pattern for Slint property reads from HTTP thread: capture Weak<DashboardWindow>, dispatch via bugsweeper::query_ui"

requirements-completed: []

# Metrics
duration: 8min
completed: 2026-03-24
---

# Phase 16.2 Plan 03: Data/State/App Endpoint Implementations Summary

**SQLite read-only query endpoint + discovery/archive/config/window inspection endpoints completing the BugsweeperBackend API surface**

## Performance

- **Duration:** ~8 min
- **Started:** 2026-03-24T11:00:00Z
- **Completed:** 2026-03-24T11:04:03Z
- **Tasks:** 2
- **Files modified:** 3

## Accomplishments
- Added `SqliteStore.query_raw` — validates SELECT-only, rejects mutation keywords, returns `Vec<Vec<(String, String)>>` rows
- Wired `AppBugsweeperBackend.app_config` field so config inspection endpoint works with/without LiveClient
- Implemented all 5 remaining stubs: `query_data`, `get_discovery_state`, `get_archive_state`, `get_app_config`, `get_window_info`
- Agents can now issue arbitrary SELECT queries to verify SQLite state, inspect discovery mode, and diagnose window/config

## Task Commits

Each task was committed atomically:

1. **Task 1: Add query_raw to SqliteStore and extend AppBugsweeperBackend with config field** - `b9de866` (feat)
2. **Task 2: Implement query_data, get_discovery_state, get_archive_state, get_app_config, get_window_info** - `694af3f` (feat)

## Files Created/Modified
- `crates/service/src/db/sqlite.rs` - Added `query_raw` method with SELECT validation and mutation keyword rejection
- `crates/app/src/main.rs` - Added `app_config` field to `AppBugsweeperBackend`; implemented all 5 endpoint stubs; construction site wires `picker_live_config`
- `crates/bugsweeper/src/server.rs` - Bug fix: `&request` -> `&mut request` for `route_request` call (pre-existing compile error)

## Decisions Made
- `query_raw` returns `Vec<Vec<(String, String)>>` (string values) for simplicity — agents can interpret types from context
- `has_shopify_token` uses `!shopify_secret_ref.is_empty()` since that field is a non-optional `String` in `AppConfig`
- `get_archive_state` reads all cards then fetches archive state per-card — debug-only so N+1 risk acceptable
- `get_discovery_state` and `get_window_info` use `query_ui` bridge; `query_data` and `get_archive_state` run directly on HTTP thread

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 1 - Bug] Fixed `server.rs` mutable reference to Request**
- **Found during:** Task 1 verification (`cargo check --features bugsweeper`)
- **Issue:** `route_request` signature requires `&mut Request` but server.rs passed `&request` (immutable reference); this was a pre-existing compile error from Plan 01/02
- **Fix:** Changed `for request in` to `for mut request in` and `&request` to `&mut request`
- **Files modified:** `crates/bugsweeper/src/server.rs`
- **Verification:** `cargo check --features bugsweeper` passes (Finished dev profile)
- **Committed in:** `b9de866` (Task 1 commit)

**2. [Rule 1 - Bug] Plan spec used `Option<String>` for `shopify_secret_ref` but actual type is `String`**
- **Found during:** Task 2 implementation (reading `crates/app/src/config.rs`)
- **Issue:** Plan's `get_app_config` pseudocode used `cfg.shopify_secret_ref.is_some()` but `AppConfig.shopify_secret_ref` is a non-optional `String`
- **Fix:** Changed to `!cfg.shopify_secret_ref.is_empty()` for the `has_shopify_token` boolean
- **Files modified:** `crates/app/src/main.rs`
- **Verification:** `cargo build --features bugsweeper` passes
- **Committed in:** `694af3f` (Task 2 commit)

---

**Total deviations:** 2 auto-fixed (2 bugs)
**Impact on plan:** Both fixes essential for compilation and correctness. No scope creep.

## Issues Encountered
- None beyond the two auto-fixed deviations above.

## User Setup Required
None - no external service configuration required.

## Next Phase Readiness
- All BugsweeperBackend methods now fully implemented
- Agents can: `GET /api/data/query?sql=SELECT...` for direct SQLite inspection, `GET /api/state/discovery` for mode/search state, `GET /api/state/archive` for archive status, `GET /api/app/config` for config diagnostics, `GET /api/app/window` for window state
- Phase 16.2 endpoint implementation complete — ready for agent UAT workflows

---
*Phase: 16.2-bugsweeper*
*Completed: 2026-03-24*
