File size: 3,273 Bytes
7872230 | 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 | from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import func, select
from sqlalchemy.orm import Session
from app.api.dependencies import require_auth
from app.db.session import get_db
from app.models.rule import RuleMaster
from app.schemas.rule import RuleCreate, RuleResponse, RuleStatusUpdate, RuleUpdate
from app.services.audit import rule_to_dict, write_rule_audit
from app.services.rule_repository import RuleRepository
router = APIRouter(prefix="/rules", tags=["Rule Management"], dependencies=[Depends(require_auth)])
repo = RuleRepository()
@router.get("", response_model=list[RuleResponse])
def list_rules(
tenant_id: str | None = None,
product_type: str | None = None,
dealer_id: str | None = None,
rule_type: str | None = None,
is_active: bool | None = Query(default=None),
db: Session = Depends(get_db),
) -> list[RuleMaster]:
return repo.list_rules(db, tenant_id, product_type, dealer_id, rule_type, is_active)
@router.post("", response_model=RuleResponse, status_code=status.HTTP_201_CREATED)
def create_rule(payload: RuleCreate, db: Session = Depends(get_db)) -> RuleMaster:
dealer_filter = (
RuleMaster.dealer_id.is_(None)
if payload.dealer_id is None
else RuleMaster.dealer_id == payload.dealer_id
)
latest_version = db.scalar(
select(func.max(RuleMaster.version)).where(
RuleMaster.rule_code == payload.rule_code,
RuleMaster.tenant_id == payload.tenant_id,
RuleMaster.product_type == payload.product_type,
dealer_filter,
)
)
rule = RuleMaster(**payload.model_dump(), version=(latest_version or 0) + 1)
db.add(rule)
db.flush()
write_rule_audit(db, rule.id, "CREATE", payload.created_by, None, rule_to_dict(rule))
db.commit()
db.refresh(rule)
repo.invalidate(rule.tenant_id, rule.product_type, rule.dealer_id)
return rule
@router.put("/{rule_id}", response_model=RuleResponse)
def update_rule(rule_id: int, payload: RuleUpdate, db: Session = Depends(get_db)) -> RuleMaster:
rule = db.get(RuleMaster, rule_id)
if not rule:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Rule not found")
before = rule_to_dict(rule)
updates = payload.model_dump(exclude_unset=True)
actor = updates.pop("actor", "system")
for field, value in updates.items():
setattr(rule, field, value)
write_rule_audit(db, rule.id, "UPDATE", actor, before, rule_to_dict(rule))
db.commit()
db.refresh(rule)
repo.invalidate(rule.tenant_id, rule.product_type, rule.dealer_id)
return rule
@router.patch("/{rule_id}/status", response_model=RuleResponse)
def update_rule_status(
rule_id: int, payload: RuleStatusUpdate, db: Session = Depends(get_db)
) -> RuleMaster:
rule = db.get(RuleMaster, rule_id)
if not rule:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Rule not found")
before = rule_to_dict(rule)
rule.is_active = payload.is_active
write_rule_audit(db, rule.id, "STATUS_UPDATE", payload.actor, before, rule_to_dict(rule))
db.commit()
db.refresh(rule)
repo.invalidate(rule.tenant_id, rule.product_type, rule.dealer_id)
return rule
|