From 9f5baed3a318cacd615125026612f5284e890744 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sun, 13 Sep 2026 20:14:15 +0300 Subject: [PATCH] docs: document workspace and safe onboarding --- .gitignore | 49 ++------------- AGENTS.md | 5 +- README.md | 119 +++++++++++++++++++++++++++++++++++++ test-workspace-tracking.py | 47 +++++++++++++++ 4 files changed, 176 insertions(+), 44 deletions(-) create mode 100644 README.md create mode 100644 test-workspace-tracking.py diff --git a/.gitignore b/.gitignore index 8ac319c..bd88cb7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,43 +1,6 @@ -# OS -.DS_Store - -# IDE / local environment -.idea -.vscode/ - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -# Runtime data -pids -*.pid -*.pid.lock -*.seed - -# Node / frontend / backend artifacts -node_modules -dist -dist-ssr -build -coverage -/.nyc_output - -# Local and generated env/runtime files -.env -.env.* -!.env.example - -# Generated and temporary -.tmp -.temp - -# Tooling metadata -.opencode -.playwright-mcp -graphify-out +# Root owns only these files; nested repositories and local data stay local. +/* +!/.gitignore +!/AGENTS.md +!/README.md +!/test-workspace-tracking.py diff --git a/AGENTS.md b/AGENTS.md index a28fdf1..398344e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,7 +3,10 @@ ## Workspace `frontend`, `backend`, `docs` и `specs` — независимые Git-репозитории. -Root не является Git-репозиторием; команды Git выполняй из нужного repo. +Root — отдельный Git-репозиторий `WealthLedger/main`; команды Git выполняй +из нужного repo. Root tracking ограничен allowlist в `.gitignore`; +вложенные repos и локальные данные в main не добавляй, включая `git add -f`. +Структура checkout и запуск — в [README](README.md). `references/**`, dated audits и архивы — read-only источники. ## Работа diff --git a/README.md b/README.md new file mode 100644 index 0000000..9d6f6b3 --- /dev/null +++ b/README.md @@ -0,0 +1,119 @@ +# WealthLedger + +Локальное приложение для портфеля T-Bank, операций, дохода и будущих выплат, +а также ручного учёта банковских карт и расходов. +[Обзор продукта](docs/overview.md) и [документация системы](docs/README.md). + +## Структура workspace + +Workspace состоит из пяти независимых Git-репозиториев. Root — репозиторий +`WealthLedger/main`; вложенные checkout не являются submodules. + +| Путь от root | Репозиторий Gitea | Назначение | +| --- | --- | --- | +| `.` | `WealthLedger/main` | Вход в workspace, инструкции и правила root tracking | +| `frontend/` | `WealthLedger/frontend` | [React/Vite UI](frontend/README.md) | +| `backend/` | `WealthLedger/backend` | [NestJS API, Prisma и SQLite](backend/README.md) | +| `docs/` | `WealthLedger/docs` | [Объяснение системы и сопровождение](docs/README.md) | +| `specs/` | `WealthLedger/specs` | [Требования и OpenSpec](specs/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 нет. Относительные ссылки требуют указанных имён каталогов. + +### Что хранится в main + +Root отслеживает только `.gitignore`, `AGENTS.md`, `README.md` и +`test-workspace-tracking.py`. Остальные 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`. + +## Подготовка и запуск + +Нужны nvm и Node из `.nvmrc` каждого npm-repo (сейчас 24.21.0, npm 11.19). +Root не содержит npm-проекта. В frontend, backend и docs отдельно выполните +`nvm install`, `nvm use --silent`, `npm ci`. +Предпосылки native dependencies и разрешения install scripts описаны в +[локальном окружении](docs/development/local-workspace.md). + +Для нового backend создайте `.env` по [backend README](backend/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 и ключ шифрования; процедуру и ограничения отката смотрите +в [локальном окружении](docs/development/local-workspace.md#сохранение-данных-и-откат). +Известная ошибка fresh migration при `RUST_LOG=warn/error` устранена в +`backend/prisma.config.ts`: CLI удаляет унаследованную переменную. +Используйте штатный `prisma migrate deploy` из backend; прежний Prisma blocker +снят. [Подробности и границы проверки](docs/development/verification.md#известное-ограничение-сквозной-проверки). + +В другом терминале подготовьте `.env` по [frontend README](frontend/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 из `frontend/.nvmrc`; проверенная версия CLI — 1.10.0. +Store `wealth-ledger-specs` расположен в `specs/openspec/`. +[Роль и необязательный lifecycle](docs/development/openspec-authority-and-lifecycle.md), +[команды validation](specs/README.md#проверка). + +## Проверки + +Перед npm-командами активируйте `.nvmrc` соответствующего repo. + +| Где | Команда | Что проверяет | +| --- | --- | --- | +| root | `python3 test-workspace-tracking.py` | Массовый add на вымышленных данных; сохранность файлов и вложенных Git | +| 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 и контракт с соседним frontend | +| docs | `npm run verify` | Markdown, относительные ссылки и diff | + +Python 3 нужен только для проверки root tracking. Backend e2e использует +временные базы; verify отдельно не доказывает HTTP/DB-сценарии или доступность +T-Bank. Полные команды и ограничения принадлежат repo README и +[руководству по проверке](docs/development/verification.md). +Для изменения проекта начните с [AGENTS](AGENTS.md). diff --git a/test-workspace-tracking.py b/test-workspace-tracking.py new file mode 100644 index 0000000..0765adb --- /dev/null +++ b/test-workspace-tracking.py @@ -0,0 +1,47 @@ +"""Check root tracking on fictional data; never stage the real workspace.""" + +from pathlib import Path +import subprocess +import tempfile + + +def check(ignore_rules): + with tempfile.TemporaryDirectory(prefix="wealthledger-tracking-") as directory: + root = Path(directory) + + def git(*args): + return subprocess.check_output( + ["git", "-C", str(root), *args], text=True + ) + + git("init", "--quiet") + allowed = {".gitignore", "AGENTS.md", "README.md", "test-workspace-tracking.py"} + for name in allowed: + (root / name).write_text("fictional fixture\n") + (root / ".gitignore").write_text(ignore_rules) + for name in ("frontend", "backend", "docs", "specs"): + nested = root / name + nested.mkdir() + subprocess.run(["git", "init", "--quiet", str(nested)], check=True) + for name in ( + "frontend/source.ts", "backend/prisma/dev.db", "docs/README.md", + "specs/README.md", "statement-imports/report.csv", "private.db", + "private.db-wal", ".env", ".env.example", "audit.pdf", + "design/preview.html", "todo/notes.md", "references/source.md", + ".agents/local.md", "unknown-directory/data.txt", "unknown-file.txt", + ): + target = root / name + target.parent.mkdir(parents=True, exist_ok=True) + target.write_text("fictional private data\n") + before = {p.relative_to(root): p.read_bytes() for p in root.rglob("*") + if p.is_file() and ".git" not in p.relative_to(root).parts[:1]} + git("add", ".") + assert set(git("ls-files").splitlines()) == allowed + assert all((root / p).read_bytes() == content for p, content in before.items()) + assert all((root / name / ".git").is_dir() + for name in ("frontend", "backend", "docs", "specs")) + + +if __name__ == "__main__": + check(Path(__file__).with_name(".gitignore").read_text()) + print("PASS: only root allowlist staged; fictional data and nested Git preserved")