init
This commit is contained in:
87
backend/app/api/pins.py
Normal file
87
backend/app/api/pins.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""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"}
|
||||
|
||||
Reference in New Issue
Block a user