Files
main/README.md
T
ksv741 7e382d460b
Conventional commits / commits (pull_request) Successful in 10s
feat: add containerized application delivery #11
2026-09-16 09:42:13 +03:00

243 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WealthLedger
Локальное приложение для портфеля T-Bank, операций, дохода и будущих выплат,
а также ручного учёта банковских карт и расходов.
[Обзор продукта](https://git.personal.ksv741.ru/WealthLedger/docs/src/commit/c557af4ea51cd3c578d0755e909e62e06462b5bc/overview.md) и [документация системы](https://git.personal.ksv741.ru/WealthLedger/docs/src/commit/c557af4ea51cd3c578d0755e909e62e06462b5bc/README.md).
## Структура workspace
Workspace состоит из пяти независимых Git-репозиториев. Root — репозиторий
`WealthLedger/main`; вложенные checkout не являются submodules.
| Путь от root | Репозиторий Gitea | Назначение |
| --- | --- | --- |
| `.` | `WealthLedger/main` | Вход в workspace, инструкции и правила root tracking |
| `frontend/` | `WealthLedger/frontend` | [React/Vite UI](https://git.personal.ksv741.ru/WealthLedger/frontend/src/commit/9f7e342333b80bfacfd5bc394a2dcd0613d33ff3/README.md) |
| `backend/` | `WealthLedger/backend` | [NestJS API, Prisma и SQLite](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/README.md) |
| `docs/` | `WealthLedger/docs` | [Объяснение системы](https://git.personal.ksv741.ru/WealthLedger/docs/src/commit/c557af4ea51cd3c578d0755e909e62e06462b5bc/README.md) |
| `specs/` | `WealthLedger/specs` | [Требования и OpenSpec](https://git.personal.ksv741.ru/WealthLedger/specs/src/commit/9e227a563dda67620f0ad78228aa8a4c18bf35a0/README.md) |
### Получение checkout
Нужны Git и SSH-доступ к Gitea на порту 2222. Из родительского каталога,
где ещё нет `WealthLedger`, выполните:
```bash
git clone ssh://git@git.personal.ksv741.ru:2222/WealthLedger/main.git WealthLedger
cd WealthLedger
git clone ssh://git@git.personal.ksv741.ru:2222/WealthLedger/frontend.git frontend
git clone ssh://git@git.personal.ksv741.ru:2222/WealthLedger/backend.git backend
git clone ssh://git@git.personal.ksv741.ru:2222/WealthLedger/docs.git docs
git clone ssh://git@git.personal.ksv741.ru:2222/WealthLedger/specs.git specs
```
Для существующего workspace клонируйте только отсутствующие checkout в пустые
каталоги. Проверяйте состояние каждого repo отдельно, например
`git -C frontend status`. Обновление main не обновляет соседние repos;
общего lockfile revisions нет. Такая раскладка удобна для совместной работы,
но каждый checkout можно использовать отдельно.
### Что хранится в main
Root отслеживает входные документы, собственные engineering conventions и исторический migration
inventory в `.ai/`, npm/release-конфигурацию, changelog,
Compose configuration, безопасные env examples и один CI workflow с commitlint. Точный allowlist — в `.gitignore`.
Остальные root-пути игнорируются по умолчанию:
вложенные repos, `.env`, базы и WAL, импорты выписок, PDF, `references/`,
`design/`, `todo/` и локальные настройки инструментов.
Новый общий файл включается отдельной правкой allowlist после проверки содержимого.
Перед commit смотрите `git diff --cached --name-status` в нужном repo.
Не используйте `git add -f` для обхода границ root. Ignore не защищает уже
отслеживаемые файлы и не меняет правила внутри вложенных repos.
Не запускайте очистку workspace через `git clean -fdx`: ignored-пути содержат
локальные данные. Правила tracking не удаляют файлы и вложенные `.git`.
## Запуск через Docker Compose
Нужны Docker Engine и Compose >= 2.24.4, а для development — checkout
`frontend/` и `backend/` рядом с root. Компоненты собираются независимо:
```bash
docker compose --env-file .env.development.example \
-f compose.yaml -f compose.development.yaml up -d --build --wait --wait-timeout 180
```
Откройте `http://localhost:5173`: Vite HMR и `/api/` используют один origin,
Nest работает в watch mode. Host `node_modules` и `.env` не монтируются.
Данные development хранятся отдельно в named volume `development-data` проекта `wealthledger-dev`;
обычные restart/down их сохраняют. Изменение dependencies/config требует rebuild.
Production использует `compose.yaml` и restricted env по `.env.compose.example`:
две ссылки на опубликованные версии images, persistent absolute host data path,
постоянные JWT/encryption secrets и публичный HTTPS origin. Каталог данных
должен существовать и принадлежать UID/GID 1000:1000. Только frontend публикует
`127.0.0.1:8080`; серверный Caddy направляет туда весь домен. Backend port
остаётся внутренним, migration service использует тот же backend image.
Полная процедура установки, независимых обновлений, stopped-backend backup
и explicit restore — [документация](https://git.personal.ksv741.ru/WealthLedger/docs),
страница `architecture/deployment.md`.
Перед backend update обязательны остановка, backup и успешная migration.
Image rollback не восстанавливает старую базу. Публикация component images
принадлежит их Gitea workflows; root CI остаётся только commitlint.
## Подготовка и запуск
Нужны nvm и Node из `.nvmrc` каждого npm-repo (сейчас 24.21.0, npm 11.19).
Во всех пяти репозиториях отдельно выполните
`nvm install`, `nvm use --silent`, `npm ci`. В root и specs npm нужен для release-it
и проверки сообщений коммитов.
После смены major Node переустановите native dependencies через `npm ci`.
Разрешения install scripts заданы в `package.json` соответствующего repo.
Для нового backend создайте `.env` по [backend README](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/README.md),
замените оба placeholder-секрета и проверьте `DATABASE_URL`.
Существующий `.env` сохраняйте. Из backend:
```bash
nvm use --silent
npm run build
npx prisma migrate deploy
npm run start:dev
```
Build генерирует Prisma client. Перед миграцией существующей базы сохраните
согласованный backup и ключ шифрования; процедуру и ограничения отката смотрите
в [описании хранения](https://git.personal.ksv741.ru/WealthLedger/docs/src/commit/c557af4ea51cd3c578d0755e909e62e06462b5bc/architecture/containers.md#сохранение-и-восстановление-данных).
Известная ошибка fresh migration при `RUST_LOG=warn/error` устранена в
`backend/prisma.config.ts`: CLI удаляет унаследованную переменную.
Используйте штатный `prisma migrate deploy` из backend; прежний Prisma blocker
снят. [Подробности и границы проверки](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/README.md#реальная-sqlite-и-сохранность-данных).
В другом терминале подготовьте `.env` по [frontend README](https://git.personal.ksv741.ru/WealthLedger/frontend/src/commit/9f7e342333b80bfacfd5bc394a2dcd0613d33ff3/README.md),
затем из frontend:
```bash
nvm use --silent
npm run dev
```
Стандартные адреса: frontend `http://localhost:5173`, API
`http://localhost:3000`. Origin backend и адрес API frontend должны совпадать
с выбранными адресами. T-Bank token вводится через настройки приложения;
без него доступны вход и ручной банковский учёт.
Для вымышленных UI-примеров выполните `npm run dev:catalog` из frontend.
### OpenSpec
OpenSpec не нужен для запуска приложения и применяется по явному запросу.
Specs использует Node из своей `.nvmrc`; проверенная версия CLI — 1.10.0.
Store `wealth-ledger-specs` расположен в `specs/openspec/`.
[Работа с OpenSpec](https://git.personal.ksv741.ru/WealthLedger/specs/src/commit/9e227a563dda67620f0ad78228aa8a4c18bf35a0/AGENTS.md), [команды validation](https://git.personal.ksv741.ru/WealthLedger/specs/src/commit/9e227a563dda67620f0ad78228aa8a4c18bf35a0/README.md#проверка).
## Проверки
Перед npm-командами активируйте `.nvmrc` соответствующего repo.
| Где | Команда | Что проверяет |
| --- | --- | --- |
| root | `npm exec --no -- commitlint --strict --from <base> --to <head>` | Формат сообщений коммитов |
| root | `git diff --check` | Whitespace в изменениях root |
| frontend | `npm run verify` | Типы, lint, тесты, зависимости, OpenAPI snapshot и сборки |
| backend | `npm run verify` | Lint, типы, unit tests и build |
| backend | `npm run test:e2e` | HTTP/SQLite suites и локальный OpenAPI artifact |
| docs | `npm run verify` | Markdown, относительные ссылки и diff |
Root CI выполняет только commitlint: проверяет сообщения коммитов и заголовок PR.
Allowlist root проверяется вручную по staged paths. Backend e2e использует
временные базы; verify отдельно не доказывает HTTP/DB-сценарии или доступность
T-Bank. Полные команды и ограничения принадлежат README
[frontend](https://git.personal.ksv741.ru/WealthLedger/frontend/src/commit/9f7e342333b80bfacfd5bc394a2dcd0613d33ff3/README.md#проверка) и [backend](https://git.personal.ksv741.ru/WealthLedger/backend/src/commit/016782657acfd35ff3fd755462007938fac35156/README.md#проверка).
Для изменения проекта начните с [AGENTS](AGENTS.md).
## Релизы и ветки
Все пять репозиториев выпускаются независимо. Первый релиз — `0.1.0`;
версия в `package.json` и lockfile соответствует последнему принятому тегу
`vX.Y.Z`. Root-репозиторий называется `main`, его ветки — `main` и `develop`.
`main` хранит принятые релизы, `develop` — интеграцию разработки. Новая задача:
отдельная ветка от свежего `develop`, затем PR в `develop`. Для веток агента
используется `codex/<task>`; также допустимы `feature/<task>` и `fix/<task>`.
В `main` напрямую не пушить. Обычные PR можно squash-merge; релизные PR и
обратную синхронизацию `main` с `develop` сливать с сохранением истории.
Commits и заголовки PR — Conventional Commits. `feat:` повышает minor,
`fix:`/`perf:` — patch, `!` или `BREAKING CHANGE:` — major, в том числе до 1.0.
`docs:`, `spec:`, `chore:`, `build:`, `ci:`, `refactor:`, `test:`, `style:` и
`revert:` дают patch при выпуске. `chore(release):` — служебная запись,
исключённая из changelog и рекомендации версии. Release-it не запускается
автоматически после каждого commit. Номер связанной issue можно добавить в заголовок.
### Подготовка релиза
1. Обновить `main`, `develop` и теги командой `git fetch origin --tags`.
Проверить, что текущий `develop` содержит последний релиз из `main`.
Создать `release/<name>` от проверенного `develop` и выполнить `npm ci`.
2. Проверить локальные входы и публичные artifacts выпускаемого репозитория.
Совместимость развёрнутых участников согласовать отдельно через публичные
контракты; CI не скачивает соседние checkout и не требует их SHA.
3. Выполнить `npm run release:preview`. Проверить номер и changelog, затем
`npm run release:prepare`. Команда создаёт `chore(release): X.Y.Z`, обновляет
`package.json`, lockfile и `CHANGELOG.md`; теги и push не выполняет.
В root встроенные проверки release-it контролируют ветку, чистое дерево и
наличие коммитов. Теги и соответствие версии последнему принятому тегу
проверяются вручную; уже подготовленную версию повторно не повышать.
4. Проверить diff релизного коммита и штатные gates. Отправить только релизную
ветку: `git push -u origin HEAD`. Открыть PR в `main` с заголовком
`chore(release): X.Y.Z`. После зелёных обязательных проверок (`commits` в root;
`verify`, `security`, `commits` в остальных repo)
выполнить **fast-forward-only merge**. Если `main` изменился, сначала
согласовать историю и повторить проверку кандидата; не обходить защиту.
5. После merge получить `main` и убедиться, что его HEAD — проверенный релизный
коммит, версия и lockfile совпадают. На этом SHA создать аннотированный тег:
`git tag -a vX.Y.Z <release-sha> -m "Release X.Y.Z"`, затем отправить
только этот тег: `git push origin refs/tags/vX.Y.Z`. Повторно release-it
на `main` не запускать: он уже подготовил версию.
6. Через PR `main → develop` вернуть релизный коммит в разработку без squash
и rebase. Убедиться, что `develop` содержит тег. После первого выпуска
`develop` создаётся непосредственно от релизного SHA.
Перед публикацией тегов сравнить local SHA с удалённым `main`; PR и проверки
должны относиться к этому кандидату. Опубликованные теги не перемещать.
При сбое после merge продолжить с создания отсутствующего тега, без нового bump.
При сбое до merge исправить релизную ветку и заново проверить кандидат;
подготовленную версию и changelog не повышать второй раз. Пять репозиториев
не имеют общей атомарной публикации: завершённость проверяется отдельно по каждому.
Первый выпуск задаётся явно: `npm run release:prepare -- 0.1.0` из
`release/0.1.0`. Начальные `0.0.0` — bootstrap-состояние до первого тега.
Исторические неконвенциональные commits не переписываются; первый changelog
требует просмотра человеком. Дальнейшие версии выбираются по commits.
### Hotfix, проверки и защита
Срочный fix начинается от `main`, проходит проверки и релизный PR из
`release/hotfix-<name>` в `main`, затем обязательно возвращается в `develop`.
Если ломается публичный контракт, major сохраняется и для hotfix.
Каждый CI использует только свой checkout. Backend генерирует OpenAPI без сервера,
сверяет генератор с configured app и не хранит JSON в Git; frontend проверяет types по входному
snapshot. Docs проверяет внутренние ссылки; внешние источники даются как
справочные веб-ссылки. Обновление API artifact потребителя — отдельное действие.
Зелёные локальные gates и порядок публикации не доказывают совместимость
развёрнутых версий. Процедуры выпуска находятся также в README каждого repo;
доступ к root для выпуска другого репозитория не требуется.
В Gitea для `main` и `develop` нужны запрет прямого push и force-push,
обязательные проверки: в root только `commits`, в остальных repo —
`verify`, `security`, `commits`; также нужен запрет обхода правил
администратором. Требование отдельного одобрения review не вводится для
разработки одним владельцем. Ветка по умолчанию — `develop`; Renovate тоже
отправляет PR в `develop`. Теги `v*` защищены, создание разрешается владельцу
релиза; их удаление или перенос не входит в обычный процесс.
В root нет собственного test/verify runner и release hooks. Release-it и
commitlint используются напрямую. Остальные репозитории сохраняют свои gates.
Если в защите веток root ранее были обязательными `verify` и `security`, их
нужно убрать из required checks в Gitea; YAML не меняет настройки сервера.
Npm publishing, автоматический deploy и карточки Gitea Releases не включены.
Граница выпуска — принятый коммит, changelog и Git-тег.