# Utformade ett funktionsbaserat dataskikt i PostgreSQL — 1 275 lagrade funktioner i 34 scheman — så att varje läsning och skrivning går via en funktion som databasen kan ge behörighet till, i stället för via en tabell.

2025

**Situation.** Affärslogik har en tendens att läcka. Lite hamnar i API:et, lite i någon SQL som en hanterare kör direkt i koden, och snart är samma regel skriven på två eller tre lite olika sätt och det finns ingenstans att peka och säga ”det här är vad systemet gör med sina data”. Det är så buggar och säkerhetshål kommer in.

**Uppgift.** Målet var ett enda hem för alltihop: varje läsning och skrivning skulle gå genom databasen, API:et skulle vara en tunn adapter som inte känner till affärsreglerna, och det hela skulle gå att låsa ordentligt.

**Handling.** Datalagret är byggt med funktionerna först. Schemat är uppdelat per domän — identity, organization, review, message, notification och 29 till, 34 totalt — och varje operation som appen kan utföra är en av 1 275 PostgreSQL‑funktioner som den anropar; det finns ingen direkt tabellåtkomst från Go över huvud taget. Sedan ser databasen till att det efterlevs. Rollen som API:et loggar in som, mariner, har EXECUTE på appens funktioner och USAGE på schemana och inget annat — ingen SELECT, ingen INSERT, inget sätt att röra en tabell direkt — vilket blir ungefär 4 000 explicita behörigheter i stället för en generell. Funktionerna körs som SECURITY DEFINER och ägs av en separat roll utan inloggning, function_owner, med en fast search_path, och superanvändarkontot är reserverat för migreringar och cron, långt från den körande appen.

**Resultat.** Logiken bor på ett ställe som faktiskt går att granska, API:et förblir tunt och tråkigt på det bra sättet, och åtkomstgränsen upprätthålls av själva Postgres i stället för av att alla kommer ihåg reglerna. Om API:et på något sätt komprometterades skulle det ändå inte kunna göra något som funktionerna inte tillåter. Med 1 275 funktioner kostar disciplinen på riktigt — ett nytt fält är en migrering och en funktionsändring, inte en rad i en SQL‑fråga — och den friktionen är priset för att gränsen håller.

---

- Roll: Databasingenjör
- Kategorier: [Plattformsarkitektur](https://software.engineer.company/sv/categories/platform-architecture/), [Backendutveckling](https://software.engineer.company/sv/categories/backend/), [Databaser](https://software.engineer.company/sv/categories/databases/), [PostgreSQL](https://software.engineer.company/sv/categories/postgresql/), [SQL](https://software.engineer.company/sv/categories/sql/), [Datastyrning](https://software.engineer.company/sv/categories/data-governance/), [Säkerhet](https://software.engineer.company/sv/categories/security/)
- Tjänster: [Plattforms- och lösningsarkitektur](https://software.engineer.company/sv/services/platform-architecture/), [Backend- och API‑utveckling](https://software.engineer.company/sv/services/backend-development/), [Databasdesign och datamodellering](https://software.engineer.company/sv/services/database-design/), [Datastyrning och datakvalitet](https://software.engineer.company/sv/services/data-governance/)

<https://software.engineer.company/sv/portfolio/designed-a-postgresql-function-first-data-layer-across-63/>
