#heading[ERD]

In dit hoofdstuk wordt het Entity-Relationship Diagram (ERD) van de PostgreSQL-database toegelicht. Het ERD is automatisch gegenereerd op basis van het Drizzle-schema (`src/lib/server/db/schema.ts`) en is als `erd.svg` toegevoegd aan de repository.

#figure(
  image("../erd.svg"),
  caption: [Globale ERD van de Serengo-database]
)

De database is ontworpen rond een aantal kernentiteiten die samen het sociale, locatie-gebaseerde karakter van Serengo ondersteunen.

== Kernentiteiten

De belangrijkste tabellen zijn:

- *users* – bevat gebruikersaccounts, inclusief referenties naar authenticatiegegevens (Lucia)[@lucia-docs] en profielinformatie.
- *sessions* – beheert actieve sessies voor gebruikers.
- *oauth_accounts* – slaat externe OAuth-accounts op (zoals Google) die aan een user gekoppeld zijn.
- *locations* – beschrijft gedeelde locaties met o.a. coördinaten, naam en type.
- *finds* – posts die aan een locatie gekoppeld zijn, met titel, beschrijving, privacy-instelling en metadata.
- *media* (impliciet in het schema afhankelijk van de definitie) – verwijzingen naar geüploade afbeeldingen en video's in Cloudflare R2.
- *likes* – registreren welke gebruiker welke find leuk vindt.
- *comments* – reacties van gebruikers bij finds.
- *friendships* – vriendschapsrelaties en hun status (bijv. pending, accepted, rejected).
- *ratings* – numerieke beoordelingen (1–5 sterren) die gebruikers aan finds geven.
- *notification_subscriptions* – Web Push-abonnementen (endpoint + keys) per gebruiker/apparaat.
- *notification_preferences* – instellingen per gebruiker voor welke notificaties gewenst zijn.

== Belangrijkste relaties

Een aantal relaties zijn cruciaal voor het gedrag van de applicatie:

- Eén *user* heeft veel *finds*; elke find hoort bij precies één user (de eigenaar).
- Eén *location* heeft veel *finds*; meerdere users kunnen finds aan dezelfde locatie koppelen.
- Eén *find* heeft veel *likes*, *comments* en *ratings*.
- Eén *user* heeft veel *likes*, *comments* en *ratings* verspreid over verschillende finds.
- *friendships* modelleren wederzijdse relaties tussen twee users; hieruit volgt welke finds zichtbaar zijn bij privacyfilters.
- *notification_subscriptions* en *notification_preferences* zijn aan users gekoppeld en bepalen hoe en wanneer pushnotificaties verstuurd worden.

Samen vormen deze relaties het fundament voor de sociale interacties rond locaties: het ERD maakt zichtbaar hoe gebruikers, locaties, finds en interacties logisch met elkaar verbonden zijn.

== Normalisatie en evolutie van het datamodel

Tijdens de ontwikkeling is het datamodel geëvolueerd van een eenvoudiger structuur naar een meer genormaliseerde, location-gecentreerde architectuur (zie ook het hoofdstuk Architectuur). Belangrijke stappen hierin waren:

- Het verplaatsen van locatienamen en -informatie uit de *finds*-tabel naar een aparte *locations*-tabel, zodat meerdere finds dezelfde locatie kunnen delen.
- Het toevoegen van aparte tabellen voor *comments*, *likes* en *ratings*, in plaats van alles in één "finds"-structuur te stoppen.
- Het uitbreiden van notificatie- en privacygerelateerde tabellen om Web Push en friend-based zichtbaarheid te ondersteunen.

Deze normalisatie heeft als effect dat:

- data-integriteit verbeterd is (minder duplicatie, duidelijke foreign keys);
- queries efficiënter en expressiever worden (bijv. alle finds op een locatie, alle activiteiten van een user);
- nieuwe features (zoals locatiepopulariteit of uitgebreidere statistieken) eenvoudiger in te passen zijn op basis van het bestaande schema.
