Datasynk og cache
Hvorfor cache brukes
For å gi raske svar og redusere databasebelastning, bygges en lokal JSON-cache per klubb.
Synkprosess
- Les master-DB (
Clubs-tabell) - Finn alle klubber med DB-tilkobling
- Koble til hver klubbdatabase
- Hent data fra tillatte tabeller
- Rens tomme felt og serialiser verdier
- Skriv cachefil:
cache/<KLUBB>_context.json
Godkjent datakilde-liste til JSON-cache
Dette er fasit for hva som skal hentes til cache i V1-oppsett/drift.
Kilde 1 - Master (hvilke klubber som synkes)
- Database: master-databasen konfigurert via miljøvariabler.
- Tabell:
Clubs. - Felter brukt for synk:
clubFolderdbNamedbUserdbPwd
- Synk skjer kun for rader der
dbNameogdbUserfinnes.
Kilde 2 - Klubbdatabase (tillatt tabelliste)
Kun tabellene under er tillatt i cache-bygging:
ActivitiesActivities_PriceGroupsActivities_PricesContactsCourse_Guide_HoleCoursesCourses_ParCourses_TeesDepartmentsDocumentsFAQFunctionsMembershipsMemberships_VtgNewsPagesPro_RegisterRestaurant_MenuitemsSetup_BasicShop_ProductsStatus_CourseClubStatus_InfoStatusboardTournaments
Filer og mapper i flyten
- Synk alle klubber:
api/sync_worker.py - Synk testklubb (SKI):
api/sync_worker_ski_only.py - Cachemål:
api/cache/{clubFolder}_context.json - Prompt bygger fra cache:
api/app.py
SQL-sporringer i synk (for belastningssjekk)
Denne seksjonen beskriver hvilke SQL-sporringer scriptet faktisk kjører, og hvorfor de normalt ikke skal belaste SQL unodvendig.
1) Master-oppslag av klubber
Kjøres i sync_worker.py før synk starter:
SELECT clubFolder, dbName, dbUser, dbPwd
FROM Clubs
WHERE dbName IS NOT NULL
AND dbUser IS NOT NULL
Kjøres i sync_worker_ski_only.py for testklubb:
SELECT clubFolder, dbName, dbUser, dbPwd
FROM Clubs
WHERE clubFolder = ?
AND dbName IS NOT NULL
AND dbUser IS NOT NULL
Belastning:
- Liten tabell i master-DB.
- Ingen join-operasjoner.
- Lett å indeksere på clubFolder ved behov.
2) Eksistenssjekk per tillatt tabell
For hver tabell i allowlist kjøres en rask metadata-sjekk:
SELECT 1
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = '<table_name>'
Belastning: - Treffer metadata, ikke store datamengder. - Brukes for å unngå feil mot klubber med ulike skjema-versjoner.
3) Datauthenting per tabell (med hard cap)
Når tabellen finnes, hentes et begrenset antall rader:
- Kurs-tabeller (
Course*):
SELECT TOP 300 * FROM <table_name>
- Tidsstyrte innholdstabeller (
News,Activities,Tournaments,Pages,Documents):
SELECT TOP 15 *
FROM <table_name>
ORDER BY 1 DESC
- Øvrige tillatte tabeller:
SELECT TOP 50 * FROM <table_name>
Belastning:
- TOP begrenser lesning og nettverkstrafikk.
- Unngår full tabellscan av store historiske tabeller i normal drift.
Hvorfor dette normalt er skånsomt mot SQL
- Ingen tunge joins i synk-script.
- Hard begrensning på antall rader per tabell.
- Kjøres batch-vis (typisk nattlig), ikke kontinuerlig.
- SKI-only script finnes for trygg testing uten full flerklubb-belastning.
Risiko og anbefalte forbedringer
Følgende punkter er viktige for ekstra trygghet:
ORDER BY 1 DESCer teknisk fallback og kan sortere på feil kolonne i noen tabeller.- Uten eksplisitt dato-kolonne kan gamle rader i verste fall bli valgt som "siste".
SELECT *henter flere kolonner enn nødvendig.
Anbefalt forbedring (neste steg):
- Definer per tabell hvilken dato/versjonskolonne som er fasit for "nyeste".
- Bytt ut
ORDER BY 1 DESCmed eksplisittORDER BY <datofelt> DESC. - Innfør valgfri tidsgrense (for eksempel kun siste 6-12 måneder) for nyheter og aktiviteter.
- Vurder å hente eksplisitt kolonneliste i stedet for
*for de største tabellene.
Datavern og blokkering
Ikke tillatt i cache-kontekst til AI
- Private kontaktfelt utenfor
Setup_Basic, inkludert feltnavn som inneholder:epost,email,mailtelefon,phone,mobil,tlf
Felter som filtreres bort som standard støy/internt
- Feltnavn som inneholder
id date_createdcreated_bymodified_bysortnumboolarchive
Prinsipp
Setup_Basicer unntaket for offisiell klubbkontakt.- Private persondata skal ikke eksponeres i chat-svar.
Regler for ferskeste informasjon (anti-gammel-data)
Målet er å hindre at gamle priser/nyheter får høyere vekt enn fersk status.
Prioritet 1 - Driftsstatus
- Ved spørsmål om banestatus skal
Setup_Basic.course_conditionbrukes som primær sannhet. - Gyldighetsfelt
ccond_validfromogccond_validtoskal tolkes sammen med statusen. - Dersom
News/Pagesmotsier dette, skalcourse_conditionvinne.
Prioritet 2 - Tidsstyrt innhold
- For nyheter, aktiviteter, turneringer, sider og dokumenter brukes et begrenset sett ferske rader i cache.
- Dagens tekniske fallback er
TOP 15medORDER BY 1 DESC.
Prioritet 3 - Stamdata/priser
- Stamdata (kurs, medlemskap, shop, menyer) brukes som faktagrunnlag, men må ikke overstyre prioritet 1 ved konflikt.
- Hvis prisinnhold mangler tydelig gyldighetsdato, skal svar være forsiktige og be om dobbeltsjekk ved tvil.
Anbefalt hard-regel for rekkefølge (for utvikler)
For tabeller med tidsdata skal sortering være eksplisitt etter dato-felt, ikke ORDER BY 1 alene.
Anbefalt sortering i prioritert rekkefølge:
valid_fromellerpublish_from(DESC)publish_date,news_date,event_date(DESC)modified_dateellerupdated_at(DESC)- Primærnøkkel-ID (DESC) kun som siste fallback
Dette skal dokumenteres per tabell før utrulling til flere klubber.
Viktig driftsregel
- Produksjon skal bruke
sync_worker.py(alle klubber) - SKI-only script er kun for lokal test
Driftsfrekvens
Anbefalt:
- Nattlig synk via Scheduled Task
- Manuell synk etter store admin-endringer
Kvalitetskontroll
- Kontroller
last_updatedi cache metadata - Verifiser at kritiske felter finnes (
setup_basic, banestatus)