from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import List from app.database import get_db from app.models.user import User from app.models.table import Table from app.models.column import Column from app.schemas.table import ( TableCreate, TableRead, TableUpdate, ColumnCreate, ColumnRead, ColumnUpdate, TableDetailRead, ) from app.routers.auth import get_current_user from app.routers.workspaces import check_workspace_access router = APIRouter() def check_table_access(table_id: int, db: Session, user: User) -> Table: """Check if user has access to table.""" table = db.query(Table).filter(Table.id == table_id).first() if not table: raise HTTPException(status_code=404, detail="Table not found") check_workspace_access(table.workspace_id, db, user) return table @router.get("/workspaces/{workspace_id}/tables", response_model=List[TableRead]) def list_tables( workspace_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """List tables in workspace.""" check_workspace_access(workspace_id, db, current_user) return db.query(Table).filter(Table.workspace_id == workspace_id).all() @router.post( "/workspaces/{workspace_id}/tables", response_model=TableRead, status_code=201 ) def create_table( workspace_id: int, data: TableCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Create table in workspace.""" check_workspace_access(workspace_id, db, current_user) table = Table( workspace_id=workspace_id, name=data.name, description=data.description ) db.add(table) db.commit() db.refresh(table) return table @router.get("/tables/{table_id}", response_model=TableDetailRead) def get_table( table_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get table with columns.""" table = check_table_access(table_id, db, current_user) return table @router.put("/tables/{table_id}", response_model=TableRead) def update_table( table_id: int, data: TableUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Update table.""" table = check_table_access(table_id, db, current_user) for key, value in data.model_dump(exclude_unset=True).items(): setattr(table, key, value) db.commit() db.refresh(table) return table @router.delete("/tables/{table_id}") def delete_table( table_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Delete table.""" table = check_table_access(table_id, db, current_user) db.delete(table) db.commit() return {"message": "Table deleted"} @router.post("/tables/{table_id}/columns", response_model=ColumnRead, status_code=201) def add_column( table_id: int, data: ColumnCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Add column to table.""" check_table_access(table_id, db, current_user) column = Column( table_id=table_id, name=data.name, type=data.type, required=data.required, default_value=data.default_value, position=data.position, options=data.options, ) db.add(column) db.commit() db.refresh(column) return column @router.put("/tables/{table_id}/columns/{column_id}", response_model=ColumnRead) def update_column( table_id: int, column_id: int, data: ColumnUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Update column.""" check_table_access(table_id, db, current_user) column = ( db.query(Column) .filter(Column.id == column_id, Column.table_id == table_id) .first() ) if not column: raise HTTPException(status_code=404, detail="Column not found") for key, value in data.model_dump(exclude_unset=True).items(): setattr(column, key, value) db.commit() db.refresh(column) return column @router.delete("/tables/{table_id}/columns/{column_id}") def delete_column( table_id: int, column_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Delete column.""" check_table_access(table_id, db, current_user) column = ( db.query(Column) .filter(Column.id == column_id, Column.table_id == table_id) .first() ) if not column: raise HTTPException(status_code=404, detail="Column not found") db.delete(column) db.commit() return {"message": "Column deleted"}