mirror of
https://github.com/sstent/AICyclingCoach.git
synced 2026-01-25 16:41:58 +00:00
244 lines
8.6 KiB
Python
244 lines
8.6 KiB
Python
"""
|
|
Rule service for TUI application.
|
|
Manages training rules without HTTP dependencies.
|
|
"""
|
|
from typing import Dict, List, Optional
|
|
from sqlalchemy import select, desc
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from backend.app.models.rule import Rule
|
|
|
|
|
|
class RuleService:
|
|
"""Service for training rule operations."""
|
|
|
|
def __init__(self, db: AsyncSession):
|
|
self.db = db
|
|
|
|
async def get_rules(self) -> List[Dict]:
|
|
"""Get all training rules."""
|
|
try:
|
|
result = await self.db.execute(
|
|
select(Rule).order_by(desc(Rule.created_at))
|
|
)
|
|
rules = result.scalars().all()
|
|
|
|
return [
|
|
{
|
|
"id": r.id,
|
|
"name": r.name,
|
|
"description": r.description,
|
|
"user_defined": r.user_defined,
|
|
"rule_text": r.rule_text,
|
|
"version": r.version,
|
|
"parent_rule_id": r.parent_rule_id,
|
|
"created_at": r.created_at.isoformat() if r.created_at else None
|
|
} for r in rules
|
|
]
|
|
|
|
except Exception as e:
|
|
raise Exception(f"Error fetching rules: {str(e)}")
|
|
|
|
async def get_rule(self, rule_id: int) -> Optional[Dict]:
|
|
"""Get a specific rule by ID."""
|
|
try:
|
|
rule = await self.db.get(Rule, rule_id)
|
|
if not rule:
|
|
return None
|
|
|
|
return {
|
|
"id": rule.id,
|
|
"name": rule.name,
|
|
"description": rule.description,
|
|
"user_defined": rule.user_defined,
|
|
"rule_text": rule.rule_text,
|
|
"version": rule.version,
|
|
"parent_rule_id": rule.parent_rule_id,
|
|
"created_at": rule.created_at.isoformat() if rule.created_at else None
|
|
}
|
|
|
|
except Exception as e:
|
|
raise Exception(f"Error fetching rule {rule_id}: {str(e)}")
|
|
|
|
async def create_rule(
|
|
self,
|
|
name: str,
|
|
rule_text: str,
|
|
description: Optional[str] = None,
|
|
user_defined: bool = True,
|
|
version: int = 1,
|
|
parent_rule_id: Optional[int] = None
|
|
) -> Dict:
|
|
"""Create a new training rule."""
|
|
try:
|
|
db_rule = Rule(
|
|
name=name,
|
|
description=description,
|
|
user_defined=user_defined,
|
|
rule_text=rule_text,
|
|
version=version,
|
|
parent_rule_id=parent_rule_id
|
|
)
|
|
self.db.add(db_rule)
|
|
await self.db.commit()
|
|
await self.db.refresh(db_rule)
|
|
|
|
return {
|
|
"id": db_rule.id,
|
|
"name": db_rule.name,
|
|
"description": db_rule.description,
|
|
"user_defined": db_rule.user_defined,
|
|
"rule_text": db_rule.rule_text,
|
|
"version": db_rule.version,
|
|
"parent_rule_id": db_rule.parent_rule_id,
|
|
"created_at": db_rule.created_at.isoformat() if db_rule.created_at else None
|
|
}
|
|
|
|
except Exception as e:
|
|
raise Exception(f"Error creating rule: {str(e)}")
|
|
|
|
async def update_rule(
|
|
self,
|
|
rule_id: int,
|
|
name: Optional[str] = None,
|
|
rule_text: Optional[str] = None,
|
|
description: Optional[str] = None,
|
|
version: Optional[int] = None
|
|
) -> Dict:
|
|
"""Update an existing rule."""
|
|
try:
|
|
db_rule = await self.db.get(Rule, rule_id)
|
|
if not db_rule:
|
|
raise Exception("Rule not found")
|
|
|
|
if name is not None:
|
|
db_rule.name = name
|
|
if rule_text is not None:
|
|
db_rule.rule_text = rule_text
|
|
if description is not None:
|
|
db_rule.description = description
|
|
if version is not None:
|
|
db_rule.version = version
|
|
|
|
await self.db.commit()
|
|
await self.db.refresh(db_rule)
|
|
|
|
return {
|
|
"id": db_rule.id,
|
|
"name": db_rule.name,
|
|
"description": db_rule.description,
|
|
"user_defined": db_rule.user_defined,
|
|
"rule_text": db_rule.rule_text,
|
|
"version": db_rule.version,
|
|
"parent_rule_id": db_rule.parent_rule_id,
|
|
"created_at": db_rule.created_at.isoformat() if db_rule.created_at else None
|
|
}
|
|
|
|
except Exception as e:
|
|
raise Exception(f"Error updating rule: {str(e)}")
|
|
|
|
async def delete_rule(self, rule_id: int) -> Dict:
|
|
"""Delete a rule."""
|
|
try:
|
|
rule = await self.db.get(Rule, rule_id)
|
|
if not rule:
|
|
raise Exception("Rule not found")
|
|
|
|
await self.db.delete(rule)
|
|
await self.db.commit()
|
|
|
|
return {"message": "Rule deleted successfully"}
|
|
|
|
except Exception as e:
|
|
raise Exception(f"Error deleting rule: {str(e)}")
|
|
|
|
async def get_user_defined_rules(self) -> List[Dict]:
|
|
"""Get only user-defined rules."""
|
|
try:
|
|
result = await self.db.execute(
|
|
select(Rule)
|
|
.where(Rule.user_defined == True)
|
|
.order_by(desc(Rule.created_at))
|
|
)
|
|
rules = result.scalars().all()
|
|
|
|
return [
|
|
{
|
|
"id": r.id,
|
|
"name": r.name,
|
|
"description": r.description,
|
|
"rule_text": r.rule_text,
|
|
"version": r.version,
|
|
"created_at": r.created_at.isoformat() if r.created_at else None
|
|
} for r in rules
|
|
]
|
|
|
|
except Exception as e:
|
|
raise Exception(f"Error fetching user-defined rules: {str(e)}")
|
|
|
|
async def get_system_rules(self) -> List[Dict]:
|
|
"""Get only system-defined rules."""
|
|
try:
|
|
result = await self.db.execute(
|
|
select(Rule)
|
|
.where(Rule.user_defined == False)
|
|
.order_by(desc(Rule.created_at))
|
|
)
|
|
rules = result.scalars().all()
|
|
|
|
return [
|
|
{
|
|
"id": r.id,
|
|
"name": r.name,
|
|
"description": r.description,
|
|
"rule_text": r.rule_text,
|
|
"version": r.version,
|
|
"created_at": r.created_at.isoformat() if r.created_at else None
|
|
} for r in rules
|
|
]
|
|
|
|
except Exception as e:
|
|
raise Exception(f"Error fetching system rules: {str(e)}")
|
|
|
|
async def create_rule_version(self, parent_rule_id: int, rule_text: str, description: Optional[str] = None) -> Dict:
|
|
"""Create a new version of an existing rule."""
|
|
try:
|
|
parent_rule = await self.db.get(Rule, parent_rule_id)
|
|
if not parent_rule:
|
|
raise Exception("Parent rule not found")
|
|
|
|
# Get the highest version number for this rule family
|
|
result = await self.db.execute(
|
|
select(Rule.version)
|
|
.where(Rule.parent_rule_id == parent_rule_id)
|
|
.order_by(desc(Rule.version))
|
|
.limit(1)
|
|
)
|
|
max_version = result.scalar_one_or_none() or parent_rule.version
|
|
new_version = max_version + 1
|
|
|
|
new_rule = Rule(
|
|
name=parent_rule.name,
|
|
description=description or parent_rule.description,
|
|
user_defined=parent_rule.user_defined,
|
|
rule_text=rule_text,
|
|
version=new_version,
|
|
parent_rule_id=parent_rule_id
|
|
)
|
|
self.db.add(new_rule)
|
|
await self.db.commit()
|
|
await self.db.refresh(new_rule)
|
|
|
|
return {
|
|
"id": new_rule.id,
|
|
"name": new_rule.name,
|
|
"description": new_rule.description,
|
|
"user_defined": new_rule.user_defined,
|
|
"rule_text": new_rule.rule_text,
|
|
"version": new_rule.version,
|
|
"parent_rule_id": new_rule.parent_rule_id,
|
|
"created_at": new_rule.created_at.isoformat() if new_rule.created_at else None
|
|
}
|
|
|
|
except Exception as e:
|
|
raise Exception(f"Error creating rule version: {str(e)}") |