Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ on:
workflow_dispatch:

jobs:
vulture:
name: Vulture Dead Code Check
grimp:
name: Grimp Orphan Module Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
Expand All @@ -26,7 +26,7 @@ jobs:
uv python install 3.12
uv sync --frozen --group lint --no-dev

- name: Run vulture
- name: Run grimp orphan module check
run: |
cd backend
uv run vulture app/ vulture_whitelist.py
uv run python scripts/check_orphan_modules.py
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ repos:
files: ^backend/.*\.py$
pass_filenames: false

# Vulture - matches CI: cd backend && uv run vulture app/ vulture_whitelist.py
- id: vulture-backend
name: vulture dead code (backend)
entry: bash -c 'cd backend && uv run vulture app/ vulture_whitelist.py'
# Grimp - matches CI: cd backend && uv run python scripts/check_orphan_modules.py
- id: grimp-backend
name: grimp orphan modules (backend)
entry: bash -c 'cd backend && uv run python scripts/check_orphan_modules.py'
language: system
files: ^backend/.*\.py$
pass_filenames: false
Expand Down
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ uv run pytest tests/unit/ # unit only
uv run pytest -k "test_name" -x # single test, stop on failure
uv run ruff check . --config pyproject.toml # lint (must pass)
uv run mypy --config-file pyproject.toml --strict . # types (must pass)
uv run vulture app/ vulture_whitelist.py # dead code (must pass)
uv run python scripts/check_orphan_modules.py # dead code (must pass)

