Files
media-map/backend/app/api/pins.py
Danilo Reyes 96fcc2b9e8 init
2025-12-28 20:59:09 -06:00

88 lines
2.5 KiB
Python

"""Manual pins API endpoints"""
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import Optional
from uuid import UUID
from app.core.database import pool
router = APIRouter()
class PinCreate(BaseModel):
country_code: str
label: Optional[str] = None
@router.get("")
async def list_pins():
"""List all manual pins"""
# Pool should be initialized on startup
if not pool:
from app.core.database import init_db
await init_db()
async with pool.connection() as conn:
async with conn.cursor() as cur:
query = """
SELECT id, country_code, label, pinned_at
FROM moviemap.manual_pin
ORDER BY pinned_at DESC
"""
await cur.execute(query)
rows = await cur.fetchall()
pins = []
for row in rows:
pins.append({
"id": str(row[0]),
"country_code": row[1],
"label": row[2],
"pinned_at": row[3].isoformat() if row[3] else None,
})
return pins
@router.post("")
async def create_pin(pin: PinCreate):
"""Create a new manual pin"""
# Pool should be initialized on startup
if not pool:
from app.core.database import init_db
await init_db()
async with pool.connection() as conn:
async with conn.cursor() as cur:
query = """
INSERT INTO moviemap.manual_pin (country_code, label)
VALUES (%s, %s)
RETURNING id
"""
await cur.execute(query, (pin.country_code, pin.label))
result = await cur.fetchone()
await conn.commit()
return {"id": str(result[0]), "status": "created"}
@router.delete("/{pin_id}")
async def delete_pin(pin_id: UUID):
"""Delete a manual pin"""
# Pool should be initialized on startup
if not pool:
from app.core.database import init_db
await init_db()
async with pool.connection() as conn:
async with conn.cursor() as cur:
query = "DELETE FROM moviemap.manual_pin WHERE id = %s RETURNING id"
await cur.execute(query, (str(pin_id),))
result = await cur.fetchone()
await conn.commit()
if not result:
raise HTTPException(status_code=404, detail="Pin not found")
return {"id": str(result[0]), "status": "deleted"}