from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from typing import List from app.database import get_db from app.models.user import User from app.models.record import Record, CellValue from app.schemas.record import ( RecordCreate, RecordRead, RecordUpdate, RecordDetailRead, BulkRecordOperation, ) from app.routers.auth import get_current_user from app.routers.tables import check_table_access router = APIRouter() @router.get("/tables/{table_id}/records", response_model=List[RecordDetailRead]) def list_records( table_id: int, skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=1000), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """List records (paginated).""" check_table_access(table_id, db, current_user) records = ( db.query(Record) .filter(Record.table_id == table_id) .offset(skip) .limit(limit) .all() ) return records @router.post("/tables/{table_id}/records", response_model=RecordRead, status_code=201) def create_record( table_id: int, data: RecordCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Create record.""" check_table_access(table_id, db, current_user) record = Record( table_id=table_id, created_by=current_user.id, updated_by=current_user.id ) db.add(record) db.flush() # Get record.id # Add cell values if data.cells: for cell in data.cells: cell_value = CellValue( record_id=record.id, column_id=cell.column_id, value=cell.value ) db.add(cell_value) db.commit() db.refresh(record) return record @router.get("/tables/{table_id}/records/{record_id}", response_model=RecordDetailRead) def get_record( table_id: int, record_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get single record.""" check_table_access(table_id, db, current_user) record = ( db.query(Record) .filter(Record.id == record_id, Record.table_id == table_id) .first() ) if not record: raise HTTPException(status_code=404, detail="Record not found") return record @router.put("/tables/{table_id}/records/{record_id}", response_model=RecordRead) def update_record( table_id: int, record_id: int, data: RecordUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Update record.""" check_table_access(table_id, db, current_user) record = ( db.query(Record) .filter(Record.id == record_id, Record.table_id == table_id) .first() ) if not record: raise HTTPException(status_code=404, detail="Record not found") record.updated_by = current_user.id # Update cell values if data.cells: for cell in data.cells: existing = ( db.query(CellValue) .filter( CellValue.record_id == record_id, CellValue.column_id == cell.column_id, ) .first() ) if existing: existing.value = cell.value else: cell_value = CellValue( record_id=record_id, column_id=cell.column_id, value=cell.value ) db.add(cell_value) db.commit() db.refresh(record) return record @router.delete("/tables/{table_id}/records/{record_id}") def delete_record( table_id: int, record_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Delete record.""" check_table_access(table_id, db, current_user) record = ( db.query(Record) .filter(Record.id == record_id, Record.table_id == table_id) .first() ) if not record: raise HTTPException(status_code=404, detail="Record not found") db.delete(record) db.commit() return {"message": "Record deleted"} @router.post("/tables/{table_id}/records/bulk") def bulk_operations( table_id: int, data: BulkRecordOperation, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Bulk create/update records.""" check_table_access(table_id, db, current_user) results = {"created": [], "updated": [], "deleted": 0} # Create if data.create: for record_data in data.create: record = Record( table_id=table_id, created_by=current_user.id, updated_by=current_user.id, ) db.add(record) db.flush() if record_data.cells: for cell in record_data.cells: cell_value = CellValue( record_id=record.id, column_id=cell.column_id, value=cell.value ) db.add(cell_value) results["created"].append(record.id) # Update if data.update: for update_data in data.update: record_id = update_data.get("id") record = ( db.query(Record) .filter(Record.id == record_id, Record.table_id == table_id) .first() ) if record: record.updated_by = current_user.id if update_data.get("cells"): for cell in update_data["cells"]: existing = ( db.query(CellValue) .filter( CellValue.record_id == record_id, CellValue.column_id == cell["column_id"], ) .first() ) if existing: existing.value = cell["value"] else: cell_value = CellValue( record_id=record_id, column_id=cell["column_id"], value=cell["value"], ) db.add(cell_value) results["updated"].append(record_id) # Delete if data.delete: for record_id in data.delete: record = ( db.query(Record) .filter(Record.id == record_id, Record.table_id == table_id) .first() ) if record: db.delete(record) results["deleted"] += 1 db.commit() return results