Спроєктувала рівень даних PostgreSQL, побудований насамперед на функціях — 1 275 збережених функцій у 34 схемах — щоб кожне читання й кожен запис проходили через функцію, на яку база даних може видати права, а не через таблицю.
Роботу виконано: 2025
1,275 збережених функцій стережуть кожне читання й запис
Ситуація. Бізнес‑логіка має звичку просочуватися. Частина потрапляє в 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 функціях ця дисципліна коштує чогось реального — нове поле означає міграцію та зміну функції, а не рядок у запиті, — і це тертя є ціною того, що межа тримається.
Читати далі: Впровадила часовпорядковані ідентифікатори UUID v7 (PostgreSQL 18) як ключі сутностей, щоб зменшити фрагментацію індексів B‑tree та пришвидшити запити. Або перегляньте повне портфоліо.
Одна частина довшого переліку — і він увесь на цьому сайті.
Кожен запис написано однаково: ситуація, завдання, що ми зробили і що змінилося.