1from fastapi import APIRouter, HTTPException, Depends
2from typing import List, Optional
3import openai
8from database.models import (
9 Store, StoreCreate, Product, ProductCreate, Transaction, TransactionCreate,
10 Category, CategoryCreate, FinancialHealth, DashboardData, ApiResponse,
11 VoiceProcessRequest, VoiceProcessResponse, ReceiptProcessRequest, ReceiptProcessResponse
12)
13
14router = APIRouter()
15
16# Demo user ID for this prototype
18
19# OpenAI configuration
20openai.api_key = os.getenv('OPENAI_API_KEY')
21
22# Health check
26
27# Store routes
28@router.get("/stores", response_model=ApiResponse)
29async def get_stores(db = Depends(get_db_connection)):
30 try:
38 stores.append(store_data)
39
40 return ApiResponse(success=True, data=stores)
41 except Exception as e:
42 raise HTTPException(status_code=500, detail=str(e))
43
44@router.post("/stores", response_model=ApiResponse)
45async def create_store(store_data: StoreCreate, db = Depends(get_db_connection)):
46 try:
63 # Get the created store
64 store = await get_store_by_id(store_id, db)
65 return ApiResponse(success=True, data=store)
66 except Exception as e:
67 raise HTTPException(status_code=500, detail=str(e))
68
69@router.get("/stores/{store_id}", response_model=ApiResponse)
70async def get_store(store_id: int, db = Depends(get_db_connection)):
71 try:
72 store = await get_store_by_id(store_id, db)
73 return ApiResponse(success=True, data=store)
74 except Exception as e:
75 raise HTTPException(status_code=500, detail=str(e))
76
77# Dashboard data
78@router.get("/stores/{store_id}/dashboard", response_model=ApiResponse)
79async def get_dashboard_data(store_id: int, db = Depends(get_db_connection)):
80 try:
106 }
107
108 return ApiResponse(success=True, data=dashboard_data)
109 except Exception as e:
110 raise HTTPException(status_code=500, detail=str(e))
111
112# Product routes
113@router.get("/stores/{store_id}/products", response_model=ApiResponse)
114async def get_products(store_id: int, db = Depends(get_db_connection)):
115 try:
116 products = await get_products_by_store_id(store_id, db)
117 return ApiResponse(success=True, data=products)
118 except Exception as e:
119 raise HTTPException(status_code=500, detail=str(e))
120
121@router.post("/stores/{store_id}/products", response_model=ApiResponse)
122async def create_product(store_id: int, product_data: ProductCreate, db = Depends(get_db_connection)):
123 try:
145 # Get the created product
146 product = await get_product_by_id(product_id, db)
147 return ApiResponse(success=True, data=product)
148 except Exception as e:
149 raise HTTPException(status_code=500, detail=str(e))
150
151# Transaction routes
152@router.get("/stores/{store_id}/transactions", response_model=ApiResponse)
153async def get_transactions(store_id: int, limit: int = 50, db = Depends(get_db_connection)):
154 try:
155 transactions = await get_transactions_by_store_id(store_id, db, limit)
156 return ApiResponse(success=True, data=transactions)
157 except Exception as e:
158 raise HTTPException(status_code=500, detail=str(e))
159
160@router.post("/stores/{store_id}/transactions", response_model=ApiResponse)
161async def create_transaction(store_id: int, transaction_data: TransactionCreate, db = Depends(get_db_connection)):
162 try:
192 # Get the created transaction
193 transaction = await get_transaction_by_id(transaction_id, db)
194 return ApiResponse(success=True, data=transaction)
195 except Exception as e:
196 raise HTTPException(status_code=500, detail=str(e))
197
198# Voice input processing
199@router.post("/voice/process", response_model=ApiResponse)
200async def process_voice_input(request: VoiceProcessRequest):
201 try:
202 if not openai.api_key:
203 raise HTTPException(status_code=500, detail="OpenAI API key not configured")
204
205 response = openai.ChatCompletion.create(
226 import json
227 parsed_data = json.loads(response_text)
228 return ApiResponse(success=True, data=parsed_data)
229 except json.JSONDecodeError:
230 return ApiResponse(
231 success=True,
232 data={
239
240# Receipt processing with AI
241@router.post("/receipt/process", response_model=ApiResponse)
242async def process_receipt(request: ReceiptProcessRequest):
243 try:
244 if not openai.api_key:
245 raise HTTPException(status_code=500, detail="OpenAI API key not configured")
246
247 response = openai.ChatCompletion.create(
277 parsed_data = json.loads(response_text)
278
279 return ApiResponse(success=True, data=parsed_data)
280 except Exception as e:
281 raise HTTPException(status_code=500, detail=str(e))
282
283# Financial health
284@router.get("/stores/{store_id}/financial-health", response_model=ApiResponse)
285async def get_financial_health(store_id: int, days: int = 30, db = Depends(get_db_connection)):
286 try:
287 health = await calculate_financial_health(store_id, db, days)
288 return ApiResponse(success=True, data=health)
289 except Exception as e:
290 raise HTTPException(status_code=500, detail=str(e))
291
292# Category routes
293@router.get("/stores/{store_id}/categories", response_model=ApiResponse)
294async def get_categories(store_id: int, db = Depends(get_db_connection)):
295 try:
296 categories = await get_categories_by_store_id(store_id, db)
297 return ApiResponse(success=True, data=categories)
298 except Exception as e:
299 raise HTTPException(status_code=500, detail=str(e))
300
301@router.post("/stores/{store_id}/categories", response_model=ApiResponse)
302async def create_category(store_id: int, category_data: CategoryCreate, db = Depends(get_db_connection)):
303 try:
319 # Get the created category
320 category = await get_category_by_id(category_id, db)
321 return ApiResponse(success=True, data=category)
322 except Exception as e:
323 raise HTTPException(status_code=500, detail=str(e))
324
325# Demo data seeding
326@router.post("/demo/seed", response_model=ApiResponse)
327async def seed_demo_data(db = Depends(get_db_connection)):
328 try:
429 await create_transaction(store_id, transaction, db)
430
431 return ApiResponse(
432 success=True,
433 data={"store": store, "categories": categories, "products": products},