| from __future__ import annotations |
|
|
| from uuid import UUID |
|
|
| from fastapi import APIRouter, Depends, HTTPException |
| from sqlalchemy.orm import Session |
|
|
| from app.core.dependencies import get_current_user |
| from app.database.session import get_db |
| from app.models.user import User |
| from app.models.workspace import Workspace |
| from app.repositories.rule_repository import RuleRepository |
| from app.schemas.rule import RuleCreate, RuleResponse, RuleUpdate |
|
|
|
|
| router = APIRouter( |
| prefix="/rules", |
| tags=["Rules"], |
| ) |
|
|
|
|
| def _verify_workspace_access( |
| db: Session, |
| workspace_id: UUID, |
| user_id: UUID, |
| ) -> Workspace: |
| workspace = ( |
| db.query(Workspace) |
| .filter( |
| Workspace.id == workspace_id, |
| Workspace.created_by == user_id, |
| ) |
| .first() |
| ) |
| if workspace is None: |
| raise HTTPException( |
| status_code=403, |
| detail="You do not have access to this workspace.", |
| ) |
| return workspace |
|
|
|
|
| @router.get("", response_model=list[RuleResponse]) |
| def list_rules( |
| workspace_id: UUID, |
| current_user: User = Depends(get_current_user), |
| db: Session = Depends(get_db), |
| ): |
| _verify_workspace_access(db, workspace_id, current_user.id) |
| repo = RuleRepository(db) |
| rules = repo.list_by_workspace(workspace_id) |
| return [RuleResponse.from_rule(r) for r in rules] |
|
|
|
|
| @router.post("", response_model=RuleResponse, status_code=201) |
| def create_rule( |
| workspace_id: UUID, |
| payload: RuleCreate, |
| current_user: User = Depends(get_current_user), |
| db: Session = Depends(get_db), |
| ): |
| _verify_workspace_access(db, workspace_id, current_user.id) |
| repo = RuleRepository(db) |
|
|
| |
| configuration = {**payload.configuration, "operator": payload.operator} |
|
|
| rule = repo.create( |
| workspace_id=workspace_id, |
| name=payload.name, |
| description=payload.description, |
| rule_type=payload.rule_type, |
| configuration=configuration, |
| enabled=payload.enabled, |
| ) |
| return RuleResponse.from_rule(rule) |
|
|
|
|
| @router.get("/{rule_id}", response_model=RuleResponse) |
| def get_rule( |
| rule_id: UUID, |
| current_user: User = Depends(get_current_user), |
| db: Session = Depends(get_db), |
| ): |
| repo = RuleRepository(db) |
| rule = repo.get(rule_id) |
| if rule is None: |
| raise HTTPException(status_code=404, detail="Rule not found.") |
| _verify_workspace_access(db, rule.workspace_id, current_user.id) |
| return RuleResponse.from_rule(rule) |
|
|
|
|
| @router.patch("/{rule_id}", response_model=RuleResponse) |
| def update_rule( |
| rule_id: UUID, |
| payload: RuleUpdate, |
| current_user: User = Depends(get_current_user), |
| db: Session = Depends(get_db), |
| ): |
| repo = RuleRepository(db) |
| rule = repo.get(rule_id) |
| if rule is None: |
| raise HTTPException(status_code=404, detail="Rule not found.") |
| _verify_workspace_access(db, rule.workspace_id, current_user.id) |
|
|
| update_kwargs = {} |
| if payload.name is not None: |
| update_kwargs["name"] = payload.name |
| if payload.description is not None: |
| update_kwargs["description"] = payload.description |
| if payload.rule_type is not None: |
| update_kwargs["rule_type"] = payload.rule_type |
| if payload.enabled is not None: |
| update_kwargs["enabled"] = payload.enabled |
|
|
| |
| if payload.operator is not None or payload.configuration is not None: |
| current_config = dict(rule.configuration or {}) |
| if payload.configuration is not None: |
| current_config.update(payload.configuration) |
| if payload.operator is not None: |
| current_config["operator"] = payload.operator |
| update_kwargs["configuration"] = current_config |
|
|
| if update_kwargs: |
| rule = repo.update(rule, **update_kwargs) |
|
|
| return RuleResponse.from_rule(rule) |
|
|
|
|
| @router.post("/{rule_id}/enable", response_model=RuleResponse) |
| def enable_rule( |
| rule_id: UUID, |
| current_user: User = Depends(get_current_user), |
| db: Session = Depends(get_db), |
| ): |
| repo = RuleRepository(db) |
| rule = repo.get(rule_id) |
| if rule is None: |
| raise HTTPException(status_code=404, detail="Rule not found.") |
| _verify_workspace_access(db, rule.workspace_id, current_user.id) |
| rule = repo.update(rule, enabled=True) |
| return RuleResponse.from_rule(rule) |
|
|
|
|
| @router.post("/{rule_id}/disable", response_model=RuleResponse) |
| def disable_rule( |
| rule_id: UUID, |
| current_user: User = Depends(get_current_user), |
| db: Session = Depends(get_db), |
| ): |
| repo = RuleRepository(db) |
| rule = repo.get(rule_id) |
| if rule is None: |
| raise HTTPException(status_code=404, detail="Rule not found.") |
| _verify_workspace_access(db, rule.workspace_id, current_user.id) |
| rule = repo.update(rule, enabled=False) |
| return RuleResponse.from_rule(rule) |
|
|
|
|
| @router.delete("/{rule_id}", status_code=204) |
| def delete_rule( |
| rule_id: UUID, |
| current_user: User = Depends(get_current_user), |
| db: Session = Depends(get_db), |
| ): |
| repo = RuleRepository(db) |
| rule = repo.get(rule_id) |
| if rule is None: |
| raise HTTPException(status_code=404, detail="Rule not found.") |
| _verify_workspace_access(db, rule.workspace_id, current_user.id) |
| repo.delete(rule) |
|
|