feat(backend): add FastAPI backend — procurement, inventory domain, Casdoor auth, PM arrival endpoints
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""Quote events — audit timeline. Manual creation is restricted to event_type=note."""
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.db.engine import get_db
|
||||
from app.models.procurement import Quote, QuoteEvent
|
||||
from app.schemas.procurement import NoteEventIn
|
||||
from app.services.expand_service import event_to_dict
|
||||
from app.utils.errors import NotFoundError, ValidationError
|
||||
from app.utils.pagination import paginate, sort_query
|
||||
|
||||
router = APIRouter(prefix="/quotes/{quote_id}/events", tags=["quote-events"])
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def list_events(
|
||||
quote_id,
|
||||
page: int = Query(1, ge=1),
|
||||
page_size: int = Query(20, ge=1, le=100),
|
||||
event_type: str | None = None,
|
||||
sort: str | None = None,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
quote = await db.get(Quote, quote_id)
|
||||
if quote is None:
|
||||
raise NotFoundError("پیشنهاد (استعلام) یافت نشد")
|
||||
stmt = select(QuoteEvent).where(QuoteEvent.quote_id == quote_id)
|
||||
if event_type:
|
||||
stmt = stmt.where(QuoteEvent.event_type == event_type)
|
||||
stmt = sort_query(stmt, QuoteEvent, sort, default="occurred_at") # contract default: ASC
|
||||
items, meta = await paginate(stmt, page, page_size, db)
|
||||
return {"data": [event_to_dict(e) for e in items], "meta": meta}
|
||||
|
||||
|
||||
@router.post("", status_code=201)
|
||||
async def create_event(quote_id, payload: NoteEventIn, db: AsyncSession = Depends(get_db)):
|
||||
quote = await db.get(Quote, quote_id)
|
||||
if quote is None:
|
||||
raise NotFoundError("پیشنهاد (استعلام) یافت نشد")
|
||||
if payload.event_type != "note":
|
||||
raise ValidationError("فقط رویدادهای note به صورت دستی ثبت میشوند", field="event_type")
|
||||
event = QuoteEvent(
|
||||
quote_id=quote.id,
|
||||
event_type="note",
|
||||
payload=payload.payload or {},
|
||||
actor=payload.actor,
|
||||
)
|
||||
db.add(event)
|
||||
await db.flush()
|
||||
return {"data": event_to_dict(event)}
|
||||
Reference in New Issue
Block a user