Før Codex endrer blant annet scorekort

This commit is contained in:
Erol 2026-04-12 10:42:28 +02:00
parent 2630e9a9fa
commit 1e2f79e36b
3 changed files with 56 additions and 5 deletions

View file

@ -117,7 +117,7 @@ def format_row(row):
for key in [
'status_updated_at', 'created_at', 'slope_valid_until',
'membership_updated_at', 'greenfee_updated_at', 'vtg_updated_at'
'membership_updated_at', 'greenfee_updated_at', 'vtg_updated_at', 'footnote_updated_at'
]:
if isinstance(d.get(key), (date, datetime)):
d[key] = d[key].isoformat()
@ -199,6 +199,14 @@ async def queue_scrape_job(job_type: str, facility_ids: List[int], requested_by:
}
async def ensure_facility_columns(conn):
"""Legger til nye facility-kolonner ved behov."""
await conn.execute("""
ALTER TABLE facilities
ADD COLUMN IF NOT EXISTS footnote_updated_at TIMESTAMPTZ
""")
@asynccontextmanager
async def lifespan(app: FastAPI):
# Opprett database-pool ved start
@ -211,6 +219,7 @@ async def lifespan(app: FastAPI):
command_timeout=60
)
async with app.state.pool.acquire() as conn:
await ensure_facility_columns(conn)
await ensure_scrape_jobs_table(conn)
print("✅ Database tilkoblet og pool opprettet")
except Exception as e:
@ -436,7 +445,8 @@ async def update_facility_full(facility_id: int, request: Request):
'vtg_presentasjon', 'vtg_lenke', 'vtg_pris', 'vtg_kursdatoer',
'guest_requirements', 'scrape_method', 'scrape_status_url',
'social_links', 'footnote', 'cooperating_clubs', 'membership_draft', 'membership_updated_at',
'greenfee_url', 'greenfee_draft', 'greenfee_updated_at', 'scrape_status_selector', 'vtg_lenke'
'greenfee_url', 'greenfee_draft', 'greenfee_updated_at', 'scrape_status_selector', 'vtg_lenke',
'footnote_updated_at'
]
update_data = {k: v for k, v in data.items() if k in allowed_fields}
@ -446,11 +456,28 @@ async def update_facility_full(facility_id: int, request: Request):
# 1. OPPDATER ANLEGG (FACILITIES)
if update_data:
if 'footnote' in update_data and 'footnote_updated_at' not in update_data:
existing_footnote = await conn.fetchval(
"SELECT footnote FROM facilities WHERE id = $1",
facility_id
)
incoming_footnote = str(update_data.get('footnote') or '').strip()
current_footnote = str(existing_footnote or '').strip()
if incoming_footnote != current_footnote:
update_data['footnote_updated_at'] = datetime.utcnow() if incoming_footnote else None
set_clauses = []
values = []
# Definer hvilke felt som er datoer i databasen
date_fields = ['membership_updated_at', 'greenfee_updated_at', 'vtg_updated_at', 'status_updated_at']
date_fields = [
'membership_updated_at',
'greenfee_updated_at',
'vtg_updated_at',
'status_updated_at',
'footnote_updated_at'
]
for i, (k, v) in enumerate(update_data.items(), 1):
if isinstance(v, (dict, list)):

View file

@ -3,7 +3,7 @@
import { STATUS_MAP } from "@/config/constants";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { useEffect, useMemo, useState, type CSSProperties } from "react";
type SortMethod = "updated" | "dist" | "alpha";
type Variant = "home" | "catalog";
@ -29,6 +29,8 @@ type Facility = {
vtg_pris?: number | null;
vtg_lenke?: string | null;
vtg_beskrivelse?: string | null;
footnote?: string | null;
footnote_updated_at?: string | null;
status_updated_at?: string | null;
amenities?: unknown;
golfamore_data?: unknown;
@ -237,6 +239,13 @@ const getSearchShellClasses = (variant: Variant) =>
? "rounded-[2rem] bg-[#39443B] px-4 py-5 text-white shadow-2xl sm:px-6 sm:py-7"
: "surface-card rounded-[2rem] px-4 py-5 text-[#112015] sm:px-6 sm:py-7";
const noteClampStyle: CSSProperties = {
display: "-webkit-box",
WebkitBoxOrient: "vertical",
WebkitLineClamp: 3,
overflow: "hidden",
};
export default function FacilitySearch({
initialFacilities,
variant = "catalog",
@ -602,6 +611,20 @@ export default function FacilitySearch({
)}
</div>
{facility.footnote && (
<div className="rounded-[1.35rem] border border-[#FFD9CC] bg-[#FFF7F3] px-4 py-3">
<p className="text-[10px] font-extrabold uppercase tracking-[0.18em] text-[#C94F2D]">
Viktig beskjed
<span className="ml-2 text-[#9A6A5E]">
{formatUpdatedDate(facility.footnote_updated_at || facility.status_updated_at)}
</span>
</p>
<p className="mt-2 text-[15px] italic leading-7 text-[#7B3D2C]" style={noteClampStyle}>
{facility.footnote}
</p>
</div>
)}
<div className="grid grid-cols-2 gap-3 rounded-[1.35rem] bg-[#F7F8F3] p-4">
<div>
<p className="text-[10px] font-extrabold uppercase tracking-[0.18em] text-[#839184]">Oppdatert</p>

View file

@ -125,7 +125,8 @@ export default function HeroSlider({ facilities }: { facilities: Facility[] }) {
<span>TeeOff.no gir deg komplett oversikt over </span>
<Link
href="/golfbaner"
className="font-extrabold text-[#FF5722] transition hover:text-white"
className="font-extrabold transition hover:text-white"
style={{ color: "#FF5722" }}
aria-label="Se alle golfbaner"
>
ALLE