v1.3 - client and admin scaffolding

This commit is contained in:
2026-04-25 22:51:36 +12:00
parent bc211ffcc8
commit 8cf9bfb441
54 changed files with 8882 additions and 1248 deletions
+38 -12
View File
@@ -2,6 +2,7 @@ from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.orm import Session, selectinload
from app.api.deps import AuthSession, require_client_session
from app.db.session import get_db
from app.models.raw_material import RawMaterial, RawMaterialPriceVersion
from app.schemas.raw_material import (
@@ -33,14 +34,20 @@ def _serialize_price(material: RawMaterial, price: RawMaterialPriceVersion) -> d
@router.get("", response_model=list[RawMaterialRead])
def list_raw_materials(db: Session = Depends(get_db)):
materials = db.scalars(select(RawMaterial).options(selectinload(RawMaterial.price_versions)).order_by(RawMaterial.name)).all()
def list_raw_materials(session: AuthSession = Depends(require_client_session), db: Session = Depends(get_db)):
materials = db.scalars(
select(RawMaterial)
.where(RawMaterial.tenant_id == session.tenant_id)
.options(selectinload(RawMaterial.price_versions))
.order_by(RawMaterial.name)
).all()
return [serialize_raw_material(material) for material in materials]
@router.post("", response_model=RawMaterialRead, status_code=status.HTTP_201_CREATED)
def create_raw_material(payload: RawMaterialCreate, db: Session = Depends(get_db)):
def create_raw_material(payload: RawMaterialCreate, session: AuthSession = Depends(require_client_session), db: Session = Depends(get_db)):
material = RawMaterial(
tenant_id=session.tenant_id,
name=payload.name,
supplier=payload.supplier,
unit_of_measure=payload.unit_of_measure,
@@ -50,6 +57,7 @@ def create_raw_material(payload: RawMaterialCreate, db: Session = Depends(get_db
)
material.price_versions.append(
RawMaterialPriceVersion(
tenant_id=session.tenant_id,
market_value=payload.initial_price.market_value,
waste_percentage=payload.initial_price.waste_percentage,
effective_date=payload.initial_price.effective_date,
@@ -64,9 +72,11 @@ def create_raw_material(payload: RawMaterialCreate, db: Session = Depends(get_db
@router.get("/{raw_material_id}", response_model=RawMaterialRead)
def get_raw_material(raw_material_id: int, db: Session = Depends(get_db)):
def get_raw_material(raw_material_id: int, session: AuthSession = Depends(require_client_session), db: Session = Depends(get_db)):
material = db.scalar(
select(RawMaterial).where(RawMaterial.id == raw_material_id).options(selectinload(RawMaterial.price_versions))
select(RawMaterial)
.where(RawMaterial.id == raw_material_id, RawMaterial.tenant_id == session.tenant_id)
.options(selectinload(RawMaterial.price_versions))
)
if material is None:
raise HTTPException(status_code=404, detail="Raw material not found")
@@ -74,9 +84,16 @@ def get_raw_material(raw_material_id: int, db: Session = Depends(get_db)):
@router.patch("/{raw_material_id}", response_model=RawMaterialRead)
def update_raw_material(raw_material_id: int, payload: RawMaterialUpdate, db: Session = Depends(get_db)):
def update_raw_material(
raw_material_id: int,
payload: RawMaterialUpdate,
session: AuthSession = Depends(require_client_session),
db: Session = Depends(get_db),
):
material = db.scalar(
select(RawMaterial).where(RawMaterial.id == raw_material_id).options(selectinload(RawMaterial.price_versions))
select(RawMaterial)
.where(RawMaterial.id == raw_material_id, RawMaterial.tenant_id == session.tenant_id)
.options(selectinload(RawMaterial.price_versions))
)
if material is None:
raise HTTPException(status_code=404, detail="Raw material not found")
@@ -88,11 +105,17 @@ def update_raw_material(raw_material_id: int, payload: RawMaterialUpdate, db: Se
@router.post("/{raw_material_id}/prices", response_model=RawMaterialPriceVersionRead, status_code=status.HTTP_201_CREATED)
def add_price_version(raw_material_id: int, payload: RawMaterialPriceVersionCreate, db: Session = Depends(get_db)):
material = db.scalar(select(RawMaterial).where(RawMaterial.id == raw_material_id))
def add_price_version(
raw_material_id: int,
payload: RawMaterialPriceVersionCreate,
session: AuthSession = Depends(require_client_session),
db: Session = Depends(get_db),
):
material = db.scalar(select(RawMaterial).where(RawMaterial.id == raw_material_id, RawMaterial.tenant_id == session.tenant_id))
if material is None:
raise HTTPException(status_code=404, detail="Raw material not found")
price = RawMaterialPriceVersion(
tenant_id=session.tenant_id,
raw_material_id=raw_material_id,
market_value=payload.market_value,
waste_percentage=payload.waste_percentage,
@@ -107,13 +130,16 @@ def add_price_version(raw_material_id: int, payload: RawMaterialPriceVersionCrea
@router.get("/{raw_material_id}/price-history", response_model=list[RawMaterialPriceVersionRead])
def get_price_history(raw_material_id: int, db: Session = Depends(get_db)):
material = db.scalar(select(RawMaterial).where(RawMaterial.id == raw_material_id))
def get_price_history(raw_material_id: int, session: AuthSession = Depends(require_client_session), db: Session = Depends(get_db)):
material = db.scalar(select(RawMaterial).where(RawMaterial.id == raw_material_id, RawMaterial.tenant_id == session.tenant_id))
if material is None:
raise HTTPException(status_code=404, detail="Raw material not found")
prices = db.scalars(
select(RawMaterialPriceVersion)
.where(RawMaterialPriceVersion.raw_material_id == raw_material_id)
.where(
RawMaterialPriceVersion.raw_material_id == raw_material_id,
RawMaterialPriceVersion.tenant_id == session.tenant_id,
)
.order_by(RawMaterialPriceVersion.effective_date.desc())
).all()
items = []