# Спроєктувала рівень даних PostgreSQL, побудований насамперед на функціях — 1 275 збережених функцій у 34 схемах — щоб кожне читання й кожен запис проходили через функцію, на яку база даних може видати права, а не через таблицю.

2025

**Ситуація.** Бізнес‑логіка має звичку просочуватися. Частина потрапляє в API, частина — у якийсь SQL, що виконується прямо в обробнику, і незабаром те саме правило виявляється записаним двома‑трьома трохи різними способами, і немає жодного місця, на яке можна вказати й сказати: «ось що система робить зі своїми даними». Так у систему потрапляють баги й діри в безпеці.

**Завдання.** Метою було одне місце для всього цього: кожне читання й запис проходить через базу даних, API залишається тонким адаптером, який не знає бізнес‑правил, а все разом можна щільно замкнути.

**Дія.** Рівень даних побудовано за принципом function‑first. Схему поділено за доменами — identity, organization, review, message, notification і ще 29 інших, 34 разом, — і кожна операція, яку може виконати застосунок, є однією з 1 275 функцій PostgreSQL, які він викликає; прямого доступу до таблиць із Go взагалі немає. Далі це забезпечує сама база даних. Роль, під якою логіниться API, mariner, має EXECUTE на функціях застосунку та USAGE на схемах — і нічого більше: жодного SELECT, жодного INSERT, жодного способу торкнутися таблиці напряму — а це виходить приблизно 4 000 явних грантів, а не один загальний. Функції виконуються як SECURITY DEFINER, належать окремій non‑login ролі function_owner із зафіксованим search_path, а обліковий запис суперкористувача лишається зарезервованим для міграцій і cron, подалі від застосунку, що працює.

**Результат.** Логіка живе в одному місці, яке справді можна перевірити, API лишається тонким і нудним у хорошому сенсі, а межу доступу забезпечує сам Postgres, а не те, що всі пам'ятають правила. Якщо API раптом буде скомпрометовано, воно все одно не зможе зробити нічого, чого не дозволяють функції. На 1 275 функціях ця дисципліна коштує чогось реального — нове поле означає міграцію та зміну функції, а не рядок у запиті, — і це тертя є ціною того, що межа тримається.

---

- Роль: Інженер баз даних
- Категорії: [Архітектура платформи](https://engineer.company/uk/categories/platform-architecture/), [Backend‑розробка](https://engineer.company/uk/categories/backend/), [Бази даних](https://engineer.company/uk/categories/databases/), [PostgreSQL](https://engineer.company/uk/categories/postgresql/), [SQL](https://engineer.company/uk/categories/sql/), [Data Governance](https://engineer.company/uk/categories/data-governance/), [Безпека](https://engineer.company/uk/categories/security/)
- Послуги: [Архітектура платформи та рішень](https://engineer.company/uk/services/platform-architecture/), [Backend- та API‑розробка](https://engineer.company/uk/services/backend-development/), [Проєктування та моделювання баз даних](https://engineer.company/uk/services/database-design/), [Data Governance та якість даних](https://engineer.company/uk/services/data-governance/)

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