add fixture-invoicing example, sample-room wrap, kind cluster support
- examples/fixture-invoicing/: FastAPI + Vue + Postgres demo (4-entity invoice fixture)
- cfg/sample/: wraps the fixture (managed.repos points at examples/)
- ctrl/kind-{up,down,status}.sh + per-room k8s render in soleprint/ctrl/k8s/
- build.py: relative repo paths, resilient rmtree, optional k8s render hook
- cfg/.gitignore: stop ignoring sample/ and standalone/ template rooms
Manifests render cleanly but kind cluster has not been run end-to-end yet.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
71
examples/fixture-invoicing/backend/api/invoices.py
Normal file
71
examples/fixture-invoicing/backend/api/invoices.py
Normal file
@@ -0,0 +1,71 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
|
||||
from db import get_session
|
||||
from models import Invoice
|
||||
from schemas import InvoiceDetail, InvoiceIn, InvoiceOut
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("", response_model=list[InvoiceOut])
|
||||
def list_invoices(
|
||||
status: str | None = None,
|
||||
customer_id: int | None = None,
|
||||
session: Session = Depends(get_session),
|
||||
):
|
||||
query = session.query(Invoice).order_by(Invoice.issued_at.desc())
|
||||
if status:
|
||||
query = query.filter(Invoice.status == status)
|
||||
if customer_id:
|
||||
query = query.filter(Invoice.customer_id == customer_id)
|
||||
return query.all()
|
||||
|
||||
|
||||
@router.post("", response_model=InvoiceOut, status_code=201)
|
||||
def create_invoice(payload: InvoiceIn, session: Session = Depends(get_session)):
|
||||
invoice = Invoice(**payload.model_dump())
|
||||
session.add(invoice)
|
||||
session.commit()
|
||||
session.refresh(invoice)
|
||||
return invoice
|
||||
|
||||
|
||||
@router.get("/{invoice_id}", response_model=InvoiceDetail)
|
||||
def get_invoice(invoice_id: int, session: Session = Depends(get_session)):
|
||||
invoice = (
|
||||
session.query(Invoice)
|
||||
.options(
|
||||
joinedload(Invoice.customer),
|
||||
joinedload(Invoice.line_items),
|
||||
joinedload(Invoice.payments),
|
||||
)
|
||||
.filter(Invoice.id == invoice_id)
|
||||
.first()
|
||||
)
|
||||
if not invoice:
|
||||
raise HTTPException(404, "invoice not found")
|
||||
return invoice
|
||||
|
||||
|
||||
@router.put("/{invoice_id}", response_model=InvoiceOut)
|
||||
def update_invoice(
|
||||
invoice_id: int, payload: InvoiceIn, session: Session = Depends(get_session)
|
||||
):
|
||||
invoice = session.get(Invoice, invoice_id)
|
||||
if not invoice:
|
||||
raise HTTPException(404, "invoice not found")
|
||||
for k, v in payload.model_dump().items():
|
||||
setattr(invoice, k, v)
|
||||
session.commit()
|
||||
session.refresh(invoice)
|
||||
return invoice
|
||||
|
||||
|
||||
@router.delete("/{invoice_id}", status_code=204)
|
||||
def delete_invoice(invoice_id: int, session: Session = Depends(get_session)):
|
||||
invoice = session.get(Invoice, invoice_id)
|
||||
if not invoice:
|
||||
raise HTTPException(404, "invoice not found")
|
||||
session.delete(invoice)
|
||||
session.commit()
|
||||
Reference in New Issue
Block a user