| 2026-09-21 |

Docker-деплой готов к проде (ТЗ 0.33, M7)
...
- nginx: client_max_body_size 20m (вложения до 10 МБ падали бы с 413),
HTTP/1.1-апстрим с keepalive и без буферизации для /api/ и /mcp/ (SSE),
кэш хэшированной статики на год, gzip
- compose: убраны контейнеры ollama/ollama-init (Ollama — внешний сервер,
OLLAMA_BASE_URL из .env); restart для db; healthcheck api через
/api/health (start_period 30s на миграции); модель по умолчанию
согласована с конфигом (qwen3.5:2b-q4_K_M, открытый вопрос ТЗ 8.5 закрыт)
- mcp_server: FastMCP пропускал только Host localhost — в проде за nginx
/mcp отвечал 421; разрешённый Host берётся из GAUTH_REDIRECT_URI
(dev-поведение не изменилось, защита от DNS-rebinding сохранена)
- README: раздел «Деплой» — шаги, внешний TLS-прокси, лимит тела,
буферизация SSE, почему 1 воркер uvicorn
- ТЗ 0.33: TLS — внешний reverse-proxy; Ollama — внешний сервер
Проверено локально полным стеком (db+api+web на :8135): сборка образов,
SPA/health/SSO-редирект/413/gzip/MCP-флоу (initialize → tools/call),
MCP с чужим Host — 421. 117 backend-тестов, mypy, ruff — чисто.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
4 hours ago
|
Сад: хват и фидбек при перемещении объектов (ТЗ 0.32)
...
- Хит-зона объекта — клетка с запасом, а не текстура: промахи мышью исключены
- Анимации «взял в руку» (масштаб + тень) и «приземление» (ease-out доводка)
- Подсветка целевой клетки по валидности: зелёная/красная, зеркало правил
бэка (растениям запрещён домик); за краем сада подсветка скрыта
- Недопустимый бросок (мимо сада, на домик) — анимированный возврат на место
без запроса к API; клик без движения больше не ломает состояние твинов
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
4 hours ago
|
Страница-инструкция по MCP + ссылка в настройках (ТЗ 0.31)
...
- Новый вид McpView (/mcp-help): что реализует, инструменты, адрес сервера
(из location.origin, кнопка «Скопировать»), токен, примеры подключения
(Claude Code и универсальный JSON), раздел про контекст проекта.
- Карточка-ссылка «MCP для ИИ-агентов» в «Настройках».
- Тексты i18n ru/en/uk.
- vite-прокси: '/mcp' регэкспом ^/mcp(/|$) — путь страницы /mcp-help
не должен проксироваться в backend (префиксный матч ловил её).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
5 hours ago
|
MCP-эргономика для небольших моделей и проектный контекст (ТЗ 0.30)
...
- Серверные instructions FastMCP: порядок работы, привязка задач к проекту,
восстановление контекста через get_project, запрет придумывать id.
- Новые тулы: list_projects (заметка + открытые задачи), get_project (по id
или имени, полная заметка + открытые задачи), list_tags.
- Адресация проекта по имени: project_name (регистронезависимо) в
create_task/update_task/list_tasks; сравнение в Python — lower() в SQLite
не понимает кириллицу.
- Ошибки с подсказкой следующего шага; create_task без проекта отдаёт hint.
- Описания всех параметров через Annotated/Field (enum, форматы, диапазоны).
- _compact отдаёт project_id; обновлённые докстринги тулов.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
5 hours ago
|
Пачка 4 ревью: расхождения с ТЗ
...
- Фильтр по приоритету в списке задач (ТЗ 3.6): параметр priority в
GET /api/tasks — градации шкалы 0-10, без приоритета = very_low;
селект в ListView, ключи i18n в ru/en/uk, тест.
- Статистика (ТЗ 3.13): метрики «закрыто», XP, график и теплокарта считают
только закрытия (kind='task') — микронаграды за создание больше не
попадают в «закрыто».
- apply_proposal привязывает задачу только к неархивному проекту; каталог
проектов для LLM-детализации тоже без архивных (ТЗ 3.8.1).
- i18n: «ч» часов в достижениях сада — через словарь (taskui.time.h).
- Докстринги: актуальные номера разделов ТЗ (MCP 3.10, архив 3.8.1).
ТЗ 0.29 (семантика фильтра приоритета в 3.6).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
5 hours ago
|

