[{"data":1,"prerenderedAt":1224},["ShallowReactive",2],{"blog-uk-test-your-supabase-backup":3,"blog-index-uk":871},{"id":4,"title":5,"body":6,"category":826,"cover":827,"coverAlt":828,"description":829,"draft":830,"extension":831,"faq":832,"image":848,"keywords":849,"meta":858,"navigation":859,"ogTitle":860,"path":861,"published":862,"seo":863,"stem":864,"tldr":865,"updated":869,"__hash__":870},"blog_uk\u002Fblog\u002Ftest-your-supabase-backup.md","Перевірте резервну копію Supabase до того, як вона знадобиться",{"type":7,"value":8,"toc":810},"minimark",[9,13,21,24,29,32,35,39,42,146,155,161,165,172,186,211,221,238,243,247,250,275,301,319,329,332,347,351,354,429,437,470,474,477,483,491,494,504,510,513,574,578,584,589,595,616,622,626,634,637,643,646,650,657,673,676,680,683,686,689,693,698,748,761,765,797],[10,11,12],"p",{},"Десь лежить файл, у якому ваша база даних. GitHub Action пише такий щоночі,\nабо ви колись один раз запустили три команди резервного копіювання Supabase,\nабо ваш тариф робить щоденні копії. У нього правильна назва й приблизно той\nрозмір, якого ви очікуєте. Ніхто ніколи його не відкривав.",[10,14,15,16,20],{},"Ось та частина, яку посібники з налаштування відкладають на потім: ",[17,18,19],"strong",{},"резервна\nкопія, яку ніколи не відновлювали, це обіцянка, а не копія."," Єдиний спосіб\nперевірити резервну копію Supabase: навмисно відновити її там, де нічого від\nцього не залежить, і подивитися, що повернеться. Дамп, обрізаний посередині,\nдамп без жодного рядка й дамп не того проєкту лежать у сховищі й виглядають\nточнісінько як добрий.",[10,22,23],{},"Згадайте навчальну пожежну тривогу. Будівля проводить її звичайного ранку,\nколи нічого не горить, бо ніхто не мав би вперше спускатися тими сходами в\nдень, коли вони наповнюються димом. Надворі хтось робить перекличку за списком\nтих, хто був усередині, а хтось записує дату на аркуші біля дверей. Навчальне\nвідновлення влаштоване так само: пройти маршрут, порахувати, записати.",[25,26,28],"h2",{"id":27},"як-дізнатися-що-моя-резервна-копія-supabase-справді-працює","Як дізнатися, що моя резервна копія Supabase справді працює?",[10,30,31],{},"Відновіть її й подивіться. Іншої перевірки не існує, бо сам файл ніяк не\nвідрізняє доброї копії від зламаної.",[10,33,34],{},"Навчання бере вашу найновішу копію, заливає її в проєкт, який нічого не важить,\nі ставить результатові три питання. Чи є кожна таблиця, і приблизно з такою ж\nкількістю рядків, як робоча? Чи датований найновіший рядок ніччю, коли робили\nкопію? Чи можете ви увійти під власним обліковим записом? Добрий файл\nвідповідає «так» на всі три, а кожен спосіб, у який копія псується, провалює\nпринаймні одне з них.",[25,36,38],{"id":37},"пять-способів-у-які-копія-неправильна-але-виглядає-правильно","П’ять способів, у які копія неправильна, але виглядає правильно",[10,40,41],{},"Усі п’ять завершуються вночі без жодної помилки, і всі п’ять лишають файл зі\nзвичною назвою у звичному місці. Відрізнити їх можна лише тоді, коли файл\nзаливають.",[43,44,45,61],"table",{},[46,47,48],"thead",{},[49,50,51,55,58],"tr",{},[52,53,54],"th",{},"Що не так із файлом",[52,56,57],{},"Як до цього зазвичай доходить",[52,59,60],{},"Крок навчання, який це виявляє",[62,63,64,88,106,124,135],"tbody",{},[49,65,66,70,85],{},[67,68,69],"td",{},"Він уривається посередині",[67,71,72,73,77,78,81,82,84],{},"Скрипт, що передає ",[74,75,76],"code",{},"pg_dump"," у ",[74,79,80],{},"gzip",", повідомляє те, що зробив ",[74,83,80],{},". Дамп, який помер на півдорозі, зберігається, а завдання звітує про успіх. Повний диск чи обірване завантаження роблять те саме",[67,86,87],{},"Завершальний рядок, потім підрахунки",[49,89,90,93,103],{},[67,91,92],{},"У ньому ваші таблиці й жодного рядка",[67,94,95,98,99,102],{},[74,96,97],{},"supabase db dump"," запустили без ",[74,100,101],{},"--data-only",", і тоді він пише лише структуру",[67,104,105],{},"Підрахунки: кожна таблиця на нулі",[49,107,108,111,117],{},[67,109,110],{},"У ньому рядки й жодного облікового запису",[67,112,113,114],{},"Дамп назвав лише вашу власну схему, а ваші користувачі живуть у схемі ",[74,115,116],{},"auth",[67,118,119,120,123],{},"Пошук ",[74,121,122],{},"auth.users",", потім вхід",[49,125,126,129,132],{},[67,127,128],{},"Це дані іншого проєкту",[67,130,131],{},"Рядок підключення вказує на staging-копію чи старий проєкт",[67,133,134],{},"Найновіший рядок, не з того дня",[49,136,137,140,143],{},[67,138,139],{},"Він узагалі не заливається",[67,141,142],{},"Дамп із Postgres 17, залитий у Postgres 15, або рядки про власника, які новий проєкт відкидає",[67,144,145],{},"Відновлення зупиняється з помилкою",[10,147,148,149,154],{},"Другий і третій описано в статті\n",[150,151,153],"a",{"href":152},"\u002Fblog\u002Fsupabase-backup-auth-users","чому у вашому дампі Supabase немає користувачів",",\nі обидва виникають через команду дампа, запущену з меншою кількістю параметрів,\nніж їй було потрібно. Перший нас здивував, тож він отримує окремий розділ.",[156,157],"diagram",{"alt":158,"caption":159,"src":160},"Шість однакових запечатаних файлів у ряд, кожен падає у відновлену базу. У першій повні таблиці й реєстр людей, з позначкою. П’ять перекреслено: обрізана таблиця поруч із порожньою, усі таблиці порожні, порожній реєстр, сірі рядки зі знаком нерівності й заливка, зупинена планкою.","У сховищі всі шість файлів однакові. Після заливки лише перший повертає вам ту базу, яка у вас була.","\u002Fblog\u002Ftest-your-supabase-backup\u002Fsix-files-one-good-copy-1600x760.png",[25,162,164],{"id":163},"чи-падає-відновлення-обрізаного-файлу-резервної-копії","Чи падає відновлення обрізаного файлу резервної копії?",[10,166,167,168,171],{},"Не завжди. Ми обрізали файл посеред таблиці, залили його з параметрами, які\nвикористовує сам посібник Supabase, і ",[74,169,170],{},"psql"," завершився без жодної помилки.",[10,173,174,175,177,178,181,182,185],{},"Тест був невеликий, і його легко повторити. 27 вересня 2026 року ми зробили\nдамп бази з двома таблицями, одна на 5 000 рядків, друга на 300, обрізали файл\nу трьох різних місцях і залили кожну версію через ",[74,176,170],{}," із Postgres 17.11.\nКожна заливка використовувала ",[74,179,180],{},"--single-transaction"," і\n",[74,183,184],{},"--variable ON_ERROR_STOP=1",", два параметри, які мають зупинити відновлення на\nпершій проблемі й скасувати все зроблене.",[187,188,189,199,205],"ul",{},[190,191,192,195,196,198],"li",{},[17,193,194],{},"Обрізано посеред значення:"," ",[74,197,170],{}," зупинився з помилкою й нічого не\nзаписав. На такий результат ви й сподівалися б.",[190,200,201,204],{},[17,202,203],{},"Обрізано в останній колонці рядка:"," завершився з кодом виходу 0, так\nпрограма повідомляє про успіх. Перша таблиця повернулася з 2 596 рядками з\n5 000, в останнього з них бракувало половини тексту, а друга таблиця\nповернулася порожньою.",[190,206,207,210],{},[17,208,209],{},"Обрізано точно між двома таблицями:"," теж завершився з 0. Перша таблиця\nбула повна, друга порожня.",[10,212,213,214,217,218,220],{},"Причина в тому, як дамп зберігає рядки. Рядки кожної таблиці лежать в одному\nблоці, що закінчується рядком файлу, у якому стоїть лише ",[74,215,216],{},"\\.",", і коли файл\nзакінчується раніше за цей рядок, ",[74,219,170],{}," сприймає кінець файлу як кінець\nблоку. Єдина ознака того, що мало бути продовження, це рядок, який мав стояти\nв самому кінці.",[10,222,223,224,226,227,230,231,234,235,237],{},"Цей рядок і є підписом ",[74,225,76],{},". Повний дамп містить ближче до кінця слова\n",[74,228,229],{},"PostgreSQL database dump complete",", а обрізаний не містить. Із трьох файлів,\nякі пише Supabase CLI, цей рядок виживає лише в ",[74,232,233],{},"data.sql",", бо CLI вилучає з\nфайлу схеми всі коментарі (перевірено на версії 2.111 CLI). Отже, шукати треба\nв ",[74,236,233],{},", і цей пошук є другим кроком навчання.",[156,239],{"alt":240,"caption":241,"src":242},"Файл із відірваним нижнім краєм іде в крок відновлення з позначкою ON_ERROR_STOP=1 і зеленою галочкою. За ним дві таблиці: перша заповнена приблизно наполовину, 2596 з 5000, з обірваним останнім рядком; друга порожня, 0 з 300.","Заливка повідомила про успіх. Перша таблиця повернулася заповненою наполовину, а друга порожньою.","\u002Fblog\u002Ftest-your-supabase-backup\u002Fa-short-file-restores-clean-1600x680.png",[25,244,246],{"id":245},"куди-її-відновлювати","Куди її відновлювати?",[10,248,249],{},"У проєкт Supabase, який нічого не важить: тестовий проєкт у вашому обліковому\nзаписі або Supabase, запущений на вашому власному комп’ютері. Ніколи не в\nпроєкт, яким користується ваш застосунок.",[10,251,252,255,256,262,263,268,269,274],{},[17,253,254],{},"Тестовий проєкт у Supabase"," найближчий до вашого справжнього, і саме для\nнього написано\n",[150,257,261],{"href":258,"rel":259},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fmigrating-within-supabase\u002Fbackup-restore",[260],"nofollow","посібник Supabase про резервне копіювання й відновлення",":\nйого перший крок полягає в тому, щоб створити новий проєкт. На безкоштовному\nтарифі вам\n",[150,264,267],{"href":265,"rel":266},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fbilling-faq",[260],"належать два активні безкоштовні проєкти",",\nа призупинені не рахуються, тож тестовий проєкт зазвичай нічого не коштує,\nпоки ваша база вміщається в безкоштовний тариф. У платній організації\nобчислювальні ресурси нового проєкту\n",[150,270,273],{"href":271,"rel":272},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fmanage-your-usage\u002Fcompute",[260],"оплачуються щогодини",",\nтож видаліть його, коли навчання закінчиться.",[10,276,277,280,281,292,293,296,297,300],{},[17,278,279],{},"Supabase на вашому власному комп’ютері"," нічого не коштує й не потребує\nоблікового запису. Supabase CLI запускає весь стек локально в Docker:\n",[150,282,285,288,289],{"href":283,"rel":284},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Flocal-development\u002Fcli\u002Fgetting-started",[260],[74,286,287],{},"supabase init",", потім ",[74,290,291],{},"supabase start",",\nі показує адресу бази на порту 54322 та publishable key для локального\nпроєкту. Перш ніж запускати, відкрийте ",[74,294,295],{},"supabase\u002Fconfig.toml"," і встановіть\n",[74,298,299],{},"major_version"," на основну версію Postgres вашого проєкту. Коментар над цим\nпараметром каже, що вони мають збігатися, а версію вашого проєкту видно в\nProject Settings, потім General.",[10,302,303,304,306,307,310,311,313,314,318],{},"На Postgres 15 є підступ. Якщо завдання резервного копіювання не задало версію,\nкопію зроблено через ",[74,305,76],{}," 17 з CLI, і файл даних тоді містить біля початку\n",[74,308,309],{},"SET transaction_timeout = 0",", параметр, якого Postgres 15 не знає, тож\nвідтворення зупиняється на цьому рядку. Для навчання встановіть ",[74,312,299],{},"\nна 17. Потім додайте в завдання резервного копіювання виправлення в один рядок\nзі ",[150,315,317],{"href":316},"\u002Fblog\u002Fsupabase-backup-github-action","статті про GitHub Action",", бо проєкт, у\nякий ви відновлюватимете насправді, досі на 15.",[10,320,321,322,324,325,328],{},"Голого Postgres у Docker, без нічого від Supabase всередині, замало. Дамп\nSupabase посилається на речі, які створює лише Supabase, як-от схема ",[74,323,116],{},", де\nживуть ваші користувачі, і роль ",[74,326,327],{},"authenticated",", яку називають ваші правила\nбезпеки, і відновлення зупиняється на першому ж рядку, що згадує одну з них.",[10,330,331],{},"Одне застереження, бо в тестовому проєкті тепер справжня копія. У ньому адреси\nелектронної пошти ваших користувачів, тож не спрямовуйте на нього ні застосунок,\nні його вебхуки, і видаліть його, коли закінчите.",[10,333,334,335,338,339,342,343,346],{},"Заплановані завдання не переносяться. Якщо ваш проєкт виконує їх через\nрозширення ",[74,336,337],{},"pg_cron",", три файли CLI повертають саме розширення і жодного з його\nзавдань, бо завдання є рядками в ",[74,340,341],{},"cron.job",", а дамп даних ці рядки пропускає. Ми\nперевірили це 4 жовтня 2026 року з версією CLI 2.119, відновивши базу, у якій\nбуло заплановане завдання. Тож тестовий проєкт мовчить, а справжнє відновлення з\nцих файлів так само починається без жодного запланованого завдання, тому\nзберігайте свої виклики ",[74,344,345],{},"cron.schedule"," там, звідки зможете запустити їх знову.",[25,348,350],{"id":349},"як-перевірити-резервну-копію-supabase-крок-за-кроком","Як перевірити резервну копію Supabase, крок за кроком",[10,352,353],{},"Шість кроків, і перші три відбуваються ще до будь-якого відновлення.",[355,356,357,363,386,402,417,423],"ol",{},[190,358,359,362],{},[17,360,361],{},"Знайдіть найновішу копію й подивіться на її дату."," Якщо вона старша за\nостанній запланований запуск, завдання зупинилося, і це ваша перша\nзнахідка.",[190,364,365,375,376],{},[17,366,367,368,370,371,374],{},"Пошукайте в ",[74,369,233],{}," слова ",[74,372,373],{},"dump complete","."," Один збіг означає, що\nфайл дійшов до кінця. Жодного означає, що його обрізано, хоч би яким був\nрозмір. Пошук у текстовому редакторі працює не гірше за термінал:",[377,378,383],"pre",{"className":379,"code":381,"language":382},[380],"language-text","grep -c 'dump complete' data.sql\n","text",[74,384,381],{"__ignoreMap":385},"",[190,387,388,391,392,395,396],{},[17,389,390],{},"Пошукайте в ньому своїх користувачів."," Рядок, що починається з\n",[74,393,394],{},"COPY \"auth\".\"users\""," і має під собою дані, означає, що ваші облікові\nзаписи у файлі:",[377,397,400],{"className":398,"code":399,"language":382},[380],"grep -n 'COPY .*auth.*users' data.sql\n",[74,401,399],{"__ignoreMap":385},[190,403,404,407,408,374,411],{},[17,405,406],{},"Залийте його в тестовий проєкт"," командою з посібника Supabase,\nспрямованою на рядок підключення тестового проєкту. Для локального Supabase\nцей рядок такий: ",[74,409,410],{},"postgresql:\u002F\u002Fpostgres:postgres@127.0.0.1:54322\u002Fpostgres",[377,412,415],{"className":413,"code":414,"language":382},[380],"psql \\\n  --single-transaction \\\n  --variable ON_ERROR_STOP=1 \\\n  --file roles.sql \\\n  --file schema.sql \\\n  --command 'SET session_replication_role = replica' \\\n  --file data.sql \\\n  --dbname \"postgresql:\u002F\u002F…the spare's connection string…\"\n",[74,416,414],{"__ignoreMap":385},[190,418,419,422],{},[17,420,421],{},"Порахуйте рядки й подивіться на найновіший",", в обох базах. Запит у\nнаступному розділі.",[190,424,425,428],{},[17,426,427],{},"Увійдіть у тестовий проєкт під власним обліковим записом."," Команда в\nрозділі після нього.",[10,430,431,432,436],{},"Якщо крок 4 зупиняється з помилкою, навчання зробило свою справу завчасно.\nНотатки з усунення проблем унизу посібника Supabase описують дві найчастіші\nпомилки, обидві про ролі, а\n",[150,433,435],{"href":434},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","як відновити резервну копію Supabase","\nпояснює, від чого захищає кожен параметр цієї команди.",[10,438,439,440,443,444,447,448,451,452,455,456,459,460,463,464,469],{},"Ще двох зупинок у ",[74,441,442],{},"roles.sql"," у цих нотатках немає. Ми натрапили на обидві 4\nжовтня 2026 року, відтворюючи файли двох баз Postgres 17, одна з яких є проєктом\nSupabase, у свіжій локальній копії Supabase:\n",[74,445,446],{},"\"supabase_admin\" is a reserved role, only superusers can modify it"," на рядку,\nщо починається з ",[74,449,450],{},"ALTER ROLE \"supabase_admin\"",", і\n",[74,453,454],{},"permission denied for parameter log_min_messages"," на рядку, що починається з\n",[74,457,458],{},"GRANT SET ON PARAMETER",". Обидва рядки налаштовують ролі, які Supabase сам\nстворює в кожному проєкті, тож поставте ",[74,461,462],{},"--"," на початку кожного з них, щоб\nзробити його коментарем, і запустіть команду знову.\n",[150,465,468],{"href":466,"rel":467},"https:\u002F\u002Fgithub.com\u002FReeve-page\u002Fsupabase-backup-action",[260],"Наша Action для резервного копіювання","\nкоментує їх уже під час створення копії.",[25,471,473],{"id":472},"що-рахувати-і-з-чим-порівнювати","Що рахувати і з чим порівнювати",[10,475,476],{},"Порахуйте кожну таблицю в тестовому проєкті й у робочому проєкті тим самим\nзапитом і покладіть обидва списки поруч. Копія має відставати від робочої бази\nна одну ніч: трохи менше в таблиці, що росте, і ніколи не нуль у таблиці, де\nбули рядки.",[10,478,479,480,482],{},"Це перекличка за списком тих, хто був усередині. Вставте запит у SQL-редактор\nкожного проєкту й натисніть Run. Він рахує рядки в кожній таблиці вашої\nвласної схеми та схеми ",[74,481,116],{},":",[377,484,489],{"className":485,"code":487,"language":488,"meta":385},[486],"language-sql","select table_schema, table_name,\n       (xpath('\u002Frow\u002Fn\u002Ftext()',\n         query_to_xml(format('select count(*) as n from %I.%I', table_schema, table_name),\n                      false, true, '')))[1]::text::bigint as row_count\n  from information_schema.tables\n where table_schema in ('public', 'auth')\n   and table_type = 'BASE TABLE'\n order by table_schema, table_name;\n","sql",[74,490,487],{"__ignoreMap":385},[10,492,493],{},"Він читає кожен рядок кожної таблиці, тож на великій базі запускайте його поза\nнайнавантаженішими годинами.",[10,495,496,497,500,501,482],{},"Потім подивіться на найновіший рядок у таблиці, яку ви знаєте, лише в\nтестовому проєкті. Підійде будь-яка таблиця з колонкою ",[74,498,499],{},"created_at","; поставте\nїї назву замість ",[74,502,503],{},"orders",[377,505,508],{"className":506,"code":507,"language":488,"meta":385},[486],"select max(created_at) from public.orders;\n",[74,509,507],{"__ignoreMap":385},[10,511,512],{},"Відповідь має бути близькою до часу, коли працювало резервне копіювання. Дата,\nстарша на тижні, або рядки, яких ви не впізнаєте, означають, що файл прийшов з\nіншого проєкту.",[43,514,515,528],{},[46,516,517],{},[49,518,519,522,525],{},[52,520,521],{},"Перевірка",[52,523,524],{},"Де",[52,526,527],{},"Що показує добра копія",[62,529,530,541,552,564],{},[49,531,532,535,538],{},[67,533,534],{},"Рядки в кожній таблиці",[67,536,537],{},"В обох",[67,539,540],{},"Ті самі таблиці, кожна трохи позаду робочої, жодна не порожня, якщо в ній були рядки",[49,542,543,546,549],{},[67,544,545],{},"Найновіший рядок",[67,547,548],{},"Тестовий проєкт",[67,550,551],{},"Час із тієї ночі, коли робили копію",[49,553,554,557,559],{},[67,555,556],{},"Ваш власний обліковий запис",[67,558,548],{},[67,560,561,562],{},"Ваша адреса в ",[74,563,122],{},[49,565,566,569,571],{},[67,567,568],{},"Вхід",[67,570,548],{},[67,572,573],{},"Повертається токен",[25,575,577],{"id":576},"чому-вхід-є-тією-перевіркою-що-доводить-ваші-облікові-записи","Чому вхід є тією перевіркою, що доводить ваші облікові записи",[10,579,580,581,583],{},"Підрахунок ",[74,582,122],{}," доводить, що рядки доїхали. Вхід доводить, що вони\nпрацюють: що збережений пароль, служба входу тестового проєкту й ваша адреса\nелектронної пошти досі узгоджуються між собою.",[10,585,586,587,482],{},"Візьміть свій власний обліковий запис із паролем, який ви знаєте. Адреса\nпроєкту й publishable key тестового проєкту є в його панелі Connect, а для\nлокального Supabase у виводі ",[74,588,291],{},[377,590,593],{"className":591,"code":592,"language":382},[380],"curl -X POST 'https:\u002F\u002F…the spare's project ref….supabase.co\u002Fauth\u002Fv1\u002Ftoken?grant_type=password' \\\n  -H \"apikey: sb_publishable_…\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"email\": \"you@example.com\", \"password\": \"…\"}'\n",[74,594,592],{"__ignoreMap":385},[10,596,597,598,603,604,607,608,611,612,615],{},"Це виклик входу з\n",[150,599,602],{"href":600,"rel":601},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fpasswords",[260],"документації самого Supabase",",\nспрямований на тестовий проєкт. Відповідь, у якій є ",[74,605,606],{},"access_token",", означає,\nщо ваш обліковий запис доїхав разом із робочим паролем.\n",[74,609,610],{},"Invalid login credentials"," для облікового запису, який без проблем входить у\nваш робочий застосунок, означає, що не доїхав, і\n",[150,613,614],{"href":152},"чому дамп приходить без облікових записів","\nє статтею саме про такий результат.",[10,617,618,619,621],{},"Якщо всі входять у ваш застосунок через Google, цьому виклику нічого\nперевіряти, бо в тестовому проєкті вхід через Google не налаштовано. Натомість\nпошукайте свою адресу у відновленій ",[74,620,122],{},". Це показує, що рядок\nоблікового запису доїхав, хоч і не доводить, що його пароль працює.",[25,623,625],{"id":624},"файли-половина-яку-відновлення-бази-перевірити-не-може","Файли: половина, яку відновлення бази перевірити не може",[10,627,628,629,633],{},"Копія бази містить рядок для кожного завантаженого файлу й жодного самого\nфайлу. Якщо ви копіюєте свої бакети Storage окремим завданням, а\n",[150,630,632],{"href":631},"\u002Fblog\u002Fsupabase-storage-backup","інакше вони взагалі не копіюються",", проведіть\nнавчання й для цієї копії.",[10,635,636],{},"Візьміть три найновіші рядки з відновленої бази:",[377,638,641],{"className":639,"code":640,"language":488,"meta":385},[486],"select bucket_id, name from storage.objects order by created_at desc limit 3;\n",[74,642,640],{"__ignoreMap":385},[10,644,645],{},"Знайдіть ці три шляхи у своїй копії файлів і відкрийте кожен. Шлях, за яким\nнемає файлу, це зображення, яке ваші користувачі побачили б зламаним після\nсправжнього відновлення.",[25,647,649],{"id":648},"чи-можна-перевірити-резервні-копії-які-supabase-робить-для-мене","Чи можна перевірити резервні копії, які Supabase робить для мене?",[10,651,652,653,374],{},"На платному тарифі так, через Restore to a New Project. Це єдиний спосіб\nвідкрити одну з щоденних копій самого Supabase, бо в поточних проєктах\n",[150,654,656],{"href":655},"\u002Fblog\u002Fdownload-your-supabase-backup","їх неможливо завантажити",[10,658,659,660,665,666,668,669,672],{},"Supabase описує цю функцію як спосіб\n",[150,661,664],{"href":662,"rel":663},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fclone-project",[260],"безпечно проводити тести",".\nВиберіть копію на вкладці Restore to a New Project сторінки Backups, і Supabase\nзбудує з неї новий проєкт із вашими користувачами та їхніми хешованими\nпаролями, готовий до тих самих підрахунків і того самого входу. Дві речі варто\nзнати, перш ніж натискати. Новий проєкт оплачується як окремий, і Supabase\nпоказує вам вартість перед початком. І він копіює все, разом із\nзапланованими завданнями: Supabase пише, що завдання ",[74,667,337],{},", ",[74,670,671],{},"pg_net"," і\nwrappers починають працювати одразу після завершення відновлення, і\nпризупинити їх заздалегідь неможливо. Якщо завдання у вашому застосунку\nнадсилає листи чи списує гроші з картки, тестовий проєкт теж це зробить.",[10,674,675],{},"Якщо ви додатково зберігаєте файл поза обліковим записом, цьому файлу потрібне\nвласне навчання.",[25,677,679],{"id":678},"як-часто-треба-перевіряти-відновлення","Як часто треба перевіряти відновлення?",[10,681,682],{},"Раз зараз, далі раз на три місяці і знову щоразу, коли щось змінюється в тому,\nяк робиться копія.",[10,684,685],{},"Важать зміни, які тихо ламають резервну копію: новий чи відредагований\nworkflow, скинутий пароль бази, перехід на новий тариф чи нову версію\nPostgres, нова таблиця, у яку ваш застосунок почав писати. Після кожної з них\nнавчання минулого кварталу вже не описує файл цього кварталу.",[10,687,688],{},"Потім запишіть результат, це і є аркуш біля дверей. Один рядок на кожне\nнавчання, у місці, до якого ви дістанетеся без того, що зламалося: дата, який\nфайл, підрахунки, що мали значення, чи спрацював вхід і скільки тривало все\nнавчання. Підійде текстовий файл у репозиторії з копіями, а так само\nповторювана подія в календарі з вставленими результатами. Дата відповідає на\n«коли ми востаннє це доводили» саме тієї години, коли комусь треба це знати, а\nтривалість стає вашою першою оцінкою того, на скільки справжнє відновлення\nзупинить ваш застосунок.",[25,690,692],{"id":691},"де-тут-reeve-care","Де тут Reeve Care",[10,694,695],{},[17,696,697],{},"Care зберігає копії вашої бази даних Supabase поза вашим обліковим записом\nSupabase за розкладом вашого тарифу, перевіряє кожну копію під час створення і\nповертає її на місце однією кнопкою.",[187,699,700,706,715,721,727,733],{},[190,701,702,705],{},[17,703,704],{},"Копії робляться за розкладом вашого тарифу",", від одного разу на день до\nкожних шести годин.",[190,707,708,711,712,714],{},[17,709,710],{},"Обрізану копію виявляють уже під час створення."," Завершальний рядок\n",[74,713,76],{}," має бути у файлі, інакше копія не проходить перевірку й ніколи не\nстає датою на вашій панелі.",[190,716,717,720],{},[17,718,719],{},"Кожну таблицю рахують, поки копія пишеться."," Коли таблиця, у якій були\nрядки в попередній копії, у цій не має жодного, про це дізнається людина в\nReeve.",[190,722,723,726],{},[17,724,725],{},"Ваші облікові записи в ній є",", а завантажені файли теж потрапляють туди,\nщойно ви підключите доступ до Storage.",[190,728,729,732],{},[17,730,731],{},"Відновлення робиться однією кнопкою",", і перш ніж щось замінити, робиться\nкопія поточного стану.",[190,734,735,738,739,668,742,744,745,747],{},[17,736,737],{},"Будь-яку копію можна завантажити як zip"," із ",[74,740,741],{},"schema.sql",[74,743,233],{},",\n",[74,746,442],{}," і маніфестом із кількістю рядків у кожній таблиці, тобто з тією\nполовиною цієї статті, що відповідає на «з чим порівнювати», уже записаною.",[10,749,750,751,755,756,760],{},"Щоквартальне навчання доводить ту копію, яку ви вибрали того дня, а перевірка\nвідбувається з кожною копією під час її створення. Копію, перевірку й\nвідновлення покроково намальовано на\n",[150,752,754],{"href":753},"\u002Fsupabase-backups","сторінці про резервні копії Supabase",", а\n",[150,757,759],{"href":758},"\u002Fpricing","що входить у кожен тариф",", разом із розкладом, написано на сторінці\nцін.",[25,762,764],{"id":763},"що-зробити-цього-тижня","Що зробити цього тижня",[766,767,768],"key-takeaways",{},[187,769,770,773,783,789,792,794],{},[190,771,772],{},"Знайдіть найновішу резервну копію й подивіться на її дату. Якщо вона старша за останній запланований запуск, спершу полагодьте завдання.",[190,774,367,775,370,777,779,780,782],{},[74,776,233],{},[74,778,373],{}," і рядок ",[74,781,394],{},". Два пошуки скажуть, чи файл доходить до кінця і чи є в ньому ваші облікові записи.",[190,784,785,786,788],{},"Створіть тестовий проєкт або запустіть Supabase на своєму комп’ютері й залийте файл командою ",[74,787,170],{}," з посібника Supabase.",[190,790,791],{},"Виконайте запит підрахунку в обох базах і покладіть два списки поруч. Подивіться на найновіший рядок у таблиці, яку ви знаєте.",[190,793,427],{},[190,795,796],{},"Запишіть дату, підрахунки й тривалість, а потім видаліть тестовий проєкт.",[10,798,799,800,802,803,805,806,809],{},"Перш ніж закрити цю вкладку, пошукайте ",[74,801,373],{}," у своєму найновішому\n",[74,804,233],{},". Це один пошук, і він скаже, чи доходить файл, який ви називаєте\nрезервною копією, до свого останнього рядка. Якщо файлу для пошуку у вас ще\nнемає, ",[150,807,808],{"href":316},"безкоштовна GitHub Action"," є\nнайшвидшим способом почати їх робити.",{"title":385,"searchDepth":811,"depth":811,"links":812},3,[813,815,816,817,818,819,820,821,822,823,824,825],{"id":27,"depth":814,"text":28},2,{"id":37,"depth":814,"text":38},{"id":163,"depth":814,"text":164},{"id":245,"depth":814,"text":246},{"id":349,"depth":814,"text":350},{"id":472,"depth":814,"text":473},{"id":576,"depth":814,"text":577},{"id":624,"depth":814,"text":625},{"id":648,"depth":814,"text":649},{"id":678,"depth":814,"text":679},{"id":691,"depth":814,"text":692},{"id":763,"depth":814,"text":764},"Backups","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcover-1200x630.png","Ряд однакових запечатаних файлів резервних копій, передній підсвічений, поруч із порожньою пунктирною базою даних, що чекає на один із них.","Як перевірити резервну копію Supabase: відновити в тестовий проєкт, порахувати рядки, увійти й знайти рядок, якого бракує обрізаному файлу.",false,"md",[833,835,837,840,843,846],{"q":28,"a":834},"Відновіть її в проєкт, який нічого не важить, і подивіться, що повернулося. Порівняйте кількість рядків у кожній таблиці з робочою базою, перевірте, що найновіший рядок датований ніччю, коли робили копію, і увійдіть під власним обліковим записом. Сам файл не відрізняє доброго дампа від зламаного: назва, розмір і зелена позначка біля завдання однакові в обох випадках.",{"q":679,"a":836},"Раз зараз, далі раз на три місяці і знову щоразу, коли змінюється те, як робиться копія: новий чи відредагований workflow, скинутий пароль бази, новий тариф чи нова версія Postgres або нова таблиця, у яку пише ваш застосунок. Щоразу записуйте дату разом із підрахунками й тривалістю, щоб на питання, коли це востаннє доводили, була відповідь.",{"q":838,"a":839},"Чи можна перевірити відновлення, не чіпаючи робочу базу?","Так, і саме так це завжди і слід робити. Відновлюйте в тестовий проєкт Supabase, що дозволяє безкоштовний тариф, або в Supabase, запущений на вашому комп’ютері через CLI і Docker. Робочу базу навчання лише один раз читає, щоб порахувати її рядки. Потім видаліть тестовий проєкт, бо в ньому справжня копія ваших користувачів.",{"q":841,"a":842},"Що перевірити після відновлення резервної копії?","Чотири речі. Кількість рядків у кожній таблиці поруч із робочою, де копія має трохи відставати й ніколи не бути нулем для таблиці, у якій були рядки. Найновіший рядок у таблиці, яку ви знаєте, датований ніччю копії. Вашу власну адресу в auth.users. І вхід під вашим обліковим записом, єдину перевірку, яка доводить, що облікові записи працюють, а не просто приїхали.",{"q":844,"a":845},"Відновлення вдалося, але ніхто не може увійти. Чому?","Найчастіше тому, що у файлі ніколи не було ваших облікових записів. Supabase тримає їх у схемі auth, і дамп, який назвав лише вашу власну схему, або голий supabase db dump залишає їх поза файлом, хоча кожна ваша таблиця відновлюється без проблем. Спершу пошукайте у файлі COPY \"auth\".\"users\". Якщо цього рядка немає, зробіть дамп даних із --data-only, який проходить схему auth і забирає ваших користувачів.",{"q":164,"a":847},"Не завжди. Ми обрізали файл pg_dump у трьох місцях і залили кожну версію з --single-transaction та ON_ERROR_STOP, параметрами з посібника Supabase про відновлення. Обрізання посеред значення зупинилося з помилкою. Обрізання в останній колонці рядка й обрізання між двома таблицями обидва завершилися без помилок, із неповними таблицями. Повний дамп містить ближче до кінця рядок PostgreSQL database dump complete, тож шукайте його, перш ніж довіряти файлу.","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",[850,851,852,853,854,855,856,857],"перевірити резервну копію supabase","перевірка резервної копії supabase","тест відновлення supabase","як перевірити резервну копію бази даних","відновити резервну копію в тестову базу","чи працює моя резервна копія supabase","верифікація резервної копії supabase","навчальне відновлення",{},true,"Перевірте резервну копію Supabase заздалегідь","\u002Fblog\u002Ftest-your-supabase-backup","2026-09-28",{"title":5,"description":829},"blog\u002Ftest-your-supabase-backup",[866,867,868],"Щоб перевірити резервну копію Supabase, відновіть її в проєкт, який нічого не важить, порівняйте кількість рядків із робочою базою і увійдіть під власним обліковим записом. Лише відновлення відрізняє добрий файл від зламаного.","Ми обрізали дамп посеред таблиці й залили його з параметрами, які радить Supabase. psql завершився без жодної помилки, а таблиці повернулися неповними.","Проведіть таке навчання раз зараз, далі раз на три місяці й після будь-якої зміни в тому, як робиться копія, і щоразу записуйте дату.","2026-10-05","9bxgd1xup5m1MY8SdlEk86wOOeqMS__wFpHKGV6c3uk",[872,879,885,891,897,903,909,914,920,926,932,938,944,950,951,956,961,966,972,978,983,989,995,1001,1007,1013,1019,1025,1031,1036,1042,1048,1054,1060,1066,1072,1078,1084,1090,1096,1102,1108,1114,1120,1126,1132,1138,1144,1150,1156,1161,1167,1173,1179,1185,1190,1196,1202,1208,1213,1219],{"path":873,"title":874,"description":875,"published":876,"category":877,"image":878,"draft":830},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" при вивантаженні","\"New row violates row-level security policy for table objects\" означає, що вашому вивантаженню бракує правила insert. Публічний бакет його не додає.","2026-10-11","Основи безпеки","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":880,"title":881,"description":882,"published":883,"category":877,"image":884,"draft":830},"\u002Fblog\u002Fbase44-security-scan","Сканування безпеки Base44: те, що бачить лише воно","Сканування безпеки Base44 перевіряє сім видів проблем зсередини. Ось половина, яку читає тільки воно, і половина, на яку воно ніколи не дивиться.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":886,"title":887,"description":888,"published":889,"category":877,"image":890,"draft":830},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Ваш API-ключ витік. Порядок дій","API-ключ витік, і ви не знаєте, що робити першим. Не кожен ключ у вашому фронтенді є витоком, а порядок важить більше за швидкість.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":892,"title":893,"description":894,"published":895,"category":877,"image":896,"draft":830},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" без вимкнення RLS","\"Infinite recursion detected in policy for relation\" означає, що ваша policy запитала таблицю, яку вона захищає. Ось як розірвати коло.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":898,"title":899,"description":900,"published":901,"category":877,"image":902,"draft":830},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" у Supabase, і хибне виправлення","\"No API key found in request\" означає, що запит дійшов до Supabase без ключа. Більшість відповідей натомість вказують на правила вашої бази.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":904,"title":905,"description":906,"published":907,"category":877,"image":908,"draft":830},"\u002Fblog\u002Fis-base44-safe","Чи безпечний Base44? Дані 5 442 застосунків","Чи безпечний Base44? Ми прогнали дев’ять перевірок на 5 442 робочих застосунках Base44. Майже всі отримали B з причин, яких власник ніколи не обирав.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":910,"title":911,"description":912,"published":869,"category":877,"image":913,"draft":830},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Сховати ключ API: перенесіть його в Supabase Edge Function","Сховати ключ API означає прибрати його з браузера, а Supabase Edge Function це найменше місце, куди його покласти. Два кроки поруч важать більше.","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":915,"title":916,"description":917,"published":918,"category":877,"image":919,"draft":830},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Чи відкритий ваш файл .env? Дванадцять шляхів для перевірки","Чи відкритий ваш файл .env на вашому власному вебсервері? Дванадцять адрес скажуть це за хвилину, а влучання означає, що все в ньому вже публічне.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":921,"title":922,"description":923,"published":924,"category":877,"image":925,"draft":830},"\u002Fblog\u002Fis-v0-safe","Безпека v0: усі 1 790 просканованих застосунків v0 отримали A","Безпека v0 на 1 790 живих застосунках v0: усі отримали A. Лише 17 згадували базу даних, і саме це здебільшого вимірює оцінка A.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":927,"title":928,"description":929,"published":930,"category":877,"image":931,"draft":830},"\u002Fblog\u002Fis-bolt-safe","Чи безпечний Bolt? Що показали 1 123 застосунки Bolt","Чи безпечний Bolt? Ми прогнали 1 123 живі застосунки Bolt через дев’ять перевірок. Хостинг був чистим. Знахідки: ключі й відкриті таблиці в самих застосунках.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":933,"title":934,"description":935,"published":936,"category":877,"image":937,"draft":830},"\u002Fblog\u002Fis-supabase-down-or-your-app","Supabase не працює чи проблема у вашому застосунку? Як розрізнити","Supabase не працює чи зламався ваш застосунок? Пауза, повна база й ваша власна помилка виглядають однаково. Чотири перевірки їх розрізняють.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":939,"title":940,"description":941,"published":942,"category":877,"image":943,"draft":830},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Чи шифрує Supabase мої дані? Так. Ось від чого це захищає","Чи шифрує Supabase дані? Так: AES-256 у стані спокою, TLS під час передавання, SOC 2 та ISO 27001. Що покриває кожне і який витік не зупиняє жодне.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":945,"title":946,"description":947,"published":948,"category":877,"image":949,"draft":830},"\u002Fblog\u002Fsupabase-free-plan-limits","Ліміти безкоштовного тарифу Supabase і що стається на кожному","Ліміти безкоштовного тарифу Supabase: 500 МБ бази, 5 ГБ egress і жодних резервних копій. Що стається на кожній межі і що змінює Pro за $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":861,"title":5,"description":829,"published":862,"category":826,"image":848,"draft":830},{"path":316,"title":952,"description":953,"published":954,"category":826,"image":955,"draft":830},"Безкоштовна резервна копія Supabase через GitHub Action і підступ","Резервна копія Supabase через GitHub Action безкоштовна й годиться багатьом застосункам. Робочий процес, потрібний рядок підключення та egress.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":655,"title":957,"description":958,"published":959,"category":826,"image":960,"draft":830},"Чому ви не можете завантажити резервну копію Supabase","Завантажити резервну копію Supabase на сучасному проєкті не вийде: щоденна копія там фізична. Як це перевірити і як тримати власну копію.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":962,"title":963,"description":964,"published":959,"category":877,"image":965,"draft":830},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": бракує GRANT","З 30 жовтня нова таблиця в Supabase відповідає \"permission denied for table\", доки ви не дасте доступ. Лист показує лише половину виправлення.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":967,"title":968,"description":969,"published":970,"category":877,"image":971,"draft":830},"\u002Fblog\u002Fopen-api-endpoint-exposed","Чи є відкритий API-ендпоінт проблемою безпеки? Читайте JSON","Ваше сканування позначило відкритий API-ендпоінт. Чи це важливо, залежить від того, що повернулося, і більшість знайдених належали платформі.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":973,"title":974,"description":975,"published":976,"category":877,"image":977,"draft":830},"\u002Fblog\u002Flovable-security-scan","Сканування безпеки Lovable: чого воно не доведе","Сканування безпеки Lovable: що перевіряють Quick scan і Deep scan, коли запускається кожне, і єдине, чого не доведе жодне сканування зсередини.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":152,"title":979,"description":980,"published":981,"category":826,"image":982,"draft":830},"Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":984,"title":985,"description":986,"published":987,"category":877,"image":988,"draft":830},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":990,"title":991,"description":992,"published":993,"category":877,"image":994,"draft":830},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":996,"title":997,"description":998,"published":999,"category":877,"image":1000,"draft":830},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":1002,"title":1003,"description":1004,"published":1005,"category":877,"image":1006,"draft":830},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":1008,"title":1009,"description":1010,"published":1011,"category":877,"image":1012,"draft":830},"\u002Fblog\u002Fvite-and-next-public-env-vars","Змінні оточення Vite відкриті: префікс означає опублікувати це","Змінні оточення Vite відкриті у вашому застосунку, бо так просив префікс. VITE_ і NEXT_PUBLIC_ означають опублікувати це, а ШІ, який їх додав, не знав ціни.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":1014,"title":1015,"description":1016,"published":1017,"category":877,"image":1018,"draft":830},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":1020,"title":1021,"description":1022,"published":1023,"category":877,"image":1024,"draft":830},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":1026,"title":1027,"description":1028,"published":1029,"category":877,"image":1030,"draft":830},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":631,"title":1032,"description":1033,"published":1034,"category":826,"image":1035,"draft":830},"Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":1037,"title":1038,"description":1039,"published":1040,"category":826,"image":1041,"draft":830},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery у Supabase: ціна та межі","Point-in-time recovery у Supabase відмотує базу на будь-яку секунду за останній тиждень. Коштує $100 на місяць понад Pro і покриває лише базу даних.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":1043,"title":1044,"description":1045,"published":1046,"category":826,"image":1047,"draft":830},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":1049,"title":1050,"description":1051,"published":1052,"category":877,"image":1053,"draft":830},"\u002Fblog\u002Fsafest-ai-app-builder","Який білдер застосунків з ШІ найбезпечніший? 30 998 тестів","Який білдер застосунків з ШІ найбезпечніший? Ми просканували 30 998 живих застосунків з Lovable, Base44, Replit, v0 і Bolt. Оцінку вирішує не білдер.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":1055,"title":1056,"description":1057,"published":1058,"category":877,"image":1059,"draft":830},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Увімкніть Row Level Security на кожній таблиці Supabase і перевірте","Row Level Security у Supabase без політики закриває таблицю повністю. Політика без увімкненого перемикача не робить нічого. Ось SQL, і ось перевірка.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":1061,"title":1062,"description":1063,"published":1064,"category":877,"image":1065,"draft":830},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": чого не бачить попередження","Supabase позначає \"RLS disabled in public\" як помилку. Про політику читання, яка лишає вашу таблицю так само відкритою, він не каже нічого.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":1067,"title":1068,"description":1069,"published":1070,"category":877,"image":1071,"draft":830},"\u002Fblog\u002Frotate-supabase-service-role-key","Як замінити злитий ключ service_role у Supabase","Supabase каже спершу закрити витік. Інші посібники кажуть міняти негайно. Що правильно, залежить від того, куди саме потрапив ваш ключ service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":1073,"title":1074,"description":1075,"published":1076,"category":877,"image":1077,"draft":830},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Десять інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":1079,"title":1080,"description":1081,"published":1082,"category":877,"image":1083,"draft":830},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":1085,"title":1086,"description":1087,"published":1088,"category":877,"image":1089,"draft":830},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":1091,"title":1092,"description":1093,"published":1094,"category":877,"image":1095,"draft":830},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":1097,"title":1098,"description":1099,"published":1100,"category":877,"image":1101,"draft":830},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Ваш ключ API OpenAI відкритий у фронтенді. Замініть його.","Ключ API OpenAI, відкритий у фронтенді, не можна прив'язати до домену. Замініть його сьогодні, перенесіть виклик на свій сервер і обмежте витрати.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1103,"title":1104,"description":1105,"published":1106,"category":877,"image":1107,"draft":830},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Ключ API у фронтенді: що насправді віддають 30 998 застосунків","Ключ API, відкритий у вашому фронтенді, зазвичай є ключем Google Maps. Ми просканували 30 998 vibe-coded застосунків і порахували, що витікає насправді.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":1109,"title":1110,"description":1111,"published":1112,"category":826,"image":1113,"draft":830},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":1115,"title":1116,"description":1117,"published":1118,"category":877,"image":1119,"draft":830},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":1121,"title":1122,"description":1123,"published":1124,"category":826,"image":1125,"draft":830},"\u002Fblog\u002Fback-up-supabase-free-tier","Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":1127,"title":1128,"description":1129,"published":1130,"category":877,"image":1131,"draft":830},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":1133,"title":1134,"description":1135,"published":1136,"category":877,"image":1137,"draft":830},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":1139,"title":1140,"description":1141,"published":1142,"category":877,"image":1143,"draft":830},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy в Supabase. Що далі?","\"New row violates row-level security policy\" означає, що Supabase відмовив у записі. Швидке виправлення знову відкриває таблицю для всіх.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":1145,"title":1146,"description":1147,"published":1148,"category":877,"image":1149,"draft":830},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":1151,"title":1152,"description":1153,"published":1154,"category":826,"image":1155,"draft":830},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching у Supabase це не бекап. Він іде тільки вперед.","Чому branching у Supabase це не бекап: гілка стартує без ваших даних, а мердж переносить саму лише схему. Для чого він потрібен і що брати замість нього.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":434,"title":1157,"description":1158,"published":1159,"category":826,"image":1160,"draft":830},"Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":1162,"title":1163,"description":1164,"published":1165,"category":877,"image":1166,"draft":830},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":1168,"title":1169,"description":1170,"published":1171,"category":877,"image":1172,"draft":830},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Чи є проблемою ключ API Google у вашому браузері?","Ключ API Google у відкритому коді сторінки наш сканер знаходить найчастіше, і зазвичай усе гаразд. Вирішує це одне безкоштовне налаштування.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1174,"title":1175,"description":1176,"published":1177,"category":826,"image":1178,"draft":830},"\u002Fblog\u002Fai-agent-deleted-my-database","ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":1180,"title":1181,"description":1182,"published":1183,"category":877,"image":1184,"draft":830},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Чи може будь-хто прочитати вашу базу Supabase? 3 680 застосунків","Чи може будь-хто прочитати вашу базу даних Supabase без входу? Ми просканували 30 998 живих застосунків, зроблених ШІ-білдерами, і виміряли, як часто так.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":1186,"title":1187,"description":1188,"published":1183,"category":877,"image":1189,"draft":830},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":1191,"title":1192,"description":1193,"published":1194,"category":877,"image":1195,"draft":830},"\u002Fblog\u002Fsupabase-new-api-keys","Нові API-ключі Supabase: який із них безпечний у застосунку?","Supabase замінив anon і service_role публічними та секретними ключами. Який із них має бути у вашому застосунку, а який не має бути ніколи?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":1197,"title":1198,"description":1199,"published":1200,"category":826,"image":1201,"draft":830},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":1203,"title":1204,"description":1205,"published":1206,"category":877,"image":1207,"draft":830},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security увімкнено. Таблиця досі публічна.","Увімкнути Supabase Row Level Security не означає захистити таблицю. Захищають політики, а та, що полагодила застосунок, часто впускає всіх.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":1209,"title":1210,"description":1211,"published":1206,"category":826,"image":1212,"draft":830},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":1214,"title":1215,"description":1216,"published":1217,"category":826,"image":1218,"draft":830},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Три способи зробити резервну копію бази Supabase, і чого бракує","Панель, pg_dump і керований сервіс. Що насправді зберігає кожен спосіб, що тихо лишає осторонь і який із них переживе втрату акаунта.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":1220,"title":1221,"description":1222,"published":1217,"category":877,"image":1223,"draft":830},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Які API-ключі безпечні у браузері, а які ні","Ваш ключ anon у Supabase створений, щоб бути публічним. Ключ service_role для цього не створений, і він ігнорує всі правила, які ви задали. Як їх розрізнити.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1791705966658]