Commit graph

18 commits

Author SHA1 Message Date
0453168d70 test(e2e): двойные ID «владелец/мой» в названиях сценариев и known-defects
Зачем: аудит владельца (docs/audit/2026-09-26/AUDIT.md) стал основным
реестром дефектов; без сопоставления исполнители и приёмка говорят о
разных ID для одной ошибки (TASK-GROK-2 §2).

Что: теги переименованы по таблице владельца ([K3/N2], [K13/SYNC-A],
[S5/SYNC-C], [D6/OWN-01], [K17/OWN-10] и т. д.), ключи known-defects.json —
так же; N9–N12, F7, F10 остаются одиночными, как в таблице. Сверх таблицы,
по тексту AUDIT.md: K1/SYNC-I (анонимный доступ без токенов — это K1 на
/sync), K1/PILOT-1 (подстановки без :? в пилотном compose прямо названы в
K1), K2/PILOT-2 (NODE_ENV=development в пилоте — суть K2). SYNC-C0, SYNC-K,
OWN-03..06/08/09, PILOT-3 ID владельца не имеют. run-e2e принимает «/» в
теге. Прогон: 38 red / 9 green, храповик OK — те же сценарии, новые имена.
2026-09-26 15:21:22 +07:00
fc20f75b55 test(e2e): evidence прогонов вне git, в CI — артефакт
Зачем: tests/e2e/evidence/ перезаписывается каждым прогоном (логи серверов
с ULID и портами, JSON vitest), поэтому любой запуск стенда менял
отслеживаемые файлы и засорял дифф (приёмка владельца, TASK-GROK-2 п.1).

Что: tests/e2e/evidence/ убран из индекса (git rm --cached) и добавлен в
корневой .gitignore (его же читает prettier, поэтому форматировать
сгенерированные файлы больше не нужно — вызов prettier из run-e2e убран).
В CI задача e2e выгружает папку артефактом e2e-evidence
(actions/upload-artifact, закреплён SHA v4.6.2; Forgejo 9.0.3 поддерживает
v4). Разовые доказательства, которые скрипты не перезаписывают (N5 до/после,
замер N13), перенесены в tests/e2e/report-evidence/ — на них ссылается
REPORT.md.
2026-09-26 15:20:28 +07:00
0aaa2f4d2d test(e2e): запуск vitest/tsx/prettier без .cmd-обёрток (Windows)
Зачем: проект разрабатывается под Windows, а стенд там не стартовал:
spawn('npx') и spawn('node_modules/.bin/tsx') без shell падают с ENOENT,
потому что в Windows это .cmd-файлы (приёмка владельца, TASK-GROK-2 п.1).

Что: scripts/test/node-commands.mjs находит JS-точки входа через
require.resolve (tsx/cli, vitest.mjs, prettier.cjs) и всегда запускает их
текущим node (process.execPath). Сервер запускается одним процессом
`node --import tsx src/server.ts`: CLI tsx порождает дочерний node, и под
Windows kill() родителя оставил бы сервер-сироту на порту. baseEnv()
передаёт дочерним процессам PATH и под win32 системные переменные
(SystemRoot, TEMP и др.), без которых node на Windows не работает с сетью,
но не наследует секреты родителя.

Проверка на Linux: tests/e2e/harness/node-commands.test.ts (входит в
npm test) — команды начинаются с process.execPath, без .cmd/.bin/npx,
файлы существуют; исходники стенда не вызывают npx и node_modules/.bin.
Реальный прогон на Windows 11 — не проверено (нет Windows-раннера).
2026-09-26 15:19:47 +07:00
045f696425 test(e2e): N13 — нагрузочная проверка гонки первого расчёта зарплаты
Зачем: владелец пометил N13 как «не воспроизведено», а в коде окно гонки
(SELECT ... FOR UPDATE по отсутствующей строке, затем INSERT ... ON CONFLICT
DO NOTHING со своим runId) видно. Нужен повторяемый замер на живом сервере
и реальной PostgreSQL 17, а не рассуждение.