Пачка 3 ревью: гонки наград и остатки фронтенда
...
- Гонка дейли: уникальный частичный индекс (source, day) + колонка
coin_events.day; параллельные POST /api/xp/daily отдают granted=False
вместо 500 (IntegrityError ловится молча).
- Гонка ensure_garden (параллельные GET /api/garden): работа в savepoint,
при нарушении уникальности (uq_coin_level, kind+ref_id) — откат и выход;
дубли бонусов уровня и растений исключены.
- Параллельное закрытие: PATCH и MCP update_task берут задачу с FOR UPDATE
OF tasks (Postgres; SQLite игнорирует) — двойных наград/спавнов нет.
- redetail утверждённой задачи — no-op: ai_proposal больше не стирается,
фоновая LLM не будится (worker и так работает только с raw).
- Фронт: ProjectView подписан на SSE (task/project changed/deleted);
SSE-refetch на странице задачи не затирает начатый ввод тега;
просрочка дедлайна считается по локальной дате, а не UTC; бросок
предмета мимо сада игнорируется (не прилипает к краю); пауза refetch'а
сада держится до конца своего move-запроса, а не фиксированные 300 мс.
- Тест: redetail no-op для approved. 110 passed.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
5 hours ago
|
Пачка 2 ревью: общий путь закрытия — MCP-награды и анти-дюп спавна
...
- Новый services/closing.py: handle_task_closed — спавн регулярной + XP +
монеты + бонус уровня; используют и HTTP-API, и MCP-инструменты. Закрытие
агентом теперь даёт те же награды, что и UI (ТЗ 3.5, 3.13, 3.10).
- Задача.spawned_at (+миграция): спавн — один раз на цепочку; раньше MCP
спавнил следующий экземпляр при каждом обновлении закрытой задачи.
- Выход из done сбрасывает done_at (HTTP и MCP): повторное закрытие снова
проходит через ветку закрытия без дублей наград (открытый вопрос ТЗ 7).
- MCP create_task: микронаграда за создание, как в HTTP-API; broadcast
xp.changed (celebrate:true при закрытии, false при создании).
- Тесты: MCP-награды при закрытии и создании, спавн ровно один раз,
un-done/повторное закрытие без дублей (HTTP и MCP). 109 passed.
ТЗ 0.28.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
5 hours ago
|

Пачка 1 ревью: безопасность + порча данных (находки 1-5)
...
Бэкенд:
- DELETE /api/tags/{id} требовал сессии только фактически — добавлен UserDep;
регрессия-тест проверяет require_user на каждом /api-роуте (не пройдёт для
любого нового эндпоинта без UserDep).
- Вложения: SVG отклоняется (скриптуемый формат — inline-отдача = stored XSS),
лимит 10 МБ на файл, X-Content-Type-Options: nosniff на отдаче.
- Open redirect закрыт: return_to только внутренние пути (не //, не внешние).
- MCP-токен сравнивается constant-time (hmac.compare_digest).
- Дефолтный SESSION_SECRET валит старт валидатором — молчаливо подделываемая
кука вместо этого даёт явную ошибку конфигурации.
- backend/data/ (runtime-вложения) в .gitignore.
Фронтенд:
- Черновик инлайн-правки больше не переезжает между задачами: при смене
/tasks/:id сбрасываются descEditing/draft, заголовочный InlineField
перемонтируется по key=taskId (PATCH старого текста в новую задачу).
- Утечка SSE-подписок: onRealtime сам отписывается при dispose scope —
N визитов на страницу больше не оставляют N load() на мёртвых инстансах.
- Out-of-order: токен запроса в load() TaskView/ProjectView — поздний ответ
старого id не перетирает данные нового; ListView — то же на фильтрах.
- Смена фильтра сбрасывает пагинацию: watch(filters, {deep}) (ТЗ 3.6).
- Двойной submit не создаёт дубликаты: busy в TaskForm и quickAdd стека.
- Утечка Pixi: unmount во время init уничтожает рендерер после резолва.
- Оффлайн-старт PWA: /auth/me без сети не роняет onMounted молча.
Тесты: 103 passed (+6: auth-все-роуты, SVG, oversize, nosniff, return_to,
дефолтный секрет). ruff/mypy чисты.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
5 hours ago
|
PWA: тёмный манифест, проверка установочности и оффлайн-оболочки (ТЗ 0.27, 3.15)
...
background_color/theme_color — палитра кита #16161e (белый фон мигал при
запуске установленного приложения, шапка окна была зелёной); добавлен id.
Проверено на прод-сборке (headful Chromium, чистый профиль): SW активен,
precache 21 запись, beforeinstallprompt приходит, оффлайн-навигация отдаёт
оболочку приложения. Поведение зафиксировано в ТЗ 3.15.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
7 hours ago
|
«Новая задача» в шапке проекта: на мобильном — кнопка-иконка
...
size="sm" (плитка иконки 32px вместо 46px) + на ≤640px лейбл скрывается,
кнопка сжимается до компактной 54x38 — как «+» топбара.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
7 hours ago
|
Чекбоксы списков задач в описании кликабельны и сохраняются (ТЗ 0.26)
...
Клик по чекбоксу в отображаемом описании переключает соответствующий
- [ ] / - [x] в сыром markdown (маркеры - * + и нумерованные списки)
и сохраняет PATCH'ем описания. marked рендерит чекбоксы с disabled —
атрибут снимается во view-режиме, иначе клики не всплывают вовсе;
повторный клик до ответа блокируется до перерендера.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
7 hours ago
|
Пачка UI: полоска таймера тостов, мобильный «+», ширина md-редактора, мета-бейджи
...
- Тосты: у .toast-progress-bar кита анимация без duration мгновенно схлопывала
полоску таймера (forwards до scaleX(0) поверх inline transform адаптера);
отключаем селектором той же специфичности (.toast .toast-progress ...).
- Кнопка «Новая задача» на мобильном — компактная кнопка-иконка вместо
растянутого .btn с пустым хвостом после скрытия лейбла.
- Инлайн-редактор описания задачи на всю ширину контейнера (max-width .form-group).
- Ссылка на проект в мете страницы задачи — inline-flex, бейджи на одном базлайне.
- Detailing: зачистка HTML-тегов из markdown-ответов LLM (_clean_markdown).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
7 hours ago
|
Сад: реальный fullscreen на мобильных — вписывание по меньшей стороне
...
- fullscreen-бокс занимает весь экран (на вертикальном телефоне — всю высоту),
аспект сетки в fullscreen отключается
- рендерер вписывает сад по меньшей стороне и центрирует (базовый сдвиг
отделён от panOffset, учтён в зуме, панораме и клиентских координатах)
- земля/газон рисуются с запасом за края сетки — вокруг поля трава,
а не фон страницы
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
7 hours ago
|
ИИ-детализация: короткий тайтл, шаги в описании, контекст проектов, валидация (ТЗ 0.25)
...
- LLM предлагает короткий заголовок для перегруженных тайтлов и описание
с нумерованными шагами, если они очевидны
- в контекст добавлены открытые проекты с описаниями — назначение по смыслу
- теги: разрешены новые (1-2 при отсутствии подходящих), до 3, не обязательно один
- валидация ответа: заглушки «NULL»/пробелы отбрасываются, дубли схлопываются,
new_project без валидного имени не протекает; несуществующие теги создаются
при утверждении
- фронт: строки «Новый заголовок»/«Описание с шагами» в карточке предложения
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
7 hours ago
|
Пачка UI: fullscreen сада, отступ empty-state, шапка задачи, форма на всю ширину
...
- fullscreen сада: резерв 64px в ширине бокса — кнопки зума и инвентарь не уезжают за экран
- «Всё спокойно» на главной не слипается с блоком быстрого ввода
- на экранах ≥641px действия шапки страницы не переносятся под длинный заголовок
- форма редактирования на весь контейнер (form-group кита растянута с 600px)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
7 hours ago
|
Пачка UI + Ollama + SSE-реактивность (ТЗ 3.14)
...
- Бейдж приоритета с иконкой (PriorityBadge) во всех видах
- Фильтры страницы проекта запоминаются в localStorage (глубокий watch)
- DurationInput (ч/мин, шаг 5), ConfirmDialog, пагинация, иконки удаления
- Диалоги: «В архив» warning, кнопки поменяны местами
- Автодетализация на Ollama 192.168.1.130 (qwen3.5:2b, think:false)
- SSE /api/events: шина realtime, публикации после коммита, coarse-события + refetch
- Фронт: realtime.ts, удаление поллинга StackView, refetch по видам,
подавление во время drag сада, дедуп XP-тостов
- Тесты 93 passed, e2e двух вкладок; ТЗ 0.24
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
8 hours ago
|
| 2026-09-20 |
Сад: изометрический домик, тени под объектами, пропорции растений
...
- Домик перестроен в изометрии 2:1 из полигонов (fillPoly/wall): две
видимые стены (свет/тень), скаты, фронтон, труба на дальнем скате,
дверь и окно с отблесками.
- Мягкая овальная тень (SHADOW) под растениями/декорациями и домиком,
ширина подгоняется под текстуру тела (fitShadow).
- Пропорции: ель/дуб/кактус выросли относительно цветов (дерево не
размером с цветок).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Сад: пиксель-арт сцена на PixiJS 8 — спрайты из кода, рендерер вне Vue-reactive
...
- PixiJS 8 (WebGL): nearest, roundPixels, нативный пиксель 16px×2 (клетка 32px),
динамический импорт — pixi в async-чанке (main не раздут, PWA в лимитах)
- src/game/pixelart.ts: пиксель-матрицы → canvas → CanvasSource(nearest) с кэшем
- src/game/sprites.ts: тайлы травы/дикой земли/изгороди, домик, 6 видов × 3
стадии растений, декорации, кольца rare/epic, блёстки — без внешних ассетов
- src/game/GardenRenderer.ts: слои terrain/house/items/fx, дифф items по id,
z-sort, drag на канвасе, grow-in/покачивание/блёстки, один тикер
- GardenScene.vue: renderer через shallowRef — deep-reactive-прокси Vue ломал
identity-проверку shared defaultScale в Pixi (TypeError при первом drag)
- ТЗ 0.16: 3.13 дополнен (отрисовка сцены), вопрос 8 закрыт
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Сад: инвентарь декораций — покупка кладёт на склад, drag на карту и обратно
...
- Бэк: garden_items.x/y nullable; покупка декорации не размещает её,
а кладёт в инвентарь; PATCH с x/y null возвращает декорацию в инвентарь
(растениям — 400); авторазмещение учитывает только размещённые элементы.
- Фронт: полоса инвентаря под сценой с чипами, drag из инвентаря на карту
с призраком у курсора, drag размещённой декорации обратно в инвентарь,
GnAlert «Куплено…» в маркете. Фикс: убран pointer-events:none у декораций —
из-за него декорации нельзя было перетаскивать по карте.
- Миграция f2a3b4c5d6e7, локали ru/en/uk, ТЗ 0.15.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Сад-сцена: монеты, растения на карте, магазин декораций и расширений
...
Контент открывается за опыт, покупается за монеты: XP — ранг садовника
(только растёт), монеты — валюта сада. Монеты за закрытие = floor(xp/2)
(заголовок X-Earned-Coins) и бонус 25×L за уровень; журнал — coin_events.
- Бэкенд: CoinEvent/GardenItem + миграция с backfill монет; сервис сада
(баланс, авторазмещение спиралью вокруг домика, виды по уровням,
premium только у rare/epic); API /api/garden — сцена, перемещение,
апгрейд растений, магазин декораций и расширений карты.
- Фронт: SVG-сцена GardenScene (сетка 20px, домик, drag&drop, поповер
роста), кошелёк в шапке, маркет (расширения, декорации, каталог видов
с замками), тост «+XP • +N монет», локали ru/en/uk.
- Тесты сада (10), ТЗ 0.14 (3.13 + модель данных).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Сущность «документ»: описания и заметки — единый текст с вложениями
...
- Новая таблица documents (owner_type task|project, owner_id, body) —
описания задач и заметки проектов теперь одна сущность; на моделях
полиморфная relationship + свойства description/note (API не меняется).
- Вложения привязаны к документу: attachments.document_id; эндпоинты
/api/documents/{id}/attachments; URL файла /api/attachments/{id}/file
не тронут (зашит в сохранённый markdown и PWA-кэш).
- Миграция d9e8f7c6b5a4: перенос текстов в документы (документ заводится
каждому владельцу), бэкфилл вложений, дроп старых колонок.
- Картинки в заметке проекта: Ctrl+V в инлайн-редакторе, drawer на
странице проекта и в списке проектов.
- MCP: поиск по описанию через join по документу; вложения в _full.
- ТЗ 0.13: модель данных обновлена.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Проект: карандаш заметки + правки инлайн-селектов
...
- Заметка проекта: карандаш виден (color:inherit) и стоит справа на линии
заголовка, как на странице задачи.
- GnSelect перекрывает @change своим внутренним onChange — сохранение по
change молча не срабатывало; убран @change="save" из инлайн-селектов
(актуальность и приоритет проекта, приоритет задачи), сохранение — по ✓.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Вставка картинок в описание: в позицию курсора + просмотр на весь экран
...
- MdEditor сам обрабатывает Ctrl+V с картинками: файл грузится колбэком
uploadImages, markdown-ссылка вставляется в позицию курсора textarea,
миниатюры вставленного показываются под полем (клик — лайтбокс).
- Новый MdLightbox: полноэкранный просмотр картинки (клик по фону,
крестик или Esc закрывает); подключён к отображению описания задачи
(клик по img в md-view) и заметки проекта, а также к предпросмотру
редактора.
- TaskForm: paste-логика перенесена в MdEditor (колбэк uploadImages).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Блок подзадач: кнопка справа, список отделён отступом
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Карандаш описания: margin-top -23px
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Правки страницы задачи: карандаш описания и малая кнопка статуса
...
- Карандаш описания: тёмный цвет в тон заголовку карточки, прижат
к правому краю линии «Описание».
- «Изменить статус»: большая кнопка заменена на маленькую иконку
(GnIconButton с карандашом), dropdown-меню прежнее.
- Инлайн-правка заголовка: .inline-field/.inline-editing на всю ширину
шапки, поле растягивается, кнопки ✓/✗ рядом.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Фикс стилизации инлайн-редакторов: GnInput вместо bare-инпутов
...
В ките GnInput bare рендерит input вообще без класса (стили кита живут
в селекторе .form-group .label .input), поэтому инлайн-редакторы были
голыми браузерными полями. Теперь инлайн использует GnInput/GnSelect
с полной обёрткой кита; в строках параметров и шапке поле ужато
(:deep-переопределения размеров, отступы формы убраны), классы width
вешаются на сам input, т.к. attrs-класс не попадает на обёртку.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
ТЗ 0.12: инлайн-редактирование полей задачи и проекта
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Инлайн-редактирование полей на страницах задачи и проекта
...
- Новый компонент InlineField: враппер «показ ↔ редактор» с кнопками ✓/✗,
Esc = отмена, throw из save() оставляет редактор открытым.
- Страница задачи: заголовок правится кликом в шапке, описание — по
карандашу (MdEditor без подписи), в «Параметрах» все 8 строк видны
всегда; приоритет, оценка, фактически, деньги (бюджет+оценка одним
PATCH) и дедлайн (дата+период, взаимоисключающие) правятся инлайн.
- Страница проекта: инлайн для названия, заметки, актуальности, приоритета.
- MdEditor: caption='' скрывает подпись, undefined — стандартная.
- Локали: common.notSet, task.editTitle/editDescription,
task.deadlineConflict, projectPage.editNote.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
«Я сам» больше не открывает форму правки
...
Кнопка просто отменяет помощь ИИ: утвердить задачу без применения
предложения (apply_proposal=false) — без принудительного перехода
в форму правки.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|