220 Commits

Author SHA1 Message Date
Andrey Epifancev
def3d72935 chore(openspec): design.md — поведение повторного seed приведено к факту; tasks.md 5.1/5.2 (T15.1, T15.2)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 01:56:48 +04:00
Andrey Epifancev
7b75981d0f docs: README/CLAUDE.md Среза 1, тест маршрутов OpenAPI, tasks.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 01:45:13 +04:00
Andrey Epifancev
fda907ba2e chore(openspec): рулинг R-21 (решения Task 14) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 01:28:13 +04:00
Andrey Epifancev
d3c2f8ab1f feat(web): страница администратора — пользователи, роли, матрица прав
Маршрут /admin (вкладки «Пользователи» и «Матрица прав») и пункт «Система → Пользователи и роли» в меню;
без USERS_ADMIN в /me — экран «Нет доступа», таблицы не монтируются и запросов к /admin/* нет, пункт меню скрыт.

Почему без Redux: данные экрана нужны только ему, после каждой правки перечитываются с сервера — хватает
локального state и маленького хука useAsyncData (отбрасывает устаревшие ответы и ответы после ухода со страницы).
Клиент один — api/client.ts (Bearer из sessionStorage, ошибки сервера -> ApiError с кодом и текстом); ошибки
показываются через App.useApp().message (корень обёрнут в antd App). Экран показывает только серверное состояние:
при отказе (409 LAST_ADMIN и др.) — уведомление и перечитывание, матрица сохраняет роли по очереди.
РАИСА появится в auth/: токен даст SSO вместо dev-входа; этот экран и клиент не меняются.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 01:04:32 +04:00
Andrey Epifancev
a7502f6315 chore(openspec): рулинг R-20 (решения Task 13) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 00:53:56 +04:00
Andrey Epifancev
498450b763 feat(web): API-клиент с Bearer, dev-вход по email, загрузка /me
Токен хранится в sessionStorage (design D-9; без Redux): живёт до закрытия вкладки, все обращения к хранилищу в try/catch с запасным токеном в памяти.
apiFetch подставляет Bearer, на 401 сбрасывает токен и шлёт событие armka:unauthorized, ошибки разбирает по трём формам detail (строка / {code,message} / массив 422).
useMe не ходит в /me без токена и отбрасывает устаревшие ответы (флаг cancelled), AuthGate показывает вход, пока профиля нет.
Форма DevLogin вырезается из production-сборки по литералу process.env.NODE_ENV; через Config это не работает: process.env там заменён объектом REACT_APP_*.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 00:23:56 +04:00
Andrey Epifancev
6217e4e123 chore(openspec): рулинг R-19 (решения Task 12) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 00:20:33 +04:00
Andrey Epifancev
800f3a49c4 feat(admin): пользователи, роли, матрица прав — API с аудитом и защитой LAST_ADMIN
/api/v1/admin/* под правом USERS_ADMIN (403 на всё без него): список пользователей
(поиск по email/ФИО, is_active, Page), создание (email уникален без учёта регистра →
409 EMAIL_EXISTS, роли — коды активных ролей → 422 UNKNOWN_ROLE), PATCH полей и
деактивация, PUT ролей (замена набора с diff), GET ролей с правами, GET справочника
прав (16 кодов), PUT прав роли (422 UNKNOWN_PERMISSION, granted_by/granted_at).
Аудит USER_CHANGE / USER_ROLE_CHANGE (USERS) и ROLE_PERMISSION_CHANGE (ACCESS);
повтор того же состояния аудит не пишет.

LAST_ADMIN: деактивация (в том числе себя), замена ролей и снятие USERS_ADMIN с роли
запрещены, если у активных пользователей через активные роли не останется USERS_ADMIN.
Гонки: строка пользователя/роли и строка права USERS_ADMIN блокируются FOR NO KEY
UPDATE (FOR UPDATE давал deadlock на FK-проверке вставки audit_event); тест двух
параллельных транзакций с барьером.

Задача плана Task 12, tasks.md 4.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 00:07:07 +04:00
Andrey Epifancev
83746e694e chore(openspec): рулинг R-18 (решения Task 11) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 23:50:01 +04:00
Andrey Epifancev
c9cd839e59 test(import): dry_run полной выгрузки ЕЦП (8400 строк) укладывается в 60 с
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 23:37:54 +04:00
Andrey Epifancev
58075e9445 chore(openspec): рулинг R-17 (решения Task 10) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 23:32:21 +04:00
Andrey Epifancev
c9c3b69076 feat(directories): импорт выгрузки ЕЦП — сервис, эндпоинт, аудит, файл в S3
POST /api/v1/directories/import (DIRECTORY_ADMIN, multipart: file, dry_run=true, on_existing=skip):
снимок справочника тремя запросами (load_snapshot), план ядра §13.2, применение пакетами по типу
операции; UpdateGroup/UpdateEntity — apply_group_update/apply_entity_update (R-14) с description
«импорт ЕЦП». dry_run — явный session.rollback(), без аудита и S3. Боевой прогон —
audit_event(DIRECTORY_IMPORT, after_value = отчёт) и файл uploads/imports/{event_id}/{имя} +
s3_object(uploads). IMPORT_MAX_BYTES (20 МБ) → 413; ошибки файла → 422 MISSING_COLUMNS/UNSUPPORTED_FILE.
Тест dry_run — на отдельной БД с сессией запроса как в проде (SAVEPOINT-обёртка db_session
при rollback снимает и seed теста).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 23:15:26 +04:00
Andrey Epifancev
7f14e70aef chore(openspec): рулинги R-14…R-16 (design #25–27), спека/план приведены к факту фикстур
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 22:41:41 +04:00
Andrey Epifancev
df8a5285bb feat(domain): ядро импорта справочников из выгрузки ЕЦП (§13.1–13.2)
- domain/directory_import.py: read_rows (xlsx первый лист / csv UTF-8 `;`/`,`,
  заголовки по нормализованному тексту, MISSING_COLUMNS / UNSUPPORTED_FILE),
  plan_import — чистая функция: операции плана и отчёт с кодами §13.2,
  ASSUMPTION(OQ-87..91); ИНН — через domain/inn.py.
- openpyxl==3.1.5 (+ et_xmlfile==2.0.0) в requirements.txt,
  types-openpyxl в requirements-dev.txt.
- Тесты без БД: нормализация, чтение csv/xlsx (Review Focus 1–3), каждый код
  §13.2, skip/update, фикстура «Русский Бисквит» (ФЛ в строке 12 → UNSUPPORTED_TYPE).
- План фазы 2: Task 9 отмечена; tasks.md 3.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 22:29:52 +04:00
Andrey Epifancev
dd176a3c69 chore(openspec): рулинги R-12, R-13 (design #23–24)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 22:20:42 +04:00
Andrey Epifancev
b5a83245e7 chore(openspec): рулинг R-11 (решения Task 8), tasks.md 1.2/2.1 приведены к фактическим именам
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 22:14:46 +04:00
Andrey Epifancev
a04d9db478 chore(directories): отметить Task 8 (2.5) и завершение фазы 1 в плане и tasks.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 22:08:04 +04:00
Andrey Epifancev
69d641c14e chore(openspec): рулинг R-10 (решения Task 7) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:54:52 +04:00
Andrey Epifancev
a19875dbe3 chore(directories): отметить Task 7 (2.4) в плане и tasks.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:53:13 +04:00
Andrey Epifancev
e03f97946f chore(openspec): рулинг R-9 (решения Task 6) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:47:57 +04:00
Andrey Epifancev
347b46e32c feat(directories): ЮЛ/ИП — CRUD, перевод, вывод из состава, история, аудит
- domain/inn.py: нормализация и проверка ИНН (ЮЛ — 10, ИП — 12 цифр 0–9), ASSUMPTION(OQ-88)
- репозиторий: список ЮЛ с видимостью и фильтрами (company_group_id, outside_group, inn точно, q по name/inn),
  карточка, история (по убыванию valid_from), текущие членства, close_memberships (SCD2), алиасы
- LegalEntityService: create (INN_EXISTS, CRM_ID_EXISTS, ГК через scope → 404, филиал по умолчанию — филиал ГК),
  update (no-op без истории; снимок UPDATE), move (MOVE_TO_GROUP, закрытие членств, MEMBERSHIP_CHANGE),
  withdraw (CLOSE / REMOVE_FROM_GROUP), effective_date ≥ сегодня — ASSUMPTION(OQ-21)
- эндпоинты /directories/legal-entities: GET/POST, GET/PATCH /{id}, /{id}/move, /{id}/withdraw, /{id}/history
- тесты: unit ИНН, интеграционные сценарии спеки, Review Focus 1–3, откат мутации

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:41:17 +04:00
Andrey Epifancev
69769cc302 chore(openspec): рулинг R-8 (решения Task 5) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:30:43 +04:00
Andrey Epifancev
80e8905e68 feat(directories): филиалы и ГК — API, история, аудит, видимость
Репозиторий, сервис и эндпоинты /api/v1/directories/{regional-offices,company-groups}:
код GK-NNNNNN из последовательности, снимки в company_group_history, no-op PATCH
без истории и аудита, поиск q по name/crm_id/code с экранированием LIKE, видимость
по филиалу (чужая ГК = 404 как несуществующая), аудит GROUP_CHANGE/ASSIGNMENT_CHANGE.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:28:06 +04:00
Andrey Epifancev
01187b550d chore(openspec): рулинг R-7 (policy: подзапрос IN вместо outerjoin) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:21:12 +04:00
Andrey Epifancev
d142c6f69e feat(domain): policy видимости справочников (§10.1, ASSUMPTION(OQ-86))
Первый модуль src/domain/ (чистые функции, без I/O, mypy strict): VisibilityScope,
scope_for/scope_of, SQL-фильтры company_groups_visible/legal_entities_visible,
проверки company_group_is_visible/legal_entity_is_visible, office_for_create
(чужой филиал → 422 OFFICE_NOT_ALLOWED). Код роли не читается; business_segment
не фильтрует (ASSUMPTION(OQ-86)). Принадлежность ЮЛ ГК филиала — подзапросом IN,
а не JOIN (число строк не меняется, нет конфликта с JOIN вызывающего).

Тесты: unit без БД (компиляция Select под PostgreSQL, все ветки) + один
integration-тест семантики фильтров и их согласованности с проверками объектов.
Отмечены шаги Task 4 в плане и 2.1 в tasks.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:17:58 +04:00
Andrey Epifancev
8eb8592452 test: фабрики справочников, фикстуры app/auth_client/seeded
Фабрики ГК/ЮЛ/ГСК/членства/пользователя (flush, без commit), фикстуры seeded/app/auth_client
в conftest (override сессии через begin_nested), test_me_and_dev_token переведён на общие
фикстуры (сочетания флагов остались на локальном _build_app), test_factories.py проверяет фабрики.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:10:41 +04:00
Andrey Epifancev
cd6cca32f2 chore(openspec): рулинг R-6 (SessionDep, scope=function) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:04:26 +04:00
Andrey Epifancev
5976986e1b feat(api): транзакция на запрос, RequestAudit, доменные ошибки 404/409/422, Page
- get_async_session: одна транзакция на запрос (commit при успехе, rollback при исключении), R-1;
  объявляется только через SessionDep (scope="function") — commit до отправки ответа, одна сессия
  на все зависимости запроса; current_user и dev-эмитент переведены на SessionDep.
- DomainError/NotFoundError/ConflictError/DomainValidationError + обработчик
  {"detail": {"code", "message", ...}}; ответы HTTPException и ошибок БД не меняются.
- RequestAudit/get_request_audit: AuditService.record с user_id, ip_address, user_agent запроса.
- schemas/common.py: Page[T], PageParams (limit 1..200, по умолчанию 50; offset >= 0), ErrorDetail.
- tests/test_uow_and_errors.py: формат ошибок, пагинация, аудит, scope сессии во всех маршрутах,
  настоящий commit/rollback на временной БД, commit до http.response.start, ошибка commit -> 409.
- План: Task 2 отмечена; tasks.md: 1.2 отмечен.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 21:03:07 +04:00
Andrey Epifancev
c80e029b96 chore(openspec): D-1 приведён к фактической миграции 0002
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 20:53:24 +04:00
Andrey Epifancev
3a0ee80504 chore(openspec): рулинг R-5 (миграция 0002 пересоздаёт related_group_member) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 20:50:55 +04:00
Andrey Epifancev
458392e94d feat(model): DBML v5.14 — related_group_member.kind, audit_action +2, миграция 0002, последовательности кодов
- RelatedGroupMember.kind (related_group_kind, NOT NULL) между legal_entity_id и valid_from, как в DBML;
  частичный уникальный индекс uq_related_group_member_entity_kind_current (legal_entity_id, kind) WHERE is_current —
  ЮЛ одновременно в одной ГСК и одной ГСЗ.
- AuditAction: LEGAL_ENTITY_CHANGE (после GROUP_CHANGE), USER_CHANGE (после USER_ROLE_CHANGE).
- Последовательности company_group_code_seq / related_group_code_seq в metadata (design D-5).
- Миграция 0002_dbml_v5_14: related_group_member пересоздаётся с переносом строк (kind из группы), чтобы порядок
  колонок совпал с DBML и create_all; ALTER TYPE ADD VALUE ×2; downgrade пересоздаёт audit_action v5.13.
- DBML_VERSION = 5.14, пути к data-model-v5.14.dbml (Makefile, dbml_parity), тесты: откат на шаг, перенос строк,
  уникальность gsk+gsz, офлайн-SQL до head.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 20:49:32 +04:00
Andrey Epifancev
13d11c074f chore(openspec): рулинги R-2..R-4 (SDD фаза 1, pre-flight) в design.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 20:41:12 +04:00
Andrey Epifancev
44806c8403 chore: план исполнения Среза 1 (две фазы) и рулинг R-1 в design.md
docs/superpowers/plans/2026-10-04-slice-1-directories-phase{1,2}.md — 15 задач из tasks.md change'а
slice-1-directories: модель v5.14 и инфраструктура запросов, policy, API справочников (фаза 1); импорт ЕЦП,
администрирование, экран /admin, документы и check-full (фаза 2).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 20:37:47 +04:00
Andrey Epifancev
39a7affc48 OpenSpec: change slice-1-directories (справочники, импорт ЕЦП, policy, администрирование)
proposal, design, tasks и дельты спек: directories-api, directory-import, directory-policy, users-admin (новые),
data-model (v5.14: related_group_member.kind, audit_action), audit-trail (события справочников и администрирования).

Issue: RSHB/arm-core#5

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 20:23:03 +04:00
Andrey Epifancev
db7df33517 chore(openspec): архив change slice-0-skeleton
Срез 0 реализован и влит (PR #3), change перенесён в openspec/changes/archive, спеки — в openspec/specs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 19:44:37 +04:00
Andrey Epifancev
477f037872 docs: сценарий «Системное событие» под R-7, решения 98–105 в design.md (I-4)
audit-trail: WHEN сценария «Системное событие» — «системный процесс (без
пользователя) вызывает сервис аудита»; NOTE: обмен через recognition_job
в Срезе 0 аудит не пишет (R-7, design #20). design.md: R-25, R-26 и
решения fix-волны финального ревью (№100–105). openspec validate --strict
проходит.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 02:01:41 +04:00
Andrey Epifancev
db3c1e5141 docs: предложения открытых вопросов в change slice-0-skeleton (I-5, R-26)
openspec/changes/slice-0-skeleton/open-questions-proposal.md — носитель
15 предложенных вопросов, правок статусов OQ-46/OQ-47 и кандидатов в DBML
v5.14 для docs-PR (открывает владелец ../docs); архивируется вместе с
change. Добавлены пункты финального ревью: аудит LOGIN/LOGIN_FAILED,
CORS * и доверенные прокси, открытые /docs и /openapi.json, статус
stored_file из inbox, срок ответа tabular, append-only на уровне БД,
последовательный callback NATS и длинный маппер, проверка ключа
results/{file_id}/{job_id}/ до чтения результата.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 02:01:41 +04:00
Andrey Epifancev
a880330f1f docs: design.md — решения 24–97 (рулинги контроллера и решения исполнителей, SDD срез 0)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 01:21:59 +04:00
Andrey Epifancev
f7bde3f82f chore: отметка задачи 27
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 01:18:12 +04:00
Andrey Epifancev
18126eeb8f docs: команды make и фактическое устройство в CLAUDE.md, выправлены формулировки tasks/plan/spec
CLAUDE.md: цели make из корня, NATS_ENABLED vs DEBUG, обмен recognition_job, аудит, аутентификация, seed,
сверка ORM-DBML, тесты; Dockerfile для dev и check-full; skip reason у fixtures.
tasks.md/plan: required_document_rule в audit_ex.py (R-4); spec data-model: 43 таблицы модели + alembic_version.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 01:16:56 +04:00
Andrey Epifancev
b3f7deae22 chore: отметка задачи 26
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 01:12:24 +04:00
Andrey Epifancev
d4a29748f5 chore: отметка задачи 25
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 00:59:24 +04:00
Andrey Epifancev
0b4fa3a819 chore: отметка задачи 24
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 00:46:54 +04:00
Andrey Epifancev
c5a5c0bf29 chore: отметка задачи 23
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 00:20:12 +04:00
Andrey Epifancev
a0de203d88 chore: отметка задачи 22
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 23:48:55 +04:00
Andrey Epifancev
1c51fb5459 chore: отметка задачи 21
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 23:21:30 +04:00
Andrey Epifancev
0837e18a0a chore: отметка задачи 20
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 23:01:34 +04:00
Andrey Epifancev
0c1e1b94b2 chore: отметка задачи 19
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 22:39:56 +04:00
Andrey Epifancev
64668085ab chore: отметка задачи 18
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 22:29:02 +04:00
Andrey Epifancev
aaf9490a8d chore: отметка задачи 17
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 22:14:29 +04:00