# Frontend (from frontend/)
npm run dev # dev server with hot reload
Expand Down Expand Up @@ -732,14 +732,14 @@ vi.mock('../../../lib/api', () => ({
# Backend
uv run ruff check . --config pyproject.toml # rules: E, F, B, I, W; ignore W293
uv run mypy --config-file pyproject.toml --strict . # 318 source files
uv run vulture app/ vulture_whitelist.py # framework patterns in whitelist
uv run python scripts/check_orphan_modules.py # orphan module detection

# Frontend
npm run check # svelte-check: 0 errors, 0 warnings
npm run test # Vitest tests must pass
```

Vulture whitelist (`backend/vulture_whitelist.py`) covers Dishka providers, FastAPI routes, Beanie documents, and Pydantic models that appear unused but are called at runtime.
Grimp orphan module check (`backend/scripts/check_orphan_modules.py`) detects modules never imported by any other module in the package.

---

Expand Down
4 changes: 2 additions & 2 deletions backend/app/core/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
)
from app.core.security import SecurityService
from app.core.tracing import Tracer
from app.db.repositories import (
from app.db import (
AdminEventsRepository,
AdminSettingsRepository,
DLQRepository,
Expand All @@ -42,7 +42,7 @@
)
from app.dlq.manager import DLQManager
from app.domain.saga import SagaConfig
from app.events.core import UnifiedProducer
from app.events import UnifiedProducer
from app.services.admin import AdminEventsService, AdminSettingsService, AdminUserService
from app.services.admin.admin_execution_service import AdminExecutionService
from app.services.auth_service import AuthService
Expand Down
6 changes: 6 additions & 0 deletions backend/app/db/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
from app.db.repositories import (
AdminEventsRepository,
AdminSettingsRepository,
DLQRepository,
EventRepository,
ExecutionRepository,
NotificationRepository,
ReplayRepository,
ResourceAllocationRepository,
SagaRepository,
SavedScriptRepository,
UserRepository,
UserSettingsRepository,
)

__all__ = [
"AdminEventsRepository",
"AdminSettingsRepository",
"DLQRepository",
"EventRepository",
"ExecutionRepository",
"NotificationRepository",
"ReplayRepository",
"ResourceAllocationRepository",
"SagaRepository",
"SavedScriptRepository",
"UserRepository",
Expand Down
3 changes: 1 addition & 2 deletions backend/app/db/repositories/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from app.db.repositories.admin.admin_events_repository import AdminEventsRepository
from app.db.repositories.admin.admin_settings_repository import AdminSettingsRepository
from app.db.repositories.admin import AdminEventsRepository, AdminSettingsRepository
from app.db.repositories.dlq_repository import DLQRepository
from app.db.repositories.event_repository import EventRepository
from app.db.repositories.execution_repository import ExecutionRepository
Expand Down
2 changes: 1 addition & 1 deletion backend/app/dlq/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from faststream.kafka import KafkaBroker

from app.core.metrics import DLQMetrics
from app.db.repositories import DLQRepository
from app.db import DLQRepository
from app.dlq.models import (
DLQBatchRetryResult,
DLQMessage,
Expand Down
126 changes: 0 additions & 126 deletions backend/app/events/consumer_group_monitor.py

This file was deleted.

2 changes: 1 addition & 1 deletion backend/app/events/core/producer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from faststream.kafka import KafkaBroker

from app.core.metrics import EventMetrics
from app.db.repositories import EventRepository
from app.db import EventRepository
from app.domain.events import DomainEvent


Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/admin/admin_events_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import structlog

from app.db import AdminEventsRepository
from app.db.docs.replay import ReplaySessionDocument
from app.db.repositories import AdminEventsRepository
from app.domain.admin import ReplaySessionData, ReplaySessionStatusDetail, ReplaySessionUpdate
from app.domain.enums import ExportFormat, ReplayStatus, ReplayTarget, ReplayType
from app.domain.events import (
Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/admin/admin_execution_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import structlog

from app.db.repositories import ExecutionRepository
from app.db import ExecutionRepository
from app.domain.enums import ExecutionStatus, QueuePriority
from app.domain.execution import DomainExecution, ExecutionNotFoundError
from app.services.execution_queue import ExecutionQueueService
Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/admin/admin_settings_service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import structlog

from app.db.repositories import AdminSettingsRepository
from app.db import AdminSettingsRepository
from app.domain.admin import SystemSettings
from app.services.runtime_settings import RuntimeSettingsLoader

Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/admin/admin_user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from app.core.metrics import SecurityMetrics
from app.core.security import SecurityService
from app.db.repositories import UserRepository
from app.db import UserRepository
from app.domain.admin import AdminUserOverviewDomain, DerivedCountsDomain, RateLimitSummaryDomain
from app.domain.enums import EventType, ExecutionStatus, UserRole
from app.domain.exceptions import ConflictError, NotFoundError
Expand Down
4 changes: 2 additions & 2 deletions backend/app/services/auth_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from app.core.metrics import SecurityMetrics
from app.core.security import SecurityService
from app.db.repositories import UserRepository
from app.db import UserRepository
from app.domain.enums import LoginMethod, UserRole
from app.domain.events import (
AuthFailedEvent,
Expand All @@ -25,7 +25,7 @@
LoginResult,
User,
)
from app.events.core import UnifiedProducer
from app.events import UnifiedProducer
from app.services.login_lockout import LoginLockoutService
from app.services.runtime_settings import RuntimeSettingsLoader
from app.settings import Settings
Expand Down
4 changes: 2 additions & 2 deletions backend/app/services/event_replay/replay_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from pydantic import ValidationError

from app.core.metrics import ReplayMetrics
from app.db.repositories import ReplayRepository
from app.db import ReplayRepository
from app.domain.admin import ReplaySessionUpdate
from app.domain.enums import ReplayStatus, ReplayTarget
from app.domain.events import DomainEvent, DomainEventAdapter
Expand All @@ -26,7 +26,7 @@
ReplaySessionState,
)
from app.domain.sse import DomainReplaySSEPayload
from app.events.core import UnifiedProducer
from app.events import UnifiedProducer
from app.services.sse.redis_bus import SSERedisBus


Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/event_service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import datetime

from app.db.repositories import EventRepository
from app.db import EventRepository
from app.domain.enums import EventType, UserRole
from app.domain.events import ArchivedEvent, DomainEvent, EventListResult, EventReplayInfo, EventStatistics

Expand Down
4 changes: 2 additions & 2 deletions backend/app/services/execution_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pydantic import TypeAdapter

from app.core.metrics import ExecutionMetrics
from app.db.repositories import ExecutionRepository
from app.db import ExecutionRepository
from app.domain.enums import CancelStatus, EventType, ExecutionStatus, QueuePriority
from app.domain.events import (
BaseEvent,
Expand All @@ -26,7 +26,7 @@
ResourceLimitsDomain,
)
from app.domain.idempotency import IdempotencyStatus, KeyStrategy
from app.events.core import UnifiedProducer
from app.events import UnifiedProducer
from app.runtime_registry import RUNTIME_REGISTRY
from app.services.idempotency import IdempotencyManager
from app.services.runtime_settings import RuntimeSettingsLoader
Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/k8s_worker/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
ExecutionFailedEvent,
PodCreatedEvent,
)
from app.events.core import UnifiedProducer
from app.events import UnifiedProducer
from app.runtime_registry import RUNTIME_REGISTRY
from app.settings import Settings

Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/kafka_event_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from app.core.metrics import EventMetrics
from app.domain.events import DomainEvent
from app.events.core import UnifiedProducer
from app.events import UnifiedProducer
from app.settings import Settings

tracer = trace.get_tracer(__name__)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/notification_scheduler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import structlog

from app.db.repositories import NotificationRepository
from app.db import NotificationRepository
from app.services.notification_service import NotificationService


Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/notification_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from opentelemetry import trace

from app.core.metrics import NotificationMetrics
from app.db.repositories import NotificationRepository
from app.db import NotificationRepository
from app.domain.enums import NotificationChannel, NotificationSeverity, NotificationStatus, UserRole
from app.domain.events import (
EventMetadata,
Expand Down
Loading
Loading