Skip to content

api: extract _rowcount(result) helper to dedupe 6x cast(CursorResult[Any], ...) #62

Description

@countercheck

Source: codebase audit, 2026-06-11 (audit finding F8, Tier 3)
Severity: Low
Category: Type hygiene / DRY

Problem

The same six-line type dance is repeated to access `.rowcount` on a SQLAlchemy result:

```python
result = await session.execute(stmt)

psycopg's CursorResult exposes .rowcount, but mypy needs the cast

deleted = cast(CursorResult[Any], result).rowcount or 0
```

Sites in api/survey_engine/service.py: 374, 614, 624, 635, 957, 971.

The `or 0` guards against `None`, but the cast suppresses mypy without explaining why `.rowcount` is Optional. Future refactors might drop the guard.

Suggested approach

Add a one-liner helper somewhere (e.g. `api/db_helpers.py` or near the existing imports):

```python
def rowcount(result: Result[Any]) -> int:
return cast(CursorResult[Any], result).rowcount or 0
```

Replace the six call sites with `rowcount(result)`.

Verification

`uv run mypy api/` should remain clean. No behavior change.

Priority

Nice-to-have, not worth its own PR. Fold into a touch of `service.py` for another reason.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions