File size: 3,742 Bytes
ff3c2e9
 
 
 
 
 
 
bf0bce6
 
ff3c2e9
bf0bce6
ff3c2e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b17c735
 
 
 
ff3c2e9
b17c735
ff3c2e9
b17c735
 
 
 
 
 
 
ff3c2e9
 
 
 
 
 
bf0bce6
 
 
 
 
 
 
 
 
 
 
ff3c2e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf0bce6
 
 
 
 
 
ff3c2e9
bf0bce6
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""Problem Desk endpoints. Contract: outreach-frontend/lib/api/problems.ts."""

from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
from sqlalchemy.orm import Session

from app.api.deps import get_current_user, get_db
from app.crud import notifications as crud_notify
from app.crud import problems as crud
from app.models import User
from app.schemas.problem import (
    CreateCommentInput,
    CreateProblemInput,
    ProblemCommentOut,
    ProblemOut,
    UpdateProblemInput,
)

router = APIRouter(tags=["problems"])


def _require(db: Session, problem_id: int):
    problem = crud.get_problem(db, problem_id)
    if problem is None:
        raise HTTPException(status_code=404, detail="Problem not found")
    return problem


@router.get("/problems", response_model=list[ProblemOut])
def list_problems(
    priority: str = Query("all", max_length=60),
    status_filter: str = Query("Open", alias="status", max_length=32),
    # Today's embedded Priority Tracker card, personalized per person (2026-10-14) -- see
    # crud.list_problems_mentioning()'s own docstring. `priority` is ignored on this path (the Today card
    # never offers a priority filter, same as it never offered the full page's status tabs either).
    mentioned_me: bool = Query(False),
    db: Session = Depends(get_db),
    user: User | None = Depends(get_current_user),
):
    if mentioned_me:
        if user is None:
            return []
        return [
            ProblemOut.from_model(p, count)
            for p, count in crud.list_problems_mentioning(db, user.id, status_filter)
        ]
    return [
        ProblemOut.from_model(p, count) for p, count in crud.list_problems(db, priority, status_filter)
    ]


@router.post("/problems", response_model=ProblemOut, status_code=status.HTTP_201_CREATED)
def create_problem(
    payload: CreateProblemInput,
    db: Session = Depends(get_db),
    user: User | None = Depends(get_current_user),
):
    problem = crud.create_problem(db, payload, user)
    crud_notify.notify_mentions(
        db, user, payload.mentions, payload.mention_team,
        text=f"{payload.title}. {payload.description}".strip(), problem_id=problem.id,
    )
    return ProblemOut.from_model(problem, 0)


@router.patch("/problems/{problem_id}", response_model=ProblemOut)
def update_problem(problem_id: int, payload: UpdateProblemInput, db: Session = Depends(get_db)):
    problem = _require(db, problem_id)
    updated = crud.set_status(db, problem, payload.status)
    return ProblemOut.from_model(updated, crud.comment_count(db, problem_id))


@router.delete("/problems/{problem_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_problem(problem_id: int, db: Session = Depends(get_db)):
    crud.delete_problem(db, _require(db, problem_id))
    return Response(status_code=status.HTTP_204_NO_CONTENT)


@router.get("/problems/{problem_id}/comments", response_model=list[ProblemCommentOut])
def list_comments(problem_id: int, db: Session = Depends(get_db)):
    _require(db, problem_id)
    return [ProblemCommentOut.from_model(c) for c in crud.list_comments(db, problem_id)]


@router.post(
    "/problems/{problem_id}/comments",
    response_model=ProblemCommentOut,
    status_code=status.HTTP_201_CREATED,
)
def add_comment(
    problem_id: int,
    payload: CreateCommentInput,
    db: Session = Depends(get_db),
    user: User | None = Depends(get_current_user),
):
    _require(db, problem_id)
    comment = crud.add_comment(db, problem_id, payload, user)
    crud_notify.notify_mentions(
        db, user, payload.mentions, payload.mention_team, text=payload.comment_text, problem_id=problem_id
    )
    return ProblemCommentOut.from_model(comment)