Что: scripts/test/n13-race.mjs — 10/25/50 параллельных первых
POST /payroll/calculate, каждая попытка на новой точке, проверка статусов,
числа run_id, строк в staff_payroll_runs и «фантомных» run_id. Режим as-is
показывает, что сейчас всё упирается в N2 (500). Режим n2-bypass ставит
DEFAULT now() только в одноразовой БД скрипта (продукт и миграции не
меняются), чтобы увидеть саму гонку. Итог: 0 некорректных из 30 попыток;
причина (из кода) — случайная сериализация через upsert
ensureDefaultPayRules. Это записано в NOTES-FOR-EXECUTORS вместе с
рекомендацией явной блокировки и замечанием об утечке текста ошибок БД в 500.
2026-09-26 15:18:31 +07:00
bc9b29dec8 ci: PostgreSQL 17 с ролями как в pilot, roundtrip миграций, e2e, SHA-пины
Зачем: прежний CI запускал миграции и тесты под POSTGRES_USER сервиса
(суперпользователь), не проверял откат миграций, не запускал e2e на
реальной БД, держал плавающие теги actions (F13) и выполнял docker build
в контейнере без Docker daemon.

- verify: bootstrap-админ сервиса только создаёт роли (provision-pg.mjs,
  пароли случайные); миграции up -> откат всех -> up -> up (no-op) ролью
  krona_migrator без SUPERUSER; `npm run check` с DATABASE_TEST_URL
  (app-роль) и DATABASE_TEST_MIGRATION_URL (очистка, см. N5); npm audit.
- format: prettier вынесен в отдельную задачу — он красный по 25 файлам
  (F14) и не должен маскировать статус verify/e2e.
- e2e: реальный сервер + PostgreSQL 17 через scripts/test/run-e2e.mjs.
  Выбран «храповик» known-defects.json, а не отдельная задача с
  continue-on-error: так CI зелёный, только если стенд работает и каждый
  красный сценарий — известный открытый дефект; новый красный сценарий
  (регрессия) или исправленный, но не вычеркнутый дефект делают задачу
  красной. continue-on-error скрыл бы и поломку самого стенда.
- docker-build: отдельная задача на метке `docker-host` только для push,
  после verify; без такого раннера она ждёт в очереди, не блокируя
  остальные.
- actions/checkout v4.4.0 и actions/setup-node v4.4.0 закреплены SHA
  (git ls-remote; одинаковы на github.com и code.forgejo.org).

Проверено: actionlint 1.7.12 (метки docker/docker-host объявлены как
self-hosted) — 0 замечаний; scripts/test/ci-local.sh повторяет шаги
verify/format/e2e на локальной PostgreSQL 17.11 (Forgejo-раннер реально
не запускался — не проверено).
2026-09-26 15:18:31 +07:00
c68370b890 test(e2e): форматировать сгенерированные json/md evidence prettier
Зачем: tests/e2e/evidence не входит в .prettierignore (файл вне разрешённых путей), и минифицированный JSON vitest делал бы npm run format:check красным из-за артефактов, а не из-за кода.
2026-09-26 15:18:31 +07:00
646e8d4f22 test(e2e): стенд с реальным сервером и PostgreSQL 17
Зачем: 156 зелёных тестов на fakeDatabase не поймали, что ключевые
сценарии (создание сотрудника, подтверждение смены, расчёт зарплаты)
всегда падают на реальной PostgreSQL. Нужен приёмочный стенд, который
проверяет продукт как чёрный ящик: настоящий процесс сервера, настоящая
БД, роли как в pilot, но с минимальными привилегиями.

- tests/e2e/harness/global-setup.ts: создаёт БД и роли через
  scripts/test/provision-pg.mjs, применяет миграции ролью krona_migrator
  (NOSUPERUSER), поднимает `tsx src/server.ts` под krona_staff_app с
  токенами/VAPID из crypto.randomBytes; три процесса: с токенами, без
  токенов (как корневой compose.yaml) и отдельный для проверки rate limit;
  логи серверов пишутся в tests/e2e/evidence/.
