Spaces:
Runtime error
Runtime error
| 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() | |
| 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) | |
| 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 | |
| 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 | |
| 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 | |