Files
Aegis/backend/app/routers/worklogs.py
T
kitos ec26183e2e refactor(pep8): enforce full PEP8 compliance across backend Python codebase
- ruff.toml: select E/W/F/I/N rules, line-length=120, drop legacy ignores
- Auto-fix: sort 82 import blocks (isort), remove 29 unused imports,
  strip 6 trailing-whitespace blank lines in docstrings
- main.py: move setup_logging and settings imports to top (E402)
- errors.py: noqa N818 on DDD exception names (96 call sites, safe)
- intel_service.py: noqa N817 for universal ET alias
- atomic/elastic/sigma import services: move _MAX_UNCOMPRESSED_SIZE and
  _MAX_ENTRIES to module level (N806)
- compliance_import_service.py: move SAMPLE_CONTROLS / CIS_CONTROLS to
  module level; wrap long description strings (N806 + E501)
- snapshot_service.py: move STATUS_ORDER dict to module level (N806)
- sigma_import_service.py: remove dead dedup_key expression (F841)
- threat_actor_import_service.py: remove dead stix_to_actor expression (F841)
- data_source.py, seed_demo.py, campaign_scheduler_service.py,
  lolbas_import_service.py: wrap lines exceeding 120 chars (E501)
- d3fend_import_service.py: per-file E501 ignore (data file with long strings)

All 439 unit tests pass. ruff check app/ → All checks passed!

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:40:14 +02:00

117 lines
3.5 KiB
Python

"""Worklog router — internal time-tracking records with integrity verification."""
from datetime import datetime
from typing import Optional
from uuid import UUID
from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from app.database import get_db
from app.dependencies.auth import get_current_user, require_any_role
from app.domain.unit_of_work import UnitOfWork
from app.models.user import User
from app.services import worklog_service
router = APIRouter(prefix="/worklogs", tags=["worklogs"])
# ── Schemas ──────────────────────────────────────────────────────────────
class WorklogCreate(BaseModel):
entity_type: str = Field(..., max_length=50)
entity_id: UUID
activity_type: str = Field(..., max_length=100)
started_at: datetime
ended_at: Optional[datetime] = None
duration_seconds: int = Field(..., gt=0)
description: Optional[str] = None
class WorklogOut(BaseModel):
id: UUID
entity_type: str
entity_id: UUID
user_id: UUID
activity_type: str
started_at: datetime
ended_at: Optional[datetime] = None
duration_seconds: int
description: Optional[str] = None
tempo_synced: Optional[datetime] = None
integrity_hash: Optional[str] = None
created_at: datetime
class Config:
from_attributes = True
# ── Endpoints ────────────────────────────────────────────────────────────
@router.post("", response_model=WorklogOut, status_code=201)
def create(
body: WorklogCreate,
db: Session = Depends(get_db),
user: User = Depends(require_any_role("red_tech", "blue_tech", "red_lead", "blue_lead")),
):
"""Create a manually-logged worklog entry."""
with UnitOfWork(db) as uow:
wl = worklog_service.create_worklog(
db,
entity_type=body.entity_type,
entity_id=body.entity_id,
user_id=user.id,
activity_type=body.activity_type,
started_at=body.started_at,
ended_at=body.ended_at,
duration_seconds=body.duration_seconds,
description=body.description,
)
uow.commit()
db.refresh(wl)
return wl
@router.get("", response_model=list[WorklogOut])
def list_all(
entity_type: Optional[str] = None,
entity_id: Optional[UUID] = None,
user_id: Optional[UUID] = None,
db: Session = Depends(get_db),
_user: User = Depends(get_current_user),
):
"""List worklogs with optional filters."""
return worklog_service.list_worklogs(
db,
entity_type=entity_type,
entity_id=entity_id,
user_id=user_id,
)
@router.get("/{worklog_id}", response_model=WorklogOut)
def get_one(
worklog_id: UUID,
db: Session = Depends(get_db),
_user: User = Depends(get_current_user),
):
"""Get a single worklog by ID."""
return worklog_service.get_worklog_or_raise(db, worklog_id)
@router.get("/{worklog_id}/verify")
def verify_integrity(
worklog_id: UUID,
db: Session = Depends(get_db),
_user: User = Depends(get_current_user),
):
"""Check whether a worklog's integrity hash is still valid."""
wl = worklog_service.get_worklog_or_raise(db, worklog_id)
return {
"worklog_id": str(wl.id),
"integrity_valid": worklog_service.verify_worklog_integrity(wl),
}