- *.e2e.ts и отдельный vitest.e2e.config.ts: e2e не попадают в `npm test`,
  поэтому `npm run check` не требует БД и не краснеет от известных дефектов.
- [HARNESS]/[CTRL] — позитивные контроли (версия PG >= 17, атрибуты ролей,
  app-роль не видит schema_migrations, RBAC, уволенный теряет доступ):
  если они красные, красные дефектные сценарии ничего не доказывают.
- scripts/test/run-e2e.mjs: «храповик» известных дефектов по
  tests/e2e/known-defects.json (новый красный или исправленный-но-не-
  вычеркнутый ID = exit 1), таблица e2e-table.md и проверка, что в
  evidence нет ничего похожего на секреты стенда.

Логи названы *.txt, т.к. *.log в .gitignore.
2026-09-26 15:18:31 +07:00
5ac248660a test(db): стенд PostgreSQL с мигратором без SUPERUSER
Зачем: аудит показал, что 156 зелёных тестов на fakeDatabase не заметили,
что создание сотрудника, подтверждение смены и расчёт зарплаты всегда
падают на реальной PostgreSQL. Чтобы тесты и CI проверяли реальный SQL,
нужен воспроизводимый стенд с ролями как в pilot, но с минимальными
привилегиями:

- scripts/test/provision-pg.mjs: bootstrap-админ (только как DBA/entrypoint)
  создаёт krona_migrator (NOSUPERUSER NOCREATEDB NOCREATEROLE, владелец БД и
  схемы public) и krona_staff_app (NOSUPERUSER NOBYPASSRLS NOINHERIT); пароли
  crypto.randomBytes, пишутся только в env-файл 0600, в вывод не попадают.
  scripts/create-app-role.mjs здесь не используется, т.к. без SUPERUSER он
  падает (находка N6, продуктовый код не трогаем).
- scripts/test/migrate-roundtrip.mjs: up -> откат всех миграций -> up ->
  повторный up должен быть no-op; ролью мигратора, как требует AGENTS.md.

Проверено на PostgreSQL 17.11: 11 миграций применены, откачены, применены
повторно, третий up пустой.
2026-09-26 15:18:31 +07:00
Ochenstarik
3e2054480c fix(push): isolate employee data and preserve platform outbox
Some checks are pending
ci / verify (push) Waiting to run
2026-09-26 12:31:10 +07:00
Ochenstarik
f74aa6d7f5 fix(import): provision workbook profession catalog
Some checks are pending
ci / verify (push) Waiting to run
2026-09-24 21:25:13 +07:00
Ochenstarik
5b159f785c feat(staff): import workbook professions and dated payroll 2026-09-24 21:14:03 +07:00
Ochenstarik
0f530dc633 fix: read terminal release version reliably
Some checks failed
ci / verify (push) Has been cancelled
2026-09-24 17:13:14 +07:00
Ochenstarik
b2f7a68589 feat(installer): update release build script and NSIS installer with Windows Service and driver detection 2026-09-24 16:37:48 +07:00
Ochenstarik
3464998168 feat: add secure attendance portal and payroll foundation
Some checks are pending
ci / verify (push) Waiting to run
2026-09-24 15:59:38 +07:00
Ochenstarik
827d321a1a feat(terminal): add secure release updates and installer
Some checks failed
ci / verify (push) Has been cancelled
2026-09-19 02:08:26 +07:00
Ochenstarik
d45bee960a fix: harden terminal recovery and deployment
Some checks are pending
ci / verify (push) Waiting to run
2026-09-18 11:10:28 +07:00
Ochenstarik
64ac5c0c66 fix: enforce tenant isolation and runtime contracts 2026-09-18 01:34:12 +07:00
Ochenstarik
fcf014cf71 feat: establish tenant-safe Staff service foundation 2026-09-10 23:29:26 +07:00