Nye-TeeOff/backend/main.py
2026-02-26 09:20:51 +01:00

69 lines
2.8 KiB
Python

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager
import asyncpg
import json
from datetime import date, datetime
DB_URL = "postgresql://teeoff_admin:teeoff_secret_password@db:5432/teeoff"
@asynccontextmanager
async def lifespan(app: FastAPI):
app.state.pool = await asyncpg.create_pool(DB_URL, min_size=5, max_size=20)
yield
await app.state.pool.close()
app = FastAPI(lifespan=lifespan)
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
def format_row(row):
if row is None: return None
d = dict(row)
for key in ['status_updated_at', 'created_at']:
if isinstance(d.get(key), (date, datetime)): d[key] = d[key].isoformat()
# JSONB vask - Mapper direkte mot kolonnene i struktur_dump.txt
json_fields = ['amenities', 'greenfee', 'membership', 'vtg', 'faqs', 'shotzoom', 'translations', 'course_statuses', 'courses', 'gallery', 'nsg_data', 'golfamore_data']
for field in json_fields:
if field in d:
if isinstance(d[field], str):
try: d[field] = json.loads(d[field])
except: pass
if d[field] is None: d[field] = [] if field in ['courses', 'faqs', 'gallery'] else {}
return d
@app.get("/api/facilities")
async def get_facilities():
async with app.state.pool.acquire() as conn:
rows = await conn.fetch("""
SELECT f.*, (
SELECT jsonb_agg(cs) FROM (
SELECT name, status FROM courses
WHERE facility_id = f.id AND status NOT IN ('finnes_ingen_bane_to', 'nedlagt')
ORDER BY is_main_course DESC, id ASC
) cs
) as course_statuses
FROM facilities f ORDER BY f.name ASC
""")
return [format_row(row) for row in rows]
@app.get("/api/facilities/{slug}")
async def get_facility(slug: str):
async with app.state.pool.acquire() as conn:
row = await conn.fetchrow("""
SELECT f.*, (
SELECT jsonb_agg(c_data) FROM (
SELECT c.*, (
SELECT jsonb_agg(h_data ORDER BY h_data.hole_number ASC)
FROM (SELECT * FROM holes WHERE course_id = c.id) h_data
) as holes
FROM courses c
WHERE c.facility_id = f.id
AND (c.is_main_course = true OR (c.status NOT IN ('finnes_ingen_bane_to', 'nedlagt', 'ukjent')))
ORDER BY c.is_main_course DESC, c.id ASC
) c_data
) as courses
FROM facilities f WHERE f.slug = $1
""", slug)
if not row: raise HTTPException(status_code=404)
return format_row(row)