Nye-TeeOff/kode_eksport_1/backend_main_py.txt

95 lines
No EOL
3.2 KiB
Text

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):
try:
app.state.pool = await asyncpg.create_pool(DB_URL, min_size=5, max_size=20)
print("✅ Database tilkoblet og pool opprettet")
except Exception as e:
print(f"❌ Databasefeil: {e}")
raise e
yield
await app.state.pool.close()
app = FastAPI(title="TeeOff API v2.4", 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)
# 1. Dato-håndtering
for key in ['status_updated_at', 'created_at']:
if isinstance(d.get(key), (date, datetime)):
d[key] = d[key].isoformat()
# 2. Garanter riktige datatyper (Vaskeliste)
list_fields = ['course_statuses', 'courses', 'gallery', 'greenfee', 'faqs', 'shotzoom', 'social_links', 'holes']
dict_fields = ['amenities', 'vtg', 'nsg_data', 'golfamore_data']
for field in list_fields:
if field in d:
if d[field] is None:
d[field] = []
elif isinstance(d[field], str):
try: d[field] = json.loads(d[field])
except: d[field] = []
for field in dict_fields:
if field in d:
if d[field] is None:
d[field] = {}
elif isinstance(d[field], str):
try: d[field] = json.loads(d[field])
except: d[field] = {}
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 != 'finnes_ingen_bane_to'
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', '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)