Skip to content

track residual architecture drift: inline auth sprawl (#8), scattered models (#14), raw fetch in views (#6/#7) #512

Description

@AndriiPasternak31

Context

Surfaced during sprint resolution of #479 (closed as superseded by #430). The stale automated report in #479 hid three real, ongoing architectural drift patterns. Filing them here so they're tracked separately from the false-positives.

This issue is a tracking + scoping ticket — actual fixes will land in follow-up PRs.

Findings (verified 2026-04-26 against commit 81a78f4)

1. Invariant #8 — Inline authorization sprawl (P1, security-adjacent)

The /validate-architecture skill classifies inline-auth sprawl as P0-P1 critical because it scatters security logic across 20+ files instead of in Depends() dependencies.

Evidence:

grep -rE "db\.can_user_|db\.is_system_agent|current_user\.username !=|raise HTTPException\(status_code=403" src/backend/routers/

Returns 85 matches across 20 files. Threshold is 5. Worst offenders:

File Matches
routers/slack.py 14
routers/agent_config.py 13
routers/subscriptions.py, routers/notifications.py 7 each
routers/avatar.py, routers/agents.py, routers/system_views.py, routers/nevermined.py 6 each
(others) 1-4 each

Fix shape: Extract permission patterns into Depends() dependencies in dependencies.py. Replace the 85 inline sites in waves (one router per PR). Reuse the existing AuthorizedAgent, OwnedAgentByName patterns.

2. Invariant #14 — Pydantic models scattered across routers (P2, decaying)

Models should live in models.py, not in routers.

Evidence:

grep -rE "^class \w+\((BaseModel|.*Model)\)" src/backend/routers/

Returns 71 BaseModel classes across 25 router files (was 63/20 in #479's 2026-04-24 run — drift is growing, not stable). Worst offenders:

File Models
routers/settings.py 9
routers/telegram.py 7
routers/git.py 6
routers/voice.py, routers/audit_log.py, routers/sharing.py, routers/messages.py 4 each

Fix shape: Phased migration. Move route-local request/response models into models.py grouped by router (e.g., models.py gets class VoiceStartRequest(...) etc.). Update router imports. ~25 PRs of 2-5 models each.

Target: ≤30 BaseModels in routers within 2 cycles.

3. Invariants #6 / #7 — Raw fetch() and api.* calls in views (P2, decaying)

Views should call Pinia stores, not API directly.

Evidence:

grep -cE "fetch\(|api\.(get|post|put|delete)\(" src/frontend/src/views/*.vue

Returns 14 matches across 5 view files:

File Matches
views/ApiKeys.vue 6
views/AgentDetail.vue 3
views/FileManager.vue 3
views/PublicChat.vue 1
views/ExecutionDetail.vue 1

Fix shape: For each view, extract direct API calls into the matching Pinia store (stores/agents.js, stores/auth.js, etc.). Add store actions, switch view to use them.

Why filed as priority-p1

Invariant #8 is classified P0-P1 by the validator skill itself (security logic scattered = scattered security). Bundling #14 + #6/#7 (P2) into the same tracking issue is a scope choice; the fixes can ship in any order.

Acceptance criteria

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    complexity-lowComplexity: low (board points 1-3)priority-p3Nice-to-havestatus-incubatingIdea under consideration — pre-Todo, not yet greenlit for developmenttheme-devexTheme: DevExtype-refactorCode improvement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions