from typing import Optional from fastapi import APIRouter, Query from app.core.security import UserContext from app.core.data_store import DataStore from app.core.document_indexer import DocumentIndexer from app.agent.tools import tool_calculate_cancellation_fee, tool_calculate_service_credit router = APIRouter(prefix="/api/data", tags=["Operational Data"]) data_store_instance: Optional[DataStore] = None indexer_instance: Optional[DocumentIndexer] = None @router.get("/accounts") async def get_accounts( account_id: Optional[str] = Query(None), is_internal: bool = Query(False), role: str = Query("customer") ): ctx = UserContext(account_id=account_id, is_internal=is_internal, role=role) return data_store_instance.get_accounts(ctx) @router.get("/orders") async def get_orders( account_id: Optional[str] = Query(None), is_internal: bool = Query(False), role: str = Query("customer") ): ctx = UserContext(account_id=account_id, is_internal=is_internal, role=role) return data_store_instance.get_orders(ctx, account_id=account_id if not is_internal else None) @router.get("/tickets") async def get_tickets( account_id: Optional[str] = Query(None), is_internal: bool = Query(False), role: str = Query("customer") ): ctx = UserContext(account_id=account_id, is_internal=is_internal, role=role) return data_store_instance.get_tickets(ctx, account_id=account_id if not is_internal else None) @router.get("/documents") async def get_documents( account_id: Optional[str] = Query(None), is_internal: bool = Query(False), role: str = Query("customer") ): ctx = UserContext(account_id=account_id, is_internal=is_internal, role=role) return indexer_instance.get_all_accessible_documents(ctx) @router.get("/compare-contracts") async def compare_contracts(): """ Unique CalQuity Feature: Side-by-side Contract Clause & Precedence Matrix comparison across all accounts. """ return [ { "account_id": "ACCT-001", "account_name": "Northstar Logistics", "plan": "Enterprise", "governing_contract": "05_Northstar_Logistics_Enterprise_Agreement.pdf", "p1_sla": "15 minutes (24x7)", "cancellation_rule": "Fee $0 for ANY BOOKED shipment before pickup (Contract Sec 2 Override)", "service_credit_rule": "SOP v4 applies (Delay >2h, min(500, 10% fee)), capped at INR 5,000/mo", "precedence_notes": "Contract Section 2 waives INR 250 SOP fee. Historical TKT-450 note was agent error." }, { "account_id": "ACCT-002", "account_name": "LumenWorks", "plan": "Growth", "governing_contract": "06_LumenWorks_Service_Agreement.pdf", "p1_sla": "2 business hours (No weekend coverage)", "cancellation_rule": "Standard SOP v4 (No fee <=30m; INR 250 fee >30m)", "service_credit_rule": "Fixed INR 300 credit ONLY if pickup is >4 hours late (Contract Sec 3 Override)", "precedence_notes": "Contract Sec 3 replaces 2-hour SOP threshold with 4-hour threshold. 3-hour delay is ineligible." }, { "account_id": "ACCT-003", "account_name": "Beacon Retail", "plan": "Standard", "governing_contract": "None (Standard Policy Applies)", "p1_sla": "4 business hours", "cancellation_rule": "Standard SOP v4 (No fee <=30m; INR 250 fee >30m)", "service_credit_rule": "Standard SOP v4 (Delay >2h, min(500, 10% fee))", "precedence_notes": "Governed by Support Policy v3 and SOP v4." }, { "account_id": "ACCT-004", "account_name": "Axis Labs", "plan": "Enterprise", "governing_contract": "None (Standard Enterprise Policy Applies)", "p1_sla": "30 minutes (24x7)", "cancellation_rule": "Standard SOP v4 (No fee <=30m; INR 250 fee >30m)", "service_credit_rule": "Standard SOP v4 (Delay >2h, min(500, 10% fee))", "precedence_notes": "Standard Enterprise Plan SLA applies." } ]