| 2026-09-21 |

Пачка 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
|

Пачка 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
|
«Новая задача» в шапке проекта: на мобильном — кнопка-иконка
...
size="sm" (плитка иконки 32px вместо 46px) + на ≤640px лейбл скрывается,
кнопка сжимается до компактной 54x38 — как «+» топбара.
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 |
Сущность «документ»: описания и заметки — единый текст с вложениями
...
- Новая таблица 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
|
Фикс стилизации инлайн-редакторов: 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
|
Инлайн-редактирование полей на страницах задачи и проекта
...
- Новый компонент 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
|
Баг: переход подзадача → родитель не обновлял данные страницы
...
/vue-router переиспользует инстанс TaskView при переходе между
/tasks/:id — onMounted не срабатывает, экран оставался на старой
задаче. Данные теперь перезагружаются по watch(taskId); заодно
сбрасывается режим правки. Та же защита добавлена в ProjectView.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
Разгрузка формы создания: «Дополнительно» свёрнуто, редирект на задачу
...
- Оценки (время, затраты) и дедлайн в TaskForm свёрнуты в GnAccordion
«Дополнительно»: при создании скрыты (детализация — позже), при правке
раскрыты по умолчанию.
- После создания задачи из стека (StackView) и со страницы проекта
(ProjectView) пользователь направляется на страницу созданной задачи —
там блоки заполняются через «Редактировать».
- Локали: stack.form.extra (ru/en/uk).
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day 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
1 day ago
|
feat(frontend): переименование в GNexus Tasks, тайтлы страниц
...
- Сервис «gntodo» → «GNexus Tasks»: brand топбара, kicker шапок видов,
subtitle навигации (ru/en/uk), index.html, PWA-манифест (short_name Tasks)
- taskui: APP_NAME + setPageTitle(); тайтлы через meta.title роутов
(afterEach в main.ts) — «{страница} — GNexus Tasks»
- TaskView/ProjectView уточняют тайтл после загрузки (watchEffect):
заголовок задачи / имя проекта
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
1 day ago
|
| 2026-09-19 |
Иконки заголовков карточек — ещё темнее (#3b4261)
...
Заодно убраны scoped-дубли .card-title-icon в TaskView/ProjectView
(var(--accent) перебивал глобальный тёмный цвет)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
Убираем дерево задач; иконки заголовков — тёмные
...
- Удалены TreeView (роут /tree и пункт навигации) и TaskTree;
переключатель «Список | Дерево» на странице проекта убран —
остаётся список карточек
- В локалях почищены мёртвые ключи дерева (nav.tree, viewList/
viewTree, tree.* кроме addSubtask/promptSubtask)
- Иконки в заголовках карточек — тёмный #565f89 вместо фиолетового
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
Добавление задач — полная форма; подзадачи карточками
...
- TaskForm умеет создавать: проп task опционален, дефолты из
projectId/parentId (create + PATCH, тост «Создано — попала в стек»)
- Подзадача на странице задачи — полная форма в drawer (было
окно-промпт одной строкой)
- Новая задача из проекта — полная форма в drawer
- В стеке кнопка «Новая задача» (шапка) открывает полную форму;
quick-add одной строкой остаётся как опция
- Подзадачи на странице задачи — классические карточки TaskCard
(заголовок-ссылка, сниппет, бейджи, меню) вместо дерева
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
UX-пачка: заметка проекта через MdEditor, троеточие, фиксы шапки
...
- Заметка проекта в drawer'е — тот же MdEditor с тулбаром, что у
описания задачи (новый проп caption; предпросмотр-чекбоксы убраны)
- Кнопка «Действия» в шапке задачи — иконка-троеточие (ph-dots-three)
- «Изменить статус» — маленькая кнопка (size sm)
- Дропдаун шапки не обрезается: overflow:visible у .page-header
(+ декоративная скан-полоска ::after скрыта — с visible overflow
вылезает за рамку); меню прижато к правому краю; z-index шапки
поднят — transform из panel_boot кита делал карточки поверх меню
- Иконки в заголовках карточек — фиолетовый #bb9af7 (сливались)
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
Задача и проект: UX-пачка из 7 правок
...
- Действия задачи (статусы/правка/переспрос/подзадача/удаление) —
в дропдаун-меню «Действия» в шапке вместо тулбара
- Карточка «Статус» в сайдбаре: бейдж статуса + явная кнопка
«Изменить статус»
- Понятная шкала приоритета: 5 градаций с цветом (очень низкий/
низкий/средний/высокий/срочно) вместо P0–P10 — в карточках,
на страницах задачи и проекта, в формах
- Быстрое добавление тега прямо в карточке «Теги» (GnTagInput,
новое имя создаёт тег в каталоге)
- «Добавить подзадачу» создаёт полноценную задачу с parent_id
(тост-подтверждение; подзадача сразу видна в дереве)
- Фильтры страницы проекта переоформлены: подписанные селекты
со сбросом
- Список/дерево проекта — переключатель вида (GnTabs) вместо
двух секций подряд
Шкала приоритета: grade в UI, число 0–10 в БД; ProjectsView —
drawer переведён на градации.
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
Страница проекта: двухколоночная раскладка, статистика, вход из списка
...
- Список проектов: заголовок карточки — ссылка на /projects/:id
(раньше страница не была достижима), бейдж со счётчиком задач
- Страница проекта: сетка «содержимое + сайдбар» как на странице задачи;
заметка всегда видна (с подсказкой, если пуста), прогресс, фильтры
статус/тег с иконками, карточки задач, дерево проекта
- Сайдбар: статистика (всего/завершено/в работе/к выполнению/просрочено
с подсветкой), параметры, теги проекта с количеством
- Исправлено: GnBadge не имеет пропа icon — иконки везде переложены
в слот (TaskBadges, шапки проектов, теги задачи); несуществующая
иконка ph-list-magnifying-glass заменена на ph-magnifying-glass
- Сниппет карточки задачи больше не показывает сырой markdown
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|
feat(frontend): страницы задачи и проекта, карточки, наглядное дерево
...
- /tasks/:id — полная страница задачи: просмотр/редактирование (TaskForm),
статусы, предложение ИИ, описание md + вложения, параметры, подзадачи
- /projects/:id — страница проекта: заметка, прогресс, задачи с фильтрами,
дерево проекта, создание задачи в проект (create + PATCH project_id)
- общие компоненты: TaskForm (вынесена из drawer'а стека), TaskCard
(заголовок-ссылка, сниппет, меню), TaskTree (шевроны, линии связей,
прогресс поддерева)
- стек: drawer на TaskForm, quick-add — многострочное поле (Enter — закинуть)
- .app-content 1200px, ключи i18n task.*/projectPage.*, ru/en/uk
Co-Authored-By: Claude Code <noreply@anthropic.com>
root
committed
2 days ago
|