Оновлено: 2026-04-15
https://github.com/serhiivereschak/biogaia-story (private)
Веб-застосунок для генерації персоналізованих дитячих казок із брендингом BioGaia. По фото дитини та введеним параметрам генерує 12-сторінкову книжку з ілюстраціями через Gemini AI.
Задеплоєно: Firebase Hosting (чистий static frontend — без backend!)
[Браузер клієнта]
→ script.js викликає Gemini API НАПРЯМУ (key захардкожений у JS!)
→ gemini-2.5-pro: аналіз фото → character_desc
→ gemini-2.5-pro: генерація тексту → 12 сторінок
→ gemini-2.5-flash-image: генерація зображень × 12
→ db.js: зберігає в IndexedDB (тільки в браузері клієнта)
→ перехід на book.html
[app.py] — Flask backend існує, але НЕ є частиною продакшн деплою!
firebase.json виключає app.py з хостингу.
Планована архітектура (в app.py, але не задеплоєна):
[Браузер] → POST /api/generate-story → Flask → Gemini
| # | Дефект | Файл | Деталі |
|---|---|---|---|
| 1 | API ключ у client-side JS | script.js:1 |
GOOGLE_API_KEY = "AIzaSyBNd..." — будь-який користувач може відкрити DevTools і вкрасти ключ |
| 2 | Другий API ключ у book.js | book.js:55 |
GOOGLE_API_KEY = "AIzaSyBNd..." — той самий ключ, дублюється |
| 3 | Немає rate limiting | — | Будь-хто може відкрити сторінку і зробити 1000 запитів — рахунок на сотні доларів |
| # | Дефект | Файл | Деталі |
|---|---|---|---|
| 4 | Помилка одного зображення = крах всього | script.js:113 |
throw imgError — якщо 1 з 12 ілюстрацій не згенерується, вся казка втрачається |
| 5 | Казка тільки в IndexedDB | db.js |
Якщо клієнт відкрив на телефоні, а потім перейшов на ноутбук — казки нема. Не можна поділитися посиланням |
| 6 | gemini-2.5-flash-image endpoint | script.js:100 |
Модель gemini-2.5-flash-image — нестабільна/experimental, може повертати 404 |
| 7 | Немає fallback при невдалій генерації | script.js |
Якщо AI повертає не-JSON — сирий текст моделі показується юзеру |
| 8 | 13 сторінок замість 12 | script.js |
Іноді модель генерує 13 сторінок (porушення prompt) — UI адаптується але dots некоректно |
| 9 | Непослідовна зовнішність дитини | — | Персонаж на різних сторінках виглядає по-різному — imagePrompt не містить "seed" або reference image |
| # | Дефект | Деталі |
|---|---|---|
| 10 | Тестові файли в репо | test_rate_limit.html/js/py, test_seed.html — виключені з Firebase, але мусорять репо |
| 11 | Неузгодженість моделей | app.py використовує gemini-1.5, script.js — gemini-2.5 |
| 12 | Немає валідації input | Поле "Ім'я дитини" — немає обмежень довжини/символів |
| Файл | Опис |
|---|---|
script.js |
Головна логіка — форма, виклики Gemini, зберігання |
book.js |
Рендер сторінок книжки, навігація |
db.js |
IndexedDB обгортка (saveStory/loadStory) |
index.html |
Форма вводу |
book.html |
Перегляд готової казки |
app.py |
Flask backend (не в продакшн деплої) |
firebase.json |
Налаштування Firebase Hosting |