| 2026-09-21 |

Мультиюзерность: изоляция данных, per-user MCP-токены, claim при первом логине (ТЗ 0.34, бэкенд)
...
- Модели: User (профиль из SSO), McpToken (только sha256-хэш),
user_id на tasks/projects/tags/documents/xp_events/coin_events/garden_items;
уникальности имени проекта/тега — составные (per-user); app_settings →
per-user (PK user_id+key), старая таблица → app_settings_global (источник claim)
- Миграция f9a0b1c2d3e4 (Postgres): новые таблицы, user_id на 7 таблиц,
составные уникальности, частичные индексы дейли/уровня per-user
- Claim-on-first-login (ТЗ 1.2): первый вошедший забирает строки с user_id NULL
и копирует глобальные настройки; upsert профиля в callback
- Scoping всех API и сервисов: tasks/projects/tags/attachments/settings/xp/
garden + xp/garden/closing/options/recurrence/detailing; чужое — 404
- MCP (ТЗ 3.10): per-user bearer-токены вместо env MCP_TOKEN (middleware →
sha256 → request.state.gntodo_user_id), 8 тулов с Context; SSE publish(uid)
- API /api/mcp-tokens: список/генерация (plaintext один раз)/отзыв
- Тесты: test_multiuser (изоляция двух пользователей, claim, per-user дейли/
настройки), test_mcp_tokens; 135 passed, ruff, mypy strict
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
8 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
8 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
8 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
9 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
9 hours ago
|
ИИ-детализация: короткий тайтл, шаги в описании, контекст проектов, валидация (ТЗ 0.25)
...
- LLM предлагает короткий заголовок для перегруженных тайтлов и описание
с нумерованными шагами, если они очевидны
- в контекст добавлены открытые проекты с описаниями — назначение по смыслу
- теги: разрешены новые (1-2 при отсутствии подходящих), до 3, не обязательно один
- валидация ответа: заглушки «NULL»/пробелы отбрасываются, дубли схлопываются,
new_project без валидного имени не протекает; несуществующие теги создаются
при утверждении
- фронт: строки «Новый заголовок»/«Описание с шагами» в карточке предложения
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
10 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
11 hours ago
|
| 2026-09-20 |
Сад: инвентарь декораций — покупка кладёт на склад, 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
|
feat: метка «ментально сложная» — кнопка «Не хочется делать» + геймификация
...
- Task.mentally_hard (миграция c8f7e6d5b4a3) + поле в TaskUpdate/TaskOut
- compute_task_xp: +10 WILLPOWER_BONUS за закрытие «ментально сложной»
- заголовок X-Mentally-Hard при закрытии; +2 теста (66 зелёных)
- TaskView: warning-кнопка-переключатель в карточке статуса (скрыта у done)
- TaskBadges: warning-бейдж «ментально сложная»
- празднование: «+N XP • сила воли», золотое конфетти всегда, фраза в тосте
- сад: ачивка «Преодоление» 5/25/50; справка сада и локали ru/en/uk обновлены
- ТЗ 0.12: пункт про метку в 3.13
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
feat: прокачка геймификации — тиры ачивок, редкие растения, история (ТЗ 0.9)
...
- Редкие растения: редкость решается при закрытии по весу задачи (epic — только
крупные, rare — шанс растёт с XP), хранится в xp_events.rarity; в саду —
золото + бейдж (sparkle/crown), PATCH отдаёт X-Plant-Rarity
- Связка с «3 вариантами» (3.9): PATCH принимает earned_via="options",
xp_events.via_options, заголовок X-Options-Close; тост «выбрал и сделал»
- Празднование: «золотое» конфетти (56 частиц) на редкости/крупные закрытия,
тост с припиской о редком растении
- GET /api/xp/events — события начисления (для сада: редкости, счётчик, история)
- Сад: названия уровней (ботанические звания), «последний росток», история
закрытий по месяцам (12 мес), ачивки с тирами I/II/III + новые исследователи
(Спринтер, Разносторонний, Марафонец, Дедлайн-босс, Выбрал и сделал)
- Локали ru/en/uk, ТЗ 0.9 (п. 3.13 дополнен)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
feat: геймификация — XP, уровни, сад и ачивки (ТЗ 0.8, п. 3.13)
...
Награда за закрытие задачи, принцип «только позитив» (без стриков и сгорания):
- XP = 10 база + бонус за приоритет (0–15) + бонус за оценку времени (0–15),
один раз на задачу (xp_events, UniqueConstraint); удаление задачи не отнимает
- PATCH /api/tasks/{id} при первом закрытии ставит заголовок X-Earned-XP,
фронт ловит его и празднует: конфетти + тост «+N XP» с похвалой
- GET /api/xp — сводка (total_xp, уровень, прогресс)
- Сад (/garden): растение за каждую закрытую задачу + уровень + ачивки-вехи
(1/10/50 задач, уровни 5/10, регулярная, закрытый проект) с прогрессом
- celebrateEarned() в TaskView/ListView/ProjectView/OptionsView; локали ru/en/uk
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
| 2026-09-19 |
i18n: ru/en/uk, язык из gnexus auth + переопределение в настройках
...
- vue-i18n v11 (legacy:false, fallback ru); локали src/locales/{ru,en,uk}.ts,
en/uk типизированы как typeof ru — полнота проверяется vue-tsc
- резолюция: settings.language (override, ''=auto) → SSO profile.locale → ru
- backend: /auth/callback прокидывает profile.locale в сессию; /api/settings
получил поле language, PUT стал частичным (model_fields_set)
- taskui.ts и все views переведены на t(); дни недели и даты через Intl
- в Настройках — карточка «Язык интерфейса», переключение мгновенное
- тесты: test_settings.py (частичный PUT, 422), AUTH_USER += locale
- ТЗ 0.5: новый пункт 3.11 «Мультиязычность»
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
Дедлайны и регулярные задачи (ТЗ 3.4, 3.5)
...
- дедлайны двух видов: строгий (deadline_date) и нестрогий
(deadline_period: день/неделя/месяц/год); бейджи в дереве и списке,
просроченные — красным
- регулярные задачи: три правила (интервал N дней, дни недели, день месяца),
якорь — фиксированный календарь от даты выполнения; при завершении
автоматически рождается следующий экземпляр (API и MCP)
- «3 варианта»: срочность дедлайнов влияет на отбор (просроченные и близкие
строгие — первыми, затем нестрогие периоды)
- ТЗ 0.4: вопросы 8.1–8.3 помечены решёнными (правила повторения, прогноз,
валюта)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
Правки по обратной связи: прогноз = LLM, валюта в настройках, «3 варианта» +50%
...
- прогноз длительности: убрана медиана истории и эндпоинт /predict —
оценка приходит только из LLM-детализации (или вручную)
- валюта бюджетов — глобальная настройка (app_settings): UAH/USD/EUR/GBP/PLN,
выбирается один раз и применяется всюду; UI — страница «Настройки»,
суммы через formatMoney (символ по настройке)
- «3 варианта»: допуск нестрогий — оценка может превышать доступное время
до +50%, короткие задачи подходят всегда; задачи без оценки — фолбэк
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
M5: MCP-сервер для ИИ-агентов (ТЗ 3.9)
...
- FastMCP (streamable HTTP), монтируется на /mcp основного приложения
- инструменты: create_task / update_task / complete_task / list_tasks / get_task
- авторизация: bearer-токен MCP_TOKEN (пусто — /mcp закрыт); SSO-токены — после
предоставления данных (открытый вопрос ТЗ)
- автодетализация созданных агентом задач — в фоновом потоке
- lifespan: запуск session manager для mounted ASGI-приложения
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
M4: прогноз времени, бюджет, режим «3 варианта»
...
- Прогноз: LLM оценивает длительность в предложении детализации
(estimated_minutes в prompt/propose/apply); пересчёт по истории
похожих завершённых задач (медиана по проекту/тегам) — эндпоинт
POST /api/tasks/{id}/predict
- Бюджет: budget_money и cost_estimate_money (целые рубли) на задаче;
в дереве/списке — чип «бюджет / оценка» рядом
- «3 варианта»: POST /api/tasks/suggest — до трёх задач под доступное
время (активные проекты, не более одной на проект, сначала строго
укладывающиеся); вью OptionsView — выбор и переход к выполнению
- Миграция 09f0fefd5d6a (4 колонки tasks), 36 тестов зелёные
- Фронт: чипы оценок ≈ в дереве/списке, кнопка пересчёта прогноза,
поля бюджета и оценки в редакторе стека
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
M3: дерево подзадач, список с фильтрами, проекты с заметками
...
- Подзадачи: parent_task_id в create/patch, защита от циклов и
самородительства; relationships parent/children; фильтры списка
parent_id и tag_id
- Проекты: GET /api/projects/{id}, PATCH заметки и актуальности
- Фронт: TreeView — настоящее дерево с раскрытием ветвей и сменой
статуса; ListView — фильтры (статус/проект/тег); ProjectsView —
актуальность, приоритет, Markdown-заметка с предпросмотром
- Общие помощники статусов и Markdown в src/taskui.ts; GnPageHeader
переведён на слоты #meta/#actions (пропсы meta у кита нет)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
M2: автодетализация (Ollama) и вложения
...
- LLM-детализация в фоне при быстром захвате: черновое предложение
тегов/проекта/приоритета (только из существующего справочника),
применяется только при утверждении («Да, всё верно»)
- Эндпоинты approve (apply_proposal) и redetail; Attachment-модель и
API вложений (изображения, FileResponse)
- Важное исправление: в FastAPI 0.141 фоновые задачи выполняются до
teardown-коммита зависимости get_db — create/redetail теперь коммитят
явно, иначе background worker не видит задачу
- Тесты detailing/attachments с моком LLM; tests как пакет (иначе
дублировался модуль conftest и в памяти оказывались две БД)
- Фронт: чипы предложения, опрос стека, Markdown-редактор с
предпросмотром (marked + DOMPurify), вставка изображений Ctrl+V
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
M1: MVP задач — быстрый ввод, стек входящих, ручная детализация
...
- Модели Task/Project/Tag (SQLAlchemy 2.0) + миграция alembic
- API: POST/GET/PATCH/DELETE /api/tasks, approve (raw→approved), проекты, теги
- Все /api эндпоинты за сессией SSO (регрессионный тест на 401)
- Frontend: api-клиент, StackView — быстрый ввод одной строкой, стек,
детализация с проектом/тегами/приоритетом, «Да, всё верно»
- dev-БД: docker postgres:17 на 15432
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
Порт API 8134 вместо 8000; креды локального SSO в .env (не коммитится)
...
- Dockerfile, nginx, vite proxy, README — единый нестандартный порт 8134
- тест redirect привязан к gauth_base_url из настроек, а не к прод-хосту
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
M0: OAuth-флоу через gnexus-gauth
...
- /auth/login → redirect на SSO с PKCE, /auth/callback → обмен code, сессия-cookie
- /auth/logout, /auth/me, защищённый /api/me
- SessionMiddleware (подписанная HttpOnly cookie, секрет из окружения)
- frontend: Войти/Выйти в навбаре, proxy /auth на backend
- тесты: health, защита API, redirect с state/PKCE
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|