Files
freetable/backend/app/routers/records.py
T

228 lines
6.7 KiB
Python
Raw Normal View History

from fastapi import APIRouter, Depends, HTTPException, Query
2026-06-09 23:33:49 +00:00
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)
2026-06-09 23:33:49 +00:00
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
2026-06-09 23:33:49 +00:00
@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),
):
2026-06-09 23:33:49 +00:00
"""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:
2026-06-09 23:33:49 +00:00
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)
2026-06-09 23:33:49 +00:00
db.commit()
db.refresh(record)
return record
2026-06-09 23:33:49 +00:00
@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),
):
2026-06-09 23:33:49 +00:00
"""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()
)
2026-06-09 23:33:49 +00:00
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