228 lines
6.7 KiB
Python
228 lines
6.7 KiB
Python
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
|