Compare commits

..

12 commits

Author SHA1 Message Date
421da722c0 docs(e2e): REPORT.md (описание PR) и свежие evidence прогона
Зачем: PR в Forgejo создать нельзя (нет API-токена), поэтому описание
изменений, таблица green/red по ID с командами и фактическим выводом, итог
N5 до/после, валидация CI и N13 лежат в репозитории рядом с тестами.
Evidence перезаписаны финальным прогоном ./scripts/test/ci-local.sh, чтобы
отчёт ссылался на те же числа, что в файлах (38 red / 9 green, храповик OK,
format красный из-за F14). Число файлов F14 в комментарии ci.yml и в
заметках уточнено до 23 по этому замеру.
2026-09-26 14:35:19 +07:00
3388b90bfa 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 14:33:11 +07:00
1e325a6dfd test(e2e): сценарии решений владельца (OWN-01..11) и заметки исполнителям
Зачем: решения владельца (роли точки/бухгалтера/директора, пакет зарплаты
с подписью директора, неизменяемость после подписи, зарплата по точке
фактической смены, согласие на биометрию) должны стать исполняемыми
критериями приёмки до того, как Codex начнёт этап 4, иначе реализацию
будет нечем проверить.

API ещё нет, поэтому тесты написаны против наиболее вероятного контракта
C1 (access-grants), C2 (payroll/batches, submit/sign/return,
notifications), C3 (biometric-consent, terminal enrollment); контракт и
инварианты описаны в tests/e2e/NOTES-FOR-EXECUTORS.md. Сейчас все OWN
красные (404 Route not found) и внесены в known-defects.json.
В NOTES также: найденные сценариями дефекты с указанием файлов,
конфликт NODE_ENV/standalone для pilot, N6, требования к раннеру docker-host.
2026-09-26 14:30:46 +07:00
a19c06b574 test(e2e): проверка deploy/pilot/compose.yaml (PILOT-1..3)
Зачем: корневой compose.yaml уже проверяется tests/unit/deployment.test.ts,
а pilot-файл, который реально разворачивается у владельца, — нет. В нём
подстановки вида ${STANDALONE_MANAGER_TOKEN} без :? молча дают пустое
значение, а при пустых токенах standalone выдаёт права анониму (F2);
NODE_ENV=development в pilot отключает production-проверки config.ts.

- PILOT-1: каждая подстановка должна быть ${VAR:?сообщение};
- PILOT-2: ни один сервис не с NODE_ENV=development;
- PILOT-3: у app нет учётных данных мигратора (сейчас зелёный).
Файл в tests/e2e как *.e2e.ts: tests/unit вне разрешённых путей, а
красные пункты (дефекты deploy/, которые правят исполнители) идут через
known-defects.json и не ломают `npm run check`. Сейчас PILOT-1 и PILOT-2
красные: 14 подстановок без :?, app с NODE_ENV=development.
2026-09-26 14:30:10 +07:00
f59be3adf9 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 14:29:47 +07:00
9bdfb66a53 test(e2e): форматировать сгенерированные json/md evidence prettier
Зачем: tests/e2e/evidence не входит в .prettierignore (файл вне разрешённых путей), и минифицированный JSON vitest делал бы npm run format:check красным из-за артефактов, а не из-за кода.
2026-09-26 14:29:47 +07:00
32ced4b100 test(e2e): сценарии офлайн-синхронизации (/sync/*)
Зачем: бэкенд офлайн-синхронизации (миграция 0011) покрыт только
юнит-тестами без реальной БД. Сценарии на живом сервере показывают, как
терминал реально взаимодействует с сервером, и фиксируют границы
доверия к устройству.

Проверяется правильное поведение: устройство не подтверждает смены и не
утверждает табель сам (SYNC-A/B); начальная загрузка работает (SYNC-C0,
сейчас 500 «column status does not exist» — у staff_org_units нет
status) и не теряет сущности после 100-й (SYNC-C); правки из портала
видны в инкрементальном pull (SYNC-D); отметки уволенных и вне окна
времени отклоняются (SYNC-E/J); точка устройства сохраняется, чужая
отклоняется (SYNC-F); битая команда не роняет пакет (SYNC-G); CSRF и
анонимная регистрация устройств запрещены (SYNC-H/I); ack не принимает
курсор из будущего (SYNC-K). SYNC-L — позитивный контроль отзыва.
2026-09-26 14:27:59 +07:00
518494d03c test(e2e): сценарии дефектов основного API (N1-N4, N9-N12, F2-F4, F7, F10)
Зачем: каждый открытый дефект аудита должен иметь исполняемый сценарий
на реальной БД, который проверяет ПРАВИЛЬНОЕ поведение. Тогда красный
тест = открытый дефект, а исправление видно по смене цвета, без ручной
перепроверки.

- N1 POST /employees -> 201; N2 подтверждение смены, расчёт, утверждение
  и сумма начисления 8 ч x синтетическая ставка; N4 пересекающиеся
  периоды не начисляют смену дважды (сейчас блокирован N2 — это видно в
  сообщении assert как «предусловие, см. N2»);
- N3 SSRF: подписка на https://127.0.0.1:<порт> должна отклоняться, и
  локальный слушатель не должен получить соединение;
- N9, N12, N10, N11, F2 (процесс без токенов), F3, F4 (отдельный процесс),
  F7, F10.
Сотрудники для сценариев, не относящихся к N1, создаются импортом, чтобы
один дефект не маскировал остальные. Все данные синтетические (E2E-*),
ставка 123,45 ₽/ч заведомо не реальная.
2026-09-26 14:27:59 +07:00
cf7f6f4510 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 14:27:59 +07:00
d7e9008b8c style(test): prettier для tenant-isolation.test.ts
Зачем: файл уже до правки N5 не проходил prettier --check (часть F14); форматирование вынесено в отдельный коммит, чтобы смысловая правка N5 читалась отдельно от шума.
2026-09-26 14:21:48 +07:00
88fc7491b6 test(integration): очистка tenant-isolation ролью мигратора (N5)
Зачем: afterAll удалял строки соединением роли приложения, а у
krona_staff_app намеренно нет DELETE на staff_employees. На реальной
PostgreSQL 17 тест проходил, но файл падал в afterAll ("permission denied
for table staff_employees", exit 1), поэтому любой CI с DATABASE_TEST_URL
был бы красным не из-за дефекта продукта, а из-за самого теста.
Выдавать app-роли DELETE ради теста нельзя: это ослабило бы модель прав.

Что сделано:
- очистка идёт отдельным соединением роли мигратора
  (DATABASE_TEST_MIGRATION_URL или DATABASE_MIGRATION_URL, который CI уже
  задаёт); так как FORCE RLS действует и на владельца таблиц, в транзакции
  выставляется app.tenant_id; удаляются строки обоих тестовых tenant;
- очистка выполняется и в beforeAll, чтобы остатки прошлого упавшего
  прогона не ломали уникальные ключи (EMP-PUSH-1, DEV-A);
- без URL мигратора тест падает с понятной ошибкой, а не оставляет мусор.

До: tests/e2e/evidence/n5-before.txt (1 passed, suite FAIL, exit=1).
После: tests/e2e/evidence/n5-after.txt (два прогона подряд, exit=0).
2026-09-26 14:21:47 +07:00
29fefc1933 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 14:21:47 +07:00
54 changed files with 3898 additions and 3010 deletions

View file

@ -91,46 +91,6 @@ jobs:
- name: e2e table
if: always()
run: cat tests/e2e/evidence/e2e-table.md || true
# tests/e2e/evidence/ в .gitignore: полный вывод vitest, JSON, логи серверов —
# артефакт прогона, а не файлы репозитория (TASK-GROK-2 п.1).
- name: upload e2e evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: e2e-evidence
path: tests/e2e/evidence/
retention-days: 14
if-no-files-found: warn
# Windows 11 (проект разрабатывается под Windows). Windows-раннера у сервера пока
# НЕТ, поэтому задача включается только переменной репозитория
# KRONA_WINDOWS_RUNNER=true (иначе пропускается и не висит в очереди).
# Раннер: forgejo-runner в режиме host с меткой `windows`, Node 22+.
# e2e на Windows идёт, только если задан секрет WINDOWS_E2E_PG_ADMIN_URL
# (bootstrap-админ локальной PostgreSQL 17 на раннере). НЕ ПРОВЕРЕНО: не запускалась.
windows:
if: vars.KRONA_WINDOWS_RUNNER == 'true'
runs-on: windows
env:
E2E_PG_ADMIN_URL: ${{ secrets.WINDOWS_E2E_PG_ADMIN_URL }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: { node-version: 22, cache: npm }
- run: npm ci
- name: spawn without .cmd wrappers
run: node node_modules/vitest/vitest.mjs run tests/e2e/harness/node-commands.test.ts
- name: e2e on Windows (needs local PostgreSQL 17)
if: env.E2E_PG_ADMIN_URL != ''
run: node scripts/test/run-e2e.mjs
- name: upload Windows e2e evidence
if: always() && env.E2E_PG_ADMIN_URL != ''
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: e2e-evidence-windows
path: tests/e2e/evidence/
retention-days: 14
if-no-files-found: warn
# docker build требует Docker daemon, которого нет в контейнере метки `docker`.
# Нужен раннер с меткой `docker-host` (хост с доступом к Docker). Пока такого

3
.gitignore vendored
View file

@ -18,6 +18,3 @@ apps/KronaStaffTerminal.Tests/bin/
apps/KronaStaffTerminal.Tests/obj/
artifacts/
.audit-build/
# Результаты прогонов e2e (логи серверов, JSON vitest, таблица) — артефакт CI, не исходники
tests/e2e/evidence/

View file

@ -1,206 +0,0 @@
# Аудит репозитория krona-staff (третий проход)
- Дата: 2026-09-18
- Ревизия: `7c8e7fc` — ветка `codex/bootstrap-platform-foundation`, 9 коммитов
- Предыдущие проходы: `14ed610` (первый отчёт), `b88ff91` (второй отчёт)
- Репозиторий: https://git.ochenstarik.ru/ochenstarik/krona-staff
## 1. Что изменилось
Два новых коммита, 53 файла, +1725/−1069 строк:
- `64ac5c0 fix: enforce tenant isolation and runtime contracts` — Node-сервис, БД, Docker, CI;
- `7c8e7fc fix: close terminal audit findings` — терминал, документация, лицензия ZKTeco.
Добавлен `docs/AUDIT-REMEDIATION-2026-09-18.md` — ответ на **первый** отчёт (ревизия `14ed610`). Замечания второго отчёта (Н1–Н10, ревизия `b88ff91`) в нём не учтены: коммиты готовились до него.
Главное из сделанного:
- разделены роли PostgreSQL: `krona_migrator` (миграции) и `krona_staff_app` (`NOSUPERUSER NOBYPASSRLS`);
- мигратор ведёт `schema_migrations`, берёт advisory lock, откатывает только последнюю миграцию и только при `ALLOW_MIGRATION_DOWN=true`;
- миграция `0002` добавляет `subject`/`actor` в outbox, `CHECK` на ULID и делает аудит-лог доступным приложению только на чтение и добавление;
- маршруты перенесены под `/api/v1/staff`, `/ready` отвечает `503` без деталей, `x-correlation-id` проверяется как ULID и возвращается в ответе;
- появились интеграционные тесты: реальная проверка изоляции тенантов на PostgreSQL и сверка OpenAPI с фактическими маршрутами; таймаут тестов поднят до 15 с;
- Redis и BullMQ удалены из зависимостей и compose; образы Docker закреплены по digest; `format:check` и миграции добавлены в CI;
- в терминале: экспорт журнала в CSV, маскирование имён на публичном экране, настраиваемая максимальная длительность смены, ограничение журнала в 100 000 записей, глобальные обработчики необработанных исключений, ротация `crash.log`, автозагрузка выключена по умолчанию, очищен `Package.appxmanifest`, добавлена EULA ZKTeco.
## 2. Проверки
| Проверка | Результат |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `npm ci` | OK |
| `npm run check` (lint, typecheck, тесты, миграции, контракты, build) | **Пройдено полностью** |
| `npm run format:check` | Пройдено по коду репозитория (замечание только к этому файлу отчёта, он не в репозитории) |
| `npm audit --audit-level=moderate` | 0 уязвимостей |
| `dotnet build` терминала (Release, x64) | OK, 0 ошибок, 0 предупреждений |
| Запрос `GET /live` (корень) | **404** — цель Docker HEALTHCHECK, см. Н11 |
| Запрос `GET /api/v1/staff/live` | 200 |
| Запрос `GET /api/v1/staff/ready` при сбое БД | 503, тело `{"status":"unavailable"}`, текст ошибки БД не раскрывается |
| Некорректный `x-correlation-id` | Заменяется на сгенерированный ULID |
| `NODE_ENV=production` + `standalone` | Запуск запрещён с понятной ошибкой |
**Не проверялось:** Docker, PostgreSQL и сканер SLK20R на машине аудита отсутствуют. Тест изоляции тенантов локально пропускается (`DATABASE_TEST_URL` не задан) — в CI он выполняется, но результата прогона CI я не видел.
## 3. Сводка
| Категория | Итог |
| ----------------------------------- | --------------------------------------------------------- |
| Закрыто из первого отчёта | 24 находки из 33 + сознательно оставлена №24 |
| Осталось из второго отчёта (Н1–Н10) | 9 открыто, 1 частично |
| Новые находки | 11 (2 высоких, 5 средних, 4 низких) |
| Архитектура и право (A1, A2) | Вынесены владельцу, зафиксированы в документе исправлений |
## 4. Новые находки
### Н11. 🟠 Docker HEALTHCHECK проверяет несуществующий маршрут
- **Где:** `Dockerfile:21`
- **Суть:** после переноса маршрутов под `/api/v1/staff` проверка осталась на `http://127.0.0.1:8080/live`. Проверено запросом: корневой `/live` теперь отдаёт 404, `wget` вернёт ошибку.
- **Последствия:** контейнер всегда в состоянии `unhealthy`. В Docker Compose это ломает `depends_on: condition: service_healthy`, в оркестраторах (Swarm, Kubernetes при аналогичной пробе) — приводит к бесконечному перезапуску или к тому, что контейнер не попадает в балансировку. Автоматическая проверка развёртывания при этом молчит.
- **Исправление:** `CMD wget -q -O - http://127.0.0.1:8080/api/v1/staff/live || exit 1`; добавить healthcheck для сервиса `app` в `compose.yaml` и тест, который сверяет путь из `Dockerfile` с маршрутами.
### Н12. 🟠 Контейнер приложения получает учётные данные мигратора
- **Где:** `compose.yaml:4`, `.env.example:5-8`
- **Суть:** у сервиса `app` указан `env_file: .env`, а в `.env` лежат `DATABASE_MIGRATION_URL`, `POSTGRES_MIGRATION_PASSWORD` и `POSTGRES_APP_PASSWORD`. Переопределение `DATABASE_URL` не убирает остальные переменные из окружения контейнера.
- **Последствия:** пароль роли-владельца схемы доступен процессу приложения и любому, кто прочитает `/proc/1/environ` или `docker inspect`. Разделение ролей, ради которого сделана находка №6, частично обесценивается. `docs/DEPLOYMENT.md` прямо утверждает обратное: «миграционный URL хранится отдельно и не передаётся runtime-контейнеру».
- **Исправление:** отдельные файлы `.env.app` и `.env.migrate`, либо перечислить нужные переменные в `environment:` без `env_file`.
### Н13. 🟡 Обновление существующей установки ломается
- **Где:** `compose.yaml:23-32`, `docker/postgres/init-app-role.sh`
- **Суть:** `POSTGRES_USER` изменён с `krona_staff` на `krona_migrator`, а роль приложения создаётся скриптом из `docker-entrypoint-initdb.d`, который выполняется только при инициализации пустого каталога данных. На уже существующем томе:
- роль `krona_staff_app` не появится;
- блок `GRANT` в миграциях обёрнут в `IF EXISTS (SELECT 1 FROM pg_roles ...)` и молча ничего не сделает;
- приложение не сможет подключиться, в кластере останется прежний суперпользователь `krona_staff`.
- **Исправление:** выполнять `scripts/create-app-role.mjs` в сервисе `migrate` перед миграциями и описать порядок обновления в `docs/DEPLOYMENT.md`.
### Н14. 🟡 Права выдаются «если роль есть» и не распространяются на будущие таблицы
- **Где:** `migrations/0001_infrastructure.up.sql:80-89`, `migrations/0002_security_hardening.up.sql:59-68`
- **Суть:** при отсутствии роли миграция завершается успешно, но без выдачи прав — ошибка проявится позже как `permission denied` в рантайме. `ALTER DEFAULT PRIVILEGES` не настроен, поэтому каждая новая миграция обязана повторять блок `GRANT`; забытый блок — новая таблица, недоступная приложению.
- **Исправление:** падать с понятной ошибкой, если роли нет; настроить `ALTER DEFAULT PRIVILEGES FOR ROLE krona_migrator IN SCHEMA public`.
### Н15. 🟡 Новое правило «Приход/Уход» теряет длинные смены и не имеет ручной корректировки
- **Где:** `MainPage.xaml.cs:586-588`
- **Суть:** «Уход» проставляется, только если предыдущее событие — «Приход» и с него прошло не больше `MaximumShiftHours` (по умолчанию 20 ч). Переход через полночь теперь обрабатывается верно (№14 закрыта), но появились новые случаи:
- смена длиннее настроенного значения (суточное дежурство при значении 20 ч) даёт второй «Приход» вместо «Ухода»;
- если сотрудник не отметил уход, «Приход» остаётся незакрытым навсегда, и следующая отметка тоже станет «Приходом»;
- исправить ошибочную запись в интерфейсе нельзя — доступна только полная очистка журнала.
- **Исправление:** редактирование или удаление отдельной записи под администратором с пометкой о ручной правке; предупреждение при незакрытом «Приходе».
### Н16. 🟡 Ограничение журнала в 100 000 записей делает сохранение очень дорогим
- **Где:** `MainPage.xaml.cs:599-601`, `Services/TerminalStore.cs:127`
- **Суть:** предел в 100 000 записей — это десятки мегабайт JSON с отступами. Каждая отметка выполняет два сохранения, каждое сохранение полностью сериализует состояние, шифрует его, пишет с принудительным сбросом на диск и копирует три резервные копии. То есть на одну отметку приходится до восьми полных записей файла.
- Записи сверх лимита удаляются молча, без архива и без предложения выгрузить CSV.
- **Исправление:** перейти на журнал с добавлением записей (SQLite или файл-журнал), либо хранить в состоянии только последние отметки, а историю писать отдельно; перед усечением требовать экспорт.
### Н17. 🟡 Приватный режим скрывает имена только в списке
- **Где:** `MainPage.xaml.cs:581`, `:605`
- **Суть:** при включённом маскировании (по умолчанию) список последних отметок показывает «И\*\*\* П\*\*\*», но крупный текст на экране терминала по-прежнему выводит полное имя: «Иван Петров / Приход отмечен в 09:14», то же при отклонении повторного скана.
- **Последствия:** цель находки №26 не достигнута — имя всё равно видно постороннему у терминала, причём более заметно, чем в списке.
- **Исправление:** применять то же маскирование к `TerminalMessage` и к сообщениям строки состояния в публичном режиме.
### Н18. ⚪ Экспорт CSV не фиксируется и не защищён
- **Где:** `MainPage.xaml.cs:641-667`
- **Суть:** экспорт выгружает полные имена, табельные номера, должности и все отметки в произвольный незашифрованный файл. Факт экспорта нигде не сохраняется.
- **Исправление:** записывать в журнал событие экспорта (кто, когда, сколько записей); предупреждать, что файл не зашифрован.
### Н19. ⚪ Изменена уже применённая миграция, контрольные суммы не проверяются
- **Где:** `migrations/0001_infrastructure.up.sql`, `scripts/migrate.mjs`
- **Суть:** файл `0001` изменён задним числом (в `CREATE TABLE` добавлены `subject_*`/`actor_*` и `CHECK`), при этом на уже мигрированных базах таблица создана по старой версии, а колонки добавляет `0002`. Сейчас расхождение компенсируется, но мигратор не хранит контрольные суммы, поэтому следующая правка применённого файла останется незамеченной.
- **Исправление:** хранить хеш файла в `schema_migrations` и падать при расхождении.
### Н20. ⚪ Подстановка Release вместо Debug в пути автозагрузки
- **Где:** `Services/StartupService.cs:25-38`
- **Суть:** если путь процесса содержит `\Debug\`, он заменяется на `\Release\`, а при отсутствии файла выбрасывается исключение. Установка в каталог, в названии которого есть «Debug», сломает автозагрузку; подставленный Release-файл может быть старой сборкой.
- **Исправление:** определять отладочную сборку по `#if DEBUG` или по атрибуту сборки, а не по пути.
### Н21. ⚪ ADR-001 не синхронизирован с кодом
- **Где:** `docs/adr/ADR-001-technology-and-runtime-modes.md:8`, `:12`
- **Суть:** ADR по-прежнему фиксирует Redis/BullMQ как принятое решение, хотя зависимости и сервис удалены; `AGENTS.md` требует синхронизировать ADR при изменении контракта. `docs/ARCHITECTURE.md` обновлён, ADR — нет.
- **Исправление:** дополнить ADR-001 или выпустить ADR-002 «Redis откладывается до появления сценария очередей».
## 5. Находки второго отчёта: почти все открыты
`Services/TerminalStore.cs` в новых коммитах **не менялся**, поэтому связанные находки в силе.
| № | Находка | Статус |
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Н1 | 🔴 После переименования повреждённого файла следующий запуск стартует с пустым состоянием: терминал открыт для создания чужого PIN, резервные копии затираются через 3–4 сохранения. То же при простом удалении файла состояния | ❌ Открыто |
| Н2 | 🟠 Любая ошибка чтения, включая временную блокировку файла антивирусом, считается повреждением; откат к резервной копии происходит без предупреждения | ❌ Открыто |
| Н3 | 🟡 Резервные копии обновляются на каждом сохранении и покрывают 1–2 скана; ошибочная очистка журнала попадает во все копии | ❌ Открыто, усугублено Н16 |
| Н4 | 🟡 `GetDeviceCount() - 1` не проверен на оборудовании | ❌ Открыто |
| Н5 | 🟡 Счётчик неверных PIN живёт в памяти, задержка блокирует и вход по отпечатку, старые хеши не пересчитываются | ❌ Открыто |
| Н6 | ⚪ `Disconnect` освобождает дескрипторы после 2 с ожидания независимо от результата | ❌ Открыто |
| Н7 | ⚪ Самопроизвольная отмена регистрации | 🟨 Частично: добавлено событие `RegistrationCancelled`, но `RefreshLists()` по-прежнему сбрасывает выбор и отменяет регистрацию |
| Н8 | ⚪ Редактирование сотрудника переписывает имена в прошлых отметках | ❌ Открыто |
| Н9 | ⚪ При недоступном хранилище приложение нельзя закрыть штатно | ❌ Открыто |
| Н10 | ⚪ Блокирующие циклы в пуле потоков, гонка при освобождении события активации, мьютекс в пространстве `Local\` | ❌ Открыто |
## 6. Находки первого отчёта: статус
### Закрыто
| № | Находка | Как закрыто |
| ---------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| 1, 4, 5 | Регистрация отпечатка, гонка дескрипторов, потеря связи со сканером | Отмена регистрации, передача дескрипторов, контроль связи (остаточные Н4, Н6) |
| 3 | Гонка записи состояния | `SemaphoreSlim`, `WriteThrough` |
| 6 | RLS обходился суперпользователем | Роль `krona_staff_app` с `NOSUPERUSER NOBYPASSRLS`, тест проверяет `rolsuper`/`rolbypassrls` |
| 7 | Несовпадение паролей в быстром старте | Пароли и URL согласованы |
| 8 | Мигратор | `schema_migrations`, advisory lock, откат только последней, `ALLOW_MIGRATION_DOWN` |
| 9 | Потеря отметок при открытом диалоге | Отметка записывается |
| 11, 12 | Второй экземпляр, дубликат пальца | Мьютекс с активацией, `DBIdentify` перед регистрацией |
| 13 | Журнал без экспорта и без границ | CSV-экспорт и лимит (новые замечания Н16, Н18) |
| 14 | Смена через полночь | Настраиваемая максимальная длительность смены (новое замечание Н15) |
| 15 | `/ready` отдавал 500 с текстом ошибки | 503 без деталей, проверено |
| 16 | Расхождение OpenAPI и маршрутов | Префикс `/api/v1/staff` и тест сверки |
| 17 | Пул PostgreSQL | `pool.on('error')`, `release(error)`, защищённый `ROLLBACK` |
| 18 | Тесты не проверяли инварианты | Реальный тест изоляции двух тенантов, сверка OpenAPI, таймаут 15 с |
| 19 | Аудит-лог и outbox | Политики `SELECT`/`INSERT`, `subject`/`actor`, `CHECK` на ULID |
| 20 | Неиспользуемый Redis | Удалён из зависимостей, compose и конфигурации (ADR не обновлён — Н21) |
| 21, 22 | Автозагрузка | `--autostart` открывает в трее, по умолчанию выключена (остаток — Н20) |
| 23 | Защита последнего администратора | Учитываются все администраторы, отдельная проверка при удалении отпечатков |
| 25 | `Trim` у PIN | Проверяются оба варианта |
| 26 | Имена на публичном экране | Маскирование в списке (неполно — Н17) |
| 27 | Ошибки фоновых задач и `crash.log` | Глобальные обработчики, ротация по 1 МБ на 3 файла |
| 28, 29 | Платформы проекта, шаблонный манифест | Только x64, манифест очищен, BOM убран |
| 31, 32, 33 | `x-correlation-id`, версия, shutdown, CI, digest | Проверка ULID, `src/version.ts` и сверка версий, таймаут остановки, `format:check` в CI, образы по digest, запрет standalone в production |
### Оставлено сознательно и вынесено владельцу
- **№24** — повторный запрос PIN перед разрушительными действиями сохранён по требованию владельца.
- **№30** — EULA ZKTeco добавлена, но сборки терминала и подписи в CI нет: нужны Windows-раннер и сертификат. Стоит отметить, что EULA запрещает включение компонента в продукты, извлекающие из этого коммерческую выгоду, — перед коммерческим распространением нужна юридическая проверка.
- **A1** (роль терминала: локальное хранилище против edge-клиента Staff) и **A2** (письменные согласия на биометрию, сроки хранения, трансграничная передача) — решения владельца и юриста, зафиксированы в `docs/AUDIT-REMEDIATION-2026-09-18.md`.
## 7. Оценка качества исправлений
Сделано аккуратно: исправления не косметические, к ним добавлены тесты (изоляция тенантов, сверка OpenAPI), документация обновлена вместе с кодом, отдельный документ фиксирует, что оставлено сознательно. Обход RLS, мигратор и контракт API — самые опасные места первого отчёта — закрыты по существу, а не «подпоркой».
Основные замечания к процессу:
1. Изменения не проверялись в реальной среде: Docker и PostgreSQL не запускались, поэтому неработающий HEALTHCHECK (Н11) и сломанный путь обновления (Н13) не были замечены. `AGENTS.md` прямо требует не считать Docker и CI проверенными, если среда не запускалась, — документ исправлений это честно фиксирует.
2. Замечания второго отчёта не попали в работу, а хранилище состояния — источник самой опасной из открытых проблем (Н1).
3. Коммиты по-прежнему крупные и смешивают исправления с новыми функциями (экспорт CSV, приватный режим, редактирование).
## 8. План
| Приоритет | Задача | Находки |
| --------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| 1 | Не стартовать с пустым состоянием при наличии `*.corrupt-*`/`.bak*`; не затирать копии; отличать повреждение от временных ошибок | Н1, Н2 |
| 2 | Исправить HEALTHCHECK и добавить проверку сервиса `app` в compose | Н11 |
| 3 | Убрать миграционные учётные данные из контейнера приложения | Н12 |
| 4 | Создание роли приложения в сервисе `migrate`, порядок обновления существующих установок, явная ошибка при отсутствии роли | Н13, Н14 |
| 5 | Журнал с добавлением записей вместо полной перезаписи, резервные копии по времени, ручная правка отметок | Н3, Н15, Н16 |
| 6 | Маскирование имени на главном экране терминала | Н17 |
| 7 | Проверить `GetDeviceCount() - 1` на оборудовании, довести устойчивость сканера | Н4, Н6 |
| 8 | Счётчик попыток PIN в хранилище, не блокировать вход по отпечатку, пересчёт старых хешей | Н5 |
| 9 | Контрольные суммы миграций, обновление ADR-001, аудит экспорта CSV | Н19, Н21, Н18 |
| 10 | Решения владельца: контракт терминала и правовая база обработки биометрии | A1, A2 |

View file

@ -1,56 +0,0 @@
# Приёмка №1: Grok и Antigravity — 2026-09-26
Проверял независимо, на живой PostgreSQL 17.10, в отдельных рабочих копиях. Код веток не менялся. Основа обеих веток — `778ba2d`; текущая основная ветка — `331e490`. Обе ветки вливаются в неё без конфликтов, друг с другом тоже.
## Итог
| Исполнитель | Ветка | Сделано из задания | Вердикт |
| ----------- | -------------------------------------------------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Antigravity | `antigravity/fix-reject-device-shifts` (`795bba0`) | Только часть 0 — немедленная мера по S1 | **Принять после одной правки**: подделка смены с устройства закрыта, но новый тест на реальной базе красный. Части 1–4 не начаты |
| Grok | `grok/e2e-harness` (`421da72`) | Задачи 1–7 | **Принять после двух правок**: стенд работает и честно ловит дефекты, но под Windows не запускается, а ID моего аудита не сопоставлены — файлы аудита до Grok не дошли |
## Antigravity
**Что проверено вживую** ([evidence/acceptance-antigravity-live-sync.txt](evidence/acceptance-antigravity-live-sync.txt)):
- **S1 закрыт.** Устройство отправляет смену `status: confirmed, worked_minutes: 2880`. Ответ: `rejected / COMMAND_NOT_SUPPORTED`, смена не создана, расчёт по ней начисляет 0 ₽. До исправления было 14 400 ₽.
- **Сценарии Grok на этой ветке.** SYNC-A и SYNC-B (устройство не может подтвердить смену и утвердить табель) стали зелёными ([evidence/acceptance-grok-sync-with-antigravity.txt](evidence/acceptance-grok-sync-with-antigravity.txt)).
- **Штатные проверки.** lint, typecheck, сборка, миграции и контракты проходят; 188 тестов пройдено. `format:check` красный только по чужим старым файлам, файлы Antigravity отформатированы.
**Что не так:**
1. **Новый тест на реальной базе падает.** В очистке `tests/integration/sync-rejection.test.ts:69-74` запись удаляется ролью приложения, а у неё нет права DELETE на `staff_timesheet_entries` и `staff_employees`. Это тот же дефект, что N5. Проверка внутри теста проходит, но сам файл красный — значит, на живой базе тест не запускался. Исправление: очистка ролью мигратора, как Grok сделал для N5.
2. **Сделана только часть 0.** Не начаты: синхронизация S2–S9 (S2 и S9 проверил на этой ветке — оба по-прежнему воспроизводятся), SSRF через push (K12), оповещения процесса подтверждения, публикатор outbox.
3. **Сообщение коммита — один абзац в строке заголовка.** Нужны короткий заголовок и причина в теле (AGENTS.md).
4. **После влития нужно синхронизироваться с Grok.** SYNC-A и SYNC-B надо убрать из `tests/e2e/known-defects.json` — иначе CI упадёт с «дефект исправлен, обновите список». Это зона Grok.
## Grok
**Что проверено** ([evidence/acceptance-grok-e2e.txt](evidence/acceptance-grok-e2e.txt)):
- **Зона соблюдена.** Изменены только `tests/e2e/**`, `tests/integration/tenant-isolation.test.ts`, `.forgejo/workflows/ci.yml` и `scripts/test/**`. Продукт не тронут.
- **Коммиты оформлены правильно.** 12 маленьких коммитов, у каждого в теле объяснена причина.
- **Стенд работает.** Прогон на моей PostgreSQL дал **38 красных и 9 зелёных** — ровно как в его отчёте. Красные совпадают с моими находками: N1, N2, N3, N4, N9, N10, N11, N12, F2, F3, F4, F7, F10, решения владельца OWN-01…11, синхронизация, пилотный compose.
- **Логика «известных дефектов» верная.** Известный красный сценарий не роняет CI. Исправленный дефект, который остался в списке, роняет CI. Незнакомый красный сценарий тоже роняет CI. Так исправление не пройдёт незамеченным, и регрессия тоже.
- **Новая находка, которой не было у меня (SYNC-C0).** Начальная загрузка данных на устройство на реальной базе всегда отвечает 500: `column "status" does not exist`. Офлайн-синхронизация фактически не работает на приём данных. Это задача для Antigravity.
**Что не так:**
1. **Под Windows стенд не запускается**, а проект разрабатывается под Windows:
- `scripts/test/run-e2e.mjs:35` — `spawn('npx')`;
- `tests/e2e/harness/global-setup.ts:67` и `scripts/test/n13-race.mjs:102` — `spawn(node_modules/.bin/tsx)`.
Всё это даёт `ENOENT`, потому что в Windows это `.cmd`. Исправление: `spawn(process.execPath, [<путь к tsx/dist/cli.mjs>, …])` и то же для vitest. С такой локальной правкой я и проводил прогон.
2. **ID моего аудита не сопоставлены.** Файлы `AUDIT.md` и `evidence` до Grok не дошли. Он это честно отметил: K1, K3–K6, K10–K12, S1, S2, S9 и A4 помечены «не проверено». Сценарии фактически покрывают те же дефекты под его номерами, нужно только переименовать теги.
3. **PR не создан**: у Grok нет токена Forgejo. Описание лежит в `tests/e2e/REPORT.md`. Также `tests/e2e/evidence/` коммитится в репозиторий и будет меняться при каждом прогоне — лучше хранить это как артефакт CI.
## Что делать дальше
1. **Влить Grok первым** (только тесты и CI) — после исправления запуска под Windows.
2. **Влить Antigravity** — после исправления очистки в тесте. В том же PR или сразу после Grok убирает SYNC-A и SYNC-B из списка известных дефектов.
3. **Antigravity продолжает** части 1–4 задания, плюс SYNC-C0 (загрузка на устройство падает на реальной базе).
4. **Grok сопоставляет ID** с моим аудитом, когда получит файлы.
5. **Codex.** В репозитории уже есть ветки `codex/fix-format-baseline` и `codex/fix-live-database` (этапы 0 и 1). Их можно принимать следующими.
Стенды удалены, база остановлена. В этой приёмке ничего не влито и не запушено.

View file

@ -1,213 +0,0 @@
# Полный аудит krona-staff — 2026-09-26
- Аудитор: Claude (Opus 5.5), режим только чтения: код, ветки и удалённый репозиторий не менялись
- Проверено: основная ветка `codex/bootstrap-platform-foundation` на коммите `3e20544` (2026-09-26 12:31 +07, версия 0.3.2) и ветки `antigravity/offline-sync-backend` (`5ee7517`, офлайн-синхронизация) и `codex/frontend-library` (`1812870`, оформление портала)
- Действует для: `778ba2d` — текущая основная ветка, в которую обе ветки влиты без изменения проверенного кода
- Сверка: аудит Grok на том же коммите `3e20544` (14 старых и 14 новых находок) — каждая перепроверена заново
- Доказательства: папка [evidence](evidence) — сценарии живой проверки и их вывод
> Во время проверки обе ветки были влиты в основную (`3595792`), плюс косметический коммит `778ba2d`. Код синхронизации совпадает с проверенным `5ee7517`, поэтому находки S1–S9 относятся к основной ветке, а S1 (устройство создаёт подтверждённые смены, и они попадают в зарплату) — действующий дефект.
## 1. Итог в трёх строках
1. **Выпускать нельзя.** На настоящей PostgreSQL главная цепочка «подтвердить смену → рассчитать → утвердить» не работает (500), а создать сотрудника через API невозможно.
2. **Деньги считаются неверно даже там, где работает.** Одна смена может быть оплачена трижды, утверждённую смену можно отклонить задним числом без сторно, импорт из Excel теряет суммы, а устройство офлайн-синхронизации может само создать «подтверждённую» смену на 48 часов.
3. **Терминал пока не отправляет отметки на сервер.** Сотрудники на терминале получают свои идентификаторы, сервер их не знает и отвечает 404; связь служба ↔ интерфейс не работает из-за разных имён канала.
## 2. Что реально запускалось
| Проверка | Результат |
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `npm ci`, lint, typecheck, build, check:migrations, check:contracts | пройдено |
| `format:check` | не пройдено — 16 файлов ([evidence/format-check.txt](evidence/format-check.txt)) |
| vitest без базы | 156 пройдено, 1 пропущен |
| vitest на живой PostgreSQL 17.10 (роль приложения) | тест изоляции арендаторов падает при очистке: `permission denied for table staff_employees` |
| Миграции 0001–0010 мигратором **без** SUPERUSER: вверх, откат 10 шагов, вверх, повтор | пройдено |
| Миграции ветки синхронизации 0001–0011, откат 0011 и повтор | пройдено |
| `scripts/create-app-role.mjs` мигратором без SUPERUSER | ошибка `permission denied to alter role` |
| RLS на живой базе | 23 из 23 таблиц с `tenant_id`: ENABLE + FORCE + политика; роль приложения без SUPERUSER, BYPASSRLS, CREATEROLE; журналы только на чтение и вставку |
| Живой API: сервер на реальной базе, реальные HTTP-запросы | 19 сценариев, см. раздел 4 |
| `npm audit` (всё и production) | 0 уязвимостей |
| .NET: сборка службы Release, тесты терминала | сборка без ошибок; тесты 43 из 43 |
| Named pipe службы | проверено запуском отдельного тестового проекта |
| Не проверено | Docker и compose (нет на машине), WinUI-интерфейс вживую, DPAPI и ACL на отдельной Windows-машине, Snyk, реальные push-сервисы |
Стенд: Windows 11, Node 24, PostgreSQL 17.10 (встроенная сборка), .NET 10 SDK. База аудита создавалась в UTF-8; первая попытка в WIN1251 дала ложную ошибку кодировки, её результаты отброшены.
## 3. Сводка
| Уровень | Открыто | Из них подтверждено вживую |
| ------- | ------- | -------------------------- |
| P0 | 2 | 1 |
| P1 | 17 | 10 |
| P2 | 32 | 6 |
| P3 | 31 | 3 |
Сверка с Grok: из его 28 находок 22 подтверждены, 4 подтверждены частично (F8, F11, N7, N10), 1 исправлена (F5), 1 не воспроизведена (N13). Сверх Grok — 57 новых замечаний, главное — в денежной логике, терминале, эксплуатации и офлайн-синхронизации.
## 4. Подтверждено на живом сервере
| ID | Что проверено | Результат |
| --- | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| F2 | Сервер без токенов, `STANDALONE_ACCESS=manager`, запросы без авторизации | `GET /portal` 200, `GET /payroll` 200, `GET /finance` 200, **запись** `POST /professions` 201 |
| F2 | То же при `STANDALONE_ACCESS=employee` (значение по умолчанию в compose) | `GET /portal` 200, `GET /payroll` 200 анонимно |
| F3 | Вход менеджером, выход, повтор старой cookie | cookie содержит сам токен менеджера; после `DELETE /session` старая cookie даёт `GET /portal` 200 |
| F4 | 60 неверных входов подряд | 60 × 401, ни одного 429 |
| N1 | `POST /employees` | 500, `42P08 inconsistent types deduced for parameter $2` |
| N2 | Подтверждение смены, расчёт | оба 500, `23502 null value in column "occurred_at" of relation "staff_outbox"` |
| N4 | Одна смена 8 ч × 300 ₽, три пересекающихся расчёта с утверждением | 3 начисления в реестре, **7 200 ₽ вместо 2 400 ₽** |
| D5 | Отклонение смены, уже оплаченной по утверждённой ведомости | 200, сторно не создано, начисления остались |
| N12 | Ставка `rate_minor = 1e20` с лишним полем | принято, 200 |
| — | Расчёт за `month = 2026-13` | 500 |
| N3 | Сотрудник подписывает push на `https://127.0.0.1:18443`, затем отметка на терминале | сервер открыл соединение на внутренний адрес и отправил TLS ClientHello |
| N9 | Сотрудник Б регистрирует endpoint сотрудника А | 201, подписка перешла к Б |
| A4 | Ошибки 500 | наружу уходят код и текст ошибки PostgreSQL |
| N10 | Токен терминала | `GET /professions` 200 со всем справочником; `GET /org-units` отдаёт пустой список — эта часть находки Grok не подтвердилась |
| N13 | Два одновременных первых расчёта периода | **не воспроизведено**: обе заявки получили один расчёт |
| S1 | Устройство синхронизации отправляет смену `status: confirmed, worked_minutes: 2880` | смена сохранена подтверждённой, подтвердил «никто», журнал аудита пуст; расчёт начислил **14 400 ₽** |
| S2 | Устройство отправляет отметку с `occurred_at = 2020-01-01` | сохранена |
| S9 | Удаление точки, к которой привязано устройство синхронизации | ошибка `23502 null value in column "tenant_id"` — точку удалить нельзя |
| — | Заголовки портала | CSP `script-src 'self'`, HSTS присутствуют |
Для N4, D5 и S1 в базе аудита временно задавалось значение по умолчанию для `staff_outbox.occurred_at` (иначе мешает N2); после сценария оно снималось.
## 5. P0 — блокируют любое использование вне стенда
**K1. Открытый режим без токенов (F2, подтверждено вживую).** Если токены менеджера и терминала не заданы, любой запрос без авторизации получает права `STANDALONE_ACCESS` (`src/adapters/identity.ts:32-49`, `src/config.ts:45-47`). Корневой `compose.yaml` публикует порт 8080 на всех интерфейсах по HTTP и токенов не задаёт; в пилотном compose переменные подставляются без `:?`, поэтому пустая строка в `.env` молча открывает сервис.
**K2. Production-режим недостижим, пилот работает как development (F1).** Адаптер платформенного JWT — заглушка (`identity.ts:60-66`), standalone в production запрещён. Поэтому оба compose ставят `NODE_ENV=development` (`compose.yaml:5`, `deploy/pilot/compose.yaml:8`) — это обходит проверки «standalone запрещён» и «HTTPS обязателен» на пилоте с реальными ФИО и зарплатами.
## 6. P1 — денежная логика и работоспособность
| ID | Суть | Где | Подтверждение |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ---------------------------------- |
| K3 (N2) | Вставки в outbox без `occurred_at`: подтверждение смены, расчёт и утверждение всегда 500 | `src/portal.ts:1145-1163`, `src/domain/payroll/service.ts:770-784`, `917-935` | вживую |
| K4 (N1) | `POST /employees` всегда 500 из-за типа параметра `$2` | `src/portal.ts:465-483` | вживую |
| K5 (N4) | Пересекающиеся и «точка / все точки» расчёты начисляют смену повторно; при пересчёте не обновляется `period_end` | `service.ts:425-454`, `759-768`, `860-903`; индексы `0006:196-199` | вживую, 7 200 ₽ за 2 400 ₽ |
| K6 (D5) | Смены и строки утверждённой ведомости можно менять; у роли приложения есть DELETE на строки и UPDATE на ведомости, неизменяемость держится только кодом | `portal.ts:1024-1106`, `0006:296-300` | вживую |
| K7 (D2) | Импорт начислений и выплат теряет деньги: дельта считается по всем записям дня, а вставка по конкретному ключу | `src/operations.ts:1017-1052`, `scripts/import-owner-workbook.py:147,168,176` | по коду |
| K8 (D1) | Версии правил фиктивны: v1 изменяемая, даты действия не учитываются, условия точки не читаются, в строке ведомости нет дерева правила и ревизии смены — утверждённый расчёт нельзя воспроизвести | `service.ts:152-180`, `517-529`, `686-695` | по коду |
| K9 (D3) | Параметры пресетов кроме ставки, процента и гарантии не сохраняются, метрики кроме выручки и позиции не загружаются: официант по пресету получает 0 ₽, премия за порог выручки — 0 ₽ | `service.ts:295-299`, `488-500`; `src/portal-ui.ts:273-275` | по коду |
| K10 (F3) | В cookie лежит сам токен, выход не отзывает сессию; токен сотрудника бессрочный | `portal.ts:262-276` | вживую |
| K11 (F4, A2) | Нет ограничения частоты; каждый неверный токен открывает транзакцию в БД при пуле 10 соединений — отказ в обслуживании | `portal.ts:1276-1296`, `src/infrastructure/database.ts:9` | вживую (F4) |
| K12 (N3) | SSRF через push-подписку: разрешён любой `https://`, редиректы следуются, фрагмент ответа сохраняется | `src/domain/notification/push-dispatcher.ts:80`, `web-push.ts:226-258` | вживую |
| K13 (S1) | Офлайн-синхронизация: устройство создаёт и перезаписывает подтверждённые смены и строки табеля | `src/domain/sync/service.ts:784-990` | вживую, 14 400 ₽ |
| K14 (T4) | Отметки терминала не доходят до сервера: локальные ULID сотрудников сервер не знает (404), повтор каждые 15 с бесконечно; контракт в `docs/TERMINAL-API-REQUIREMENTS.md` расходится с кодом | `apps/KronaStaffTerminal/MainPage.xaml.cs:479-492`, `TerminalModels.cs:157` | по коду + ответ сервера 404 |
| K15 (T1) | Служба создаёт pipe `\\.\pipe\global\KronaStaffTerminalPipe`, интерфейс подключается к `\\.\pipe\KronaStaffTerminalPipe`: IPC не работает, свободное имя может занять любой процесс и получать отметки с ФИО | `apps/KronaStaffTerminal/Services/TerminalIpc.cs:84`, `:236` | проверено запуском |
| K16 (T2) | Служба от LocalSystem выдаёт операторам полный доступ к каталогу данных и сама ротирует там логи и меняет ACL — путь к правам SYSTEM через junction | `TerminalStore.cs:305-360`, `CrashLogService.cs:331-371`, `installer/KronaStaffTerminal.nsi:119` | по коду (механизм), PoC не делался |
| K17 (T5) | Биометрия: нет письменного согласия (152-ФЗ ст. 11), шаблоны остаются в резервных копиях после удаления, уведомления в Telegram — трансграничная передача | `MainPage.xaml.cs:685-776`, `TerminalStore.cs:96-100, 376-384` | по коду |
| K18 (D1 эксплуатации) | Нет резервного копирования пилотной базы с реальными ФИО, табелем и зарплатой; `BACKUP-RESTORE.md` — только шаблон | `docs/BACKUP-RESTORE.md`, `deploy/pilot/` | по коду |
| K19 (D4 расчёта) | Утверждается устаревший расчёт: ревизии смен и выручки не сверяются, предупреждения «нет выручки», «нет профиля оплаты» не сохраняются, сотрудник без профиля выпадает из фонда и его долю делят остальные | `service.ts:632-641`, `840-903` | по коду |
## 7. P2
**Сервер и расчёт**
- N5 — тест изоляции арендаторов удаляет сотрудников ролью приложения, у которой нет DELETE: CI с базой красный (подтверждено). Маршрутные тесты работают на поддельной базе, поэтому N1 и N2 не ловятся.
- N6 — `create-app-role.mjs` требует мигратора-суперпользователя (подтверждено).
- N7 — импорт-скрипт отключает проверку TLS при `--allow-self-signed` и принимает токен в аргументах командной строки. **Уточнение к Grok:** ответа 400 на `/professions` не будет — Fastify по умолчанию молча отбрасывает лишние поля (`removeAdditional`), поэтому ответ 201, а задуманный код профессии теряется.
- N12, D9 — нет верхних границ ставок и `additionalProperties:false` на назначении оплаты; `2026-13` и `2026-02-30` проходят шаблон и дают 500 (подтверждено).
- F7 — `Idempotency-Key` и таблица ключей не используются, хотя ADR и контракт приложения их требуют.
- F9 — healthcheck в Dockerfile по HTTP при HTTPS-only production.
- F10, A6 — проверка Origin пропускает запросы без Origin и с любым `Authorization`; практическая эксплуатация закрыта `SameSite=Strict`, но должно быть fail-closed.
- A3 — один общий токен терминала на все устройства, отметки до 180 дней назад.
- A4 — ошибки 500 раскрывают текст PostgreSQL (подтверждено).
- D6 — одна роль «менеджер» и считает, и утверждает, и выплачивает, без привязки к точке — разделения обязанностей нет.
- D13 — `additionalProperties:false` в схемах на деле не отклоняет лишние поля, а молча их удаляет: опечатки клиентов не видны.
- D7 — округление строк после деления фонда выплачивает на 1 ₽ больше фонда; вес фонда у правила без доли фонда теряет эту часть фонда.
**Уведомления и outbox**
- F6 — outbox пишется, но публикатора нет, `dispatchPending` не вызывается, строки в `pending` не повторяются никогда; отправка живёт в `setImmediate` и теряется при рестарте.
- U1 — некорректные ключи подписки роняют цикл отправки остальным устройствам.
- U2 — нет лимита подписок и таймаутов: одна отметка может породить тысячи запросов.
- U3 — нет захвата строки при отправке: при двух экземплярах возможна двойная отправка.
**Офлайн-синхронизация**
- S2 — время отметки задаётся клиентом без ограничений (подтверждено: 2020 год принят).
- S3 — гонки идемпотентности, потеря обновлений без проверки ревизии, одна плохая команда откатывает весь пакет из 100.
- S4 — начальная синхронизация отдаёт устройству весь арендатор, включая уволенных и всю историю минут.
- S5 — курсор теряет изменения за пределами первых 100 строк; изменения из портала устройство не видит.
- S6 — отметки через синхронизацию не пишут outbox и принимаются для уволенных.
- S9 — внешний ключ `ON DELETE SET NULL` на составном ключе ломает удаление точки (подтверждено).
**Терминал и служба**
- T3 — член группы операторов может расшифровать состояние: хеш PIN, токены сервера и ботов, токен обновлений, шаблоны отпечатков.
- T6 — служба и интерфейс перезаписывают один файл без межпроцессной блокировки: теряются смена PIN, счётчик попыток, блокировки.
- T7 — установщик не задаёт ACL на выбранный каталог установки; предсозданный пользователем каталог данных остаётся в его владении.
- T8 — терминал запускается с правами администратора после установки и автообновления; через диалог экспорта можно получить оболочку.
- T9 — проверка обновления сильная (HTTPS, SHA-256, Authenticode, закреплённый издатель), но файл проверяется в профиле пользователя и запускается позже (TOCTOU); на каждом терминале лежит токен чтения приватного репозитория.
- T10 — служба от SYSTEM загружает `libzkfp.dll` по PATH, если драйвер не установлен.
**Эксплуатация**
- D3 — самоподписанный сертификат на IP: у сотрудников не заработают PWA и push; ключ лежит рядом с pfx незашифрованным; продление ломает пиннинг на всех терминалах.
- D4 — обновление без тегированных образов и отката, без бэкапа перед миграцией, без `lock_timeout`.
- D5 — скрипт настройки терминала пишет не туда, где терминал читает состояние после переноса в `%ProgramData%`.
- D6 — `docker build` в CI внутри docker-раннера, down-миграции в CI не проверяются, пилотный compose тестами не покрыт.
## 8. P3 (кратко)
N8 эфемерные VAPID-ключи и кэш публичного ключа на сутки; N9 перепривязка чужого endpoint (подтверждено, но нужен секретный endpoint); N10 справочник профессий без проверки прав; N11 слабая валидация импорта; N13 гонка первого расчёта (не воспроизведена); N14 GET-запросы переписывают правило v1; F12 деньги в `number`; F13 плавающие теги в CI; F14 форматирование 16 файлов; A5 валидация и импорт до проверки прав, открытый `/openapi.json`; A7 новый токен сотрудника без `no-store`; A8 все менеджеры — один актор в аудите; A9 correlation id от клиента; U4 нет политики повторов и dead letter; U5 scope service worker не покрывает `/staff`; U6 выход не отзывает push-подписку; U7 FK без `tenant_id`; S7 очистка входящих не работает (передаётся не тот идентификатор); S8 CSRF и белый список scope устройств; W1 `/staff/*` отвечает 200 на любой путь; T11 DoS через IPC до проверки HMAC; T12 нет backoff в синхронизации терминала; T13 молчаливый откат службы к резервной копии, нет порога совпадения отпечатка; D8 документация расходится с кодом; D9 нет лимитов ресурсов контейнеров; D10 `.dockerignore` не исключает `deploy/pilot/.env` и секреты; D11 миграции из build-стадии от root; D12 smoke-тест ничего не проверяет и пишет в боевую базу; D14 нет редактирования PII в логах; D15 дефолты корневого compose; D16 коммиты без тела и смешанные по темам, 67 файлов bin/obj в истории.
## 9. Сверка с аудитом Grok
| ID Grok | Вердикт | Комментарий |
| ---------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------- |
| F1, F2, F3, F4 | подтверждено | F2–F4 вживую; к F1 добавлено: пилот обходит запрет через `NODE_ENV=development` |
| F5 | исправлено | неизвестный сотрудник → 404 |
| F6 | подтверждено, серьёзнее | строки `pending` не повторяются никогда |
| F7, F9, F12, F13, F14 | подтверждено | F13: `ajv allErrors` в проверке контрактов вектором не является |
| F8 | исправлено по форме, остаток P1 | ACL и HMAC есть, но имена pipe не совпадают (K15) |
| F10 | подтверждено, практически закрыто cookie `SameSite=Strict` | |
| F11 | API есть, но неработоспособно на реальной базе (K3) | |
| N1, N2, N3, N4, N5, N6 | подтверждено вживую | |
| N7 | частично | TLS и токен в argv — да; ответ 400 — нет (поля молча отбрасываются) |
| N8, N11, N12, N14 | подтверждено | |
| N9 | подтверждено вживую | эксплуатация требует знать секретный endpoint |
| N10 | частично | `/professions` — да; `/org-units` для не-менеджеров отфильтрован |
| N13 | не воспроизведено вживую | по коду возможно, оставлено P3 |
Чего в аудите Grok нет: денежные дефекты K6–K9 и K19, терминал K14–K17, отсутствие бэкапа, пилот в режиме development, ветка синхронизации целиком (она появилась после его аудита).
## 10. Что сделано хорошо
- Изоляция арендаторов: RLS с FORCE на всех 23 таблицах, составные внешние ключи, `set_config(..., true)` в транзакции, арендатор никогда не берётся из запроса.
- Роли базы: приложение без SUPERUSER и BYPASSRLS, журналы начислений и аудита — только чтение и вставка на уровне прав.
- Миграции: SHA-256, advisory lock, откат только последней и только явным флагом; работают мигратором без суперпользователя.
- Токены: сравнение за постоянное время, 256 бит, в базе только хеш; cookie `__Host-`, HttpOnly, Secure, SameSite=Strict; CSP `script-src 'self'`, экранирование в портале.
- Web-push: шифрование по RFC 8291/8188 и VAPID реализованы корректно, в уведомлениях нет персональных данных.
- Калькулятор: чистая функция, распределение фонда методом наибольшего остатка, тесты на реальной таблице владельца.
- Терминал: закрыты все прошлые находки по хранилищу и PIN (Argon2id, маркер первичной настройки в HKLM, отличие повреждения от временной ошибки), шаблоны отпечатков не уходят на сервер, автообновление проверяет подпись и издателя.
- Контейнеры не от root, read-only, образы по digest; секретов в истории нет; UTF-8 без BOM и LF соблюдены.
## 11. Порядок исправлений
1. **Разблокировать работу на базе:** K3 (одна строка в трёх местах), K4 и сразу интеграционные тесты этих маршрутов на PostgreSQL в CI.
2. **Закрыть открытый доступ и пилот:** K1, K2 (профиль `pilot` с обязательными токенами и HTTPS), K10, K11, бэкап K18.
3. **Деньги:** K5, K6, K7, K8, K9, K19 — до первого боевого расчёта.
4. **Синхронизация (уже в основной ветке):** сразу отключить приём смен и табеля от устройств и не регистрировать устройства в пилоте; затем закрыть K13, S2, S3, S9.
5. **Уведомления:** K12, F6, U1–U3.
6. **Терминал:** K14 (без этого отметки не попадают на сервер), K15, K16, K17.
7. P2 и P3 по мере работы.
Распределение по исполнителям — в файлах [TASK-CODEX.md](TASK-CODEX.md), [TASK-ANTIGRAVITY.md](TASK-ANTIGRAVITY.md), [TASK-GROK.md](TASK-GROK.md).
## 12. Решения владельца (2026-09-26)
**Роли и точки (закрывает вопрос D6):**
- **бухгалтер** готовит расчёт и ведомость выплат и отправляет пакет на подтверждение;
- **руководитель** получает оповещение, просматривает и подписывает пакет (или возвращает с комментарием); только его подпись регистрирует начисления и выплаты — руководитель проводит оплаты;
- **управляющий** привязан к своим точкам и работает с ними; утверждать и выплачивать не может;
- сотрудники и управляющие **могут работать на других точках**: привязка к основной точке сохраняется, но смена на другой точке допустима и относится к той точке, где отработана.
**Согласие на обработку биометрии (закрывает вопрос K17):** согласие обязательно; подтверждается в мобильном приложении сотрудника при авторизации.
Юридическая оговорка для исполнителя: 152-ФЗ требует для биометрии согласия в письменной форме. Электронное согласие равнозначно письменному, если подписано электронной подписью, в том числе простой, при наличии соглашения о её использовании (например, пункт трудового договора или локального акта). Текст согласия и такое соглашение готовит юрист.
## 13. Локальная ветка
Ветка `codex/payroll-foundation` удалена по решению владельца. Её незакоммиченные копии, уже влитые в основную ветку коммитом `3464998`, сохранены в `git stash` на случай сверки.

View file

@ -1,22 +0,0 @@
# Аудит 2026-09-26 и задания исполнителям
Рабочая папка аудита: исполнители берут отсюда задания и отчитываются через git.
| Файл | Что это |
| ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
| [AUDIT.md](AUDIT.md) | Полный аудит на живой PostgreSQL 17: находки P0–P3, сверка с аудитом Grok, решения владельца |
| [ACCEPTANCE-1.md](ACCEPTANCE-1.md) | Приёмка первого круга работ Grok и Antigravity |
| [TASK-CODEX.md](TASK-CODEX.md) | Codex: сервер, расчёт, база, пилот, терминал, роли, подтверждение и согласие — этапы 0–6 |
| [TASK-ANTIGRAVITY-2.md](TASK-ANTIGRAVITY-2.md) | Antigravity, **текущий круг**: синхронизация, push, оповещения, outbox |
| [TASK-GROK-2.md](TASK-GROK-2.md) | Grok, **текущий круг**: запуск стенда под Windows, сопоставление ID, недостающие сценарии, приёмка |
| [TASK-ANTIGRAVITY.md](TASK-ANTIGRAVITY.md), [TASK-GROK.md](TASK-GROK.md) | Задания первого круга, для истории |
| [evidence/](evidence) | Сценарии живой проверки и их фактический вывод |
## Как работать
- Каждый исполнитель работает в своих ветках и только в своей зоне файлов — зоны перечислены в задании.
- Готовность пункта подтверждается зелёным сценарием стенда Grok (`node scripts/test/run-e2e.mjs`) на живой PostgreSQL, а не тестами на поддельной базе.
- Отчёт о выполненном — в описании ветки или коммита: ID, коммит, какой сценарий стал зелёным.
- Приёмку каждой ветки независимо проводит Grok; итог следующего круга появится здесь как `ACCEPTANCE-2.md`.
Решения владельца (роли, точки, процесс подтверждения, согласие) — раздел 12 в [AUDIT.md](AUDIT.md) и раздел «Решения владельца» в [TASK-CODEX.md](TASK-CODEX.md).

View file

@ -1,116 +0,0 @@
# Задание для Antigravity, круг 2: синхронизация, push, outbox
- Репозиторий: https://git.ochenstarik.ru/ochenstarik/krona-staff
- Основа: текущая основная ветка `codex/bootstrap-platform-foundation` (`331e490`)
- Задание самодостаточное; полный аудит и доказательства — в `docs/audit/2026-09-26/`.
## Итог приёмки прошлого круга
Ветку `antigravity/fix-reject-device-shifts` (`795bba0`) проверили на живой PostgreSQL 17.
**Что сработало:**
- Подделка смены с устройства закрыта. Смена `status: confirmed, worked_minutes: 2880` теперь получает `rejected / COMMAND_NOT_SUPPORTED`. Раньше она начисляла 14 400 ₽, теперь 0 ₽.
- Сценарии Grok SYNC-A и SYNC-B на этой ветке зелёные.
**Что не так:**
1. `tests/integration/sync-rejection.test.ts:69-74` на реальной базе падает. Очистка идёт ролью приложения, а у неё нет права DELETE на `staff_timesheet_entries` и `staff_employees`. Проверка внутри теста проходит, но файл красный — значит, на живой базе тест не запускали.
2. Сообщение коммита — один абзац в строке заголовка. Нужен короткий заголовок, а причина — в теле.
3. Из задания сделана только немедленная мера. Остальные части не начаты.
## Как работать в этом круге
- **Ветки.** `antigravity/fix-<тема>` от `331e490`, по одной на каждый пункт ниже. Маленькие коммиты: заголовок до 72 символов, причина в теле (AGENTS.md).
- **Проверка на живой базе обязательна.** В репозитории есть стенд Grok (ветка `grok/e2e-harness`, после влития — в основной):
- `scripts/test/provision-pg.mjs` создаёт роли как в пилоте: мигратор без SUPERUSER, приложение без BYPASSRLS;
- `node scripts/test/run-e2e.mjs` прогоняет сценарии на реальном сервере и реальной PostgreSQL 17.
Пункт считается сделанным, когда соответствующий сценарий стал зелёным. Номера сценариев указаны в таблицах.
- **Очистка в тестах** — ролью мигратора, как в `tests/integration/tenant-isolation.test.ts` после исправления Grok. Роли приложения удалять запрещено, так задумано.
- **Список известных дефектов.** После каждого исправления сообщи Grok ID сценариев, которые стали зелёными, — он уберёт их из `tests/e2e/known-defects.json`. Сам этот файл не правь: иначе CI упадёт с «дефект исправлен, обновите список».
- **Outbox.** Писать в `staff_outbox` только через общий хелпер, который делает Codex (ветка `codex/fix-live-database`). Во вставке обязательно поле `occurred_at` — без него подтверждение и расчёт падают.
**Твоя зона:**
- `src/sync.ts`, `src/domain/sync/**`, миграции синхронизации;
- `src/domain/notification/**`, маршруты `/push/*`;
- service worker и подписка в `src/portal-ui.ts`;
- диспетчер и публикатор outbox.
**Не трогай:** авторизацию, сотрудников, смены, расчёт, терминал и развёртывание — это зона Codex; `tests/e2e/**` и CI — зона Grok.
## 1. Довести прошлую ветку (сегодня)
| Что сделать | Готово, когда |
| --------------------------------------------------------------- | ----------------------------------------- |
| Очистка в `sync-rejection.test.ts` — ролью мигратора | Тест зелёный на живой базе |
| Перебазировать ветку на `331e490`, переписать сообщение коммита | Ветка вливается в основную без конфликтов |
## 2. Синхронизация на реальной базе не работает (срочно)
| ID | Что сломано | Где | Готово, когда |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | --------------- |
| SYNC-C0 | Начальная загрузка на устройство (`/sync/pull` без курсора) всегда отвечает 500: `column "status" does not exist`. Запрос обращается к столбцу, которого в таблице нет | `src/domain/sync/service.ts`, начальная загрузка | SYNC-C0 зелёный |
## 3. Синхронизация: остальные дефекты
| Мой ID | Сценарий Grok | Что сделать | Готово, когда |
| ------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| S2 | SYNC-J | `occurred_at` — строгий ISO с часовым поясом. Устройство передаёт своё текущее время, сервер вычисляет расхождение часов и ограничивает время отметки относительно момента получения. При большом расхождении — `pending_review`. Сейчас отметка с датой 2020 года принимается | SYNC-J зелёный |
| S3 | SYNC-G | Сначала захватить ключ идемпотентности, потом выполнять команду. `SAVEPOINT` на каждую команду. Проверять ревизию в UPDATE. `source_event_id = sync:{device}:{key}`. Временные отказы не кэшировать | Битая команда не откатывает весь пакет; две параллельные отправки с одним ключом выполняются один раз |
| S4 | SYNC-E, SYNC-F | Начальная загрузка — только по точке устройства, только активные сотрудники, ограниченное окно дат, пагинация в SQL. Отметки уволенных отклонять. Точку брать из устройства; чужую точку в payload отклонять | SYNC-E и SYNC-F зелёные |
| S5 | SYNC-C, SYNC-D | Курсор не теряет данные при `has_more`. Порядок — по фиксации транзакций, а не по `BIGSERIAL`. Изменения из портала видны устройству. Устаревший курсор запускает повторную начальную загрузку | SYNC-C и SYNC-D зелёные |
| S6 | — | Отметки через синхронизацию пишут outbox (через общий хелпер), как онлайн-маршрут | Отметка через синхронизацию порождает событие |
| S7 | — | Очистка входящих получает `tenant_id`, а не идентификатор системного актора (`service.ts:1056`), и запускается по расписанию | — |
| S8 | SYNC-H | Проверка Origin на маршрутах управления устройствами, белый список scope, `no-store` на ответе с токеном устройства | SYNC-H зелёный |
| S9 | попроси Grok добавить | Внешний ключ `(tenant_id, org_unit_id) ON DELETE SET NULL` обнуляет и `tenant_id`, поэтому удаление точки с привязанным устройством падает с `23502`. Новой миграцией заменить на `SET NULL (org_unit_id)` или `RESTRICT` | Точку можно удалить или получить понятный отказ |
| — | SYNC-I | Без настроенных токенов анонимный запрос не должен регистрировать устройство. Сделать вместе с Codex: он закрывает открытый режим без токенов (F2) | SYNC-I зелёный |
| — | SYNC-K | Подтверждение курсора «из будущего» (больше выданного сервером) отклонять с 400 | SYNC-K зелёный |
## 4. Push-уведомления
| Мой ID | Сценарий Grok | Что сделать | Готово, когда |
| ------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- |
| K12 | N3 | SSRF: сейчас сотрудник подписывает push на `https://127.0.0.1:…`, и сервер сам туда подключается. Разрешать только известные push-сервисы (FCM, Mozilla, Apple, WNS). После DNS запрещать приватные, loopback и link-local адреса. `redirect: 'manual'`, таймаут 5–10 с, тело ответа не сохранять. Где: `push-dispatcher.ts:80`, `web-push.ts:226-258` | N3 зелёный |
| N9 | N9 | Конфликт endpoint с другим сотрудником — ответ 409. Перепривязка разрешена только тем же браузером | N9 зелёный |
| N8 | — | В production без `VAPID_*` сервер не стартует. Публичный ключ отдавать с `no-cache` | — |
| U1–U4 | — | Проверять ключи подписки при регистрации. Ошибка по одной подписке не прерывает отправку остальным. Не больше 5–10 подписок на сотрудника. Таймаут и лимит чтения ответа 1 КБ. Атомарный захват строки перед отправкой (`sending` плюс аренда), повторы с backoff, dead letter | Два экземпляра сервера не отправляют сообщение дважды |
| U5–U7 | — | Scope service worker покрывает `/staff`. Выход отзывает push-подписку устройства. Составной внешний ключ с `tenant_id` в `staff_notification_deliveries` | — |
## 5. Оповещения процесса подтверждения (после этапа 4 у Codex)
Решение владельца: бухгалтер отправляет пакет расчёта и выплат на подтверждение, руководитель получает оповещение, проверяет и подписывает, после чего всё регистрируется. Сам процесс и события делает Codex, от тебя — доставка.
| Событие | Кому | Содержание |
| --------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------ |
| `staff.payroll.package_submitted` | Всем с ролью «Руководитель» в арендаторе | Период, число сотрудников, итог, число предупреждений, ссылка на экран подписи |
| `staff.payroll.package_returned` | Бухгалтеру, который отправил пакет | Комментарий руководителя |
| `staff.payroll.package_signed` | Бухгалтеру и сотрудникам из пакета | Сотрудникам — только «начисление за период доступно», без сумм |
Основной канал — push. Запасной — Telegram, без персональных данных и сумм. Если пакет не подписан за 24 ч (значение настраивается), отправить повторное напоминание. Адресата определять по роли, а не по фиксированному списку.
Сценарий Grok OWN-03 («каждый руководитель получает ровно одно оповещение») должен стать зелёным.
## 6. Публикатор outbox
Вместо `setImmediate` нужен фоновый публикатор:
- повторяет строки в статусах `pending` и `failed`;
- ставит `published_at`;
- на стороне получателя — идемпотентность через inbox;
- соблюдает политику хранения.
Готово, когда после перезапуска сервера неотправленные события уходят, а `staff_outbox` не растёт бесконечно.
## Порядок
1. Пункт 1, затем пункт 2 — сегодня.
2. Пункты 3 и 4 — параллельно, по одной ветке на пункт.
3. Пункт 5 — когда Codex выпустит события пакета.
4. Пункт 6 — после влития общего хелпера outbox от Codex.
## Отчёт после каждой ветки
Ветка, коммит и ID сценариев Grok, которые стали зелёными, — с фактическим выводом `run-e2e`.

View file

@ -1,105 +0,0 @@
# Задание для Antigravity: синхронизация, уведомления, outbox
- Репозиторий: https://git.ochenstarik.ru/ochenstarik/krona-staff
- Основа: ветка `codex/bootstrap-platform-foundation`, коммит `778ba2d`. Твоя офлайн-синхронизация в неё уже влита (`3595792`); код такой же, как в проверенном коммите `5ee7517`.
- Материалы в репозитории: `docs/audit/2026-09-26/` — `AUDIT.md` и `evidence/`. Для синхронизации есть живые сценарии: `evidence/live-sync.mjs.txt`, вывод — `evidence/live-sync.txt`.
## Контекст
На живой PostgreSQL 17 подтвердилось:
- **Устройство синхронизации создаёт подтверждённые смены.** Оно отправило смену с `status: confirmed` и `worked_minutes: 2880`. Смена сохранилась подтверждённой без участия управляющего и без записи в журнале аудита. Расчёт начислил по ней 14 400 ₽. Это дефект основной ветки.
- **Отметки задним числом проходят.** Устройство сохранило отметку с датой 2020 года.
- **Точку с устройством нельзя удалить.** Удаление падает с `23502`.
- **Push-подписка даёт доступ во внутреннюю сеть.** Сотрудник подписал push на `https://127.0.0.1:…`, после чего сервер сам открыл туда соединение.
## Зона ответственности
**Твоя зона:**
- офлайн-синхронизация: `src/sync.ts`, `src/domain/sync/**`, миграция `0011`, `docs/OFFLINE-SYNC-PROTOCOL.md`;
- уведомления: `src/domain/notification/**`, маршруты `/push/*` в `src/portal.ts`, миграция `0010`, service worker и подписка в `src/portal-ui.ts`;
- диспетчер и публикатор outbox — всё, что читает `staff_outbox` и доставляет события.
**Не трогай:**
- авторизацию, сотрудников, смены, расчёт, импорт, процесс подтверждения, терминал и развёртывание — это Codex;
- `tests/e2e/**`, `tests/integration/tenant-isolation.test.ts`, CI — это Grok.
**Записывать в outbox** только через общий хелпер, который Codex делает в задаче K3. Свою вставку не пиши: сейчас именно из-за разрозненных вставок без `occurred_at` падают подтверждение и расчёт.
## Правила
- Ветки `antigravity/fix-<тема>` от основной, отдельный PR на каждую часть.
- Маленькие коммиты. **В теле каждого коммита объясни причину** (AGENTS.md).
- Перед пушем: `npm run check` и `npm run format:check` зелёные. Миграции проверены вверх и вниз на чистой PostgreSQL 17 мигратором без SUPERUSER.
- Каждое исправление — с тестом на настоящей PostgreSQL, а не только на поддельной базе.
- Пункт считается закрытым, только если соответствующий сценарий из `evidence/live-sync.mjs.txt` или `evidence/live-audit.mjs.txt` больше не воспроизводит дефект. Grok проверяет каждый пункт независимо.
## Часть 0 — немедленная мера (первым PR, сегодня)
- Сервер отклоняет от устройств команды `upsert_work_session` и `upsert_timesheet_entry`: ответ «команда не поддерживается», в базу ничего не пишется. Файл: `src/domain/sync/service.ts:784-990`.
- Отдельный маленький PR. Grok проверяет его первым.
- До закрытия S1 и S2 устройства синхронизации в пилоте не регистрировать.
**Готово, когда:** сценарий S1 из `evidence/live-sync.mjs.txt` больше не создаёт смену.
## Часть 1 — офлайн-синхронизация
| ID | Что сделать | Где | Готово, когда |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| S1 (P1) | Устройство отправляет только события отметок, смены и табель считает сервер (reconcile). Если правка с устройства действительно нужна: отдельный scope, только черновые статусы, запрет трогать `confirmed` и `approved`, запись в журнал аудита | `src/domain/sync/service.ts:784-990` | Команда с `status: confirmed` отклоняется; поддельная смена не попадает в расчёт |
| S2 | `occurred_at` принимать только в строгом ISO с зоной. Устройство передаёт своё текущее время, сервер считает расхождение часов и ограничивает время отметки относительно времени получения. При большом расхождении — статус `pending_review` | `service.ts:659, 723, 756` | Отметка с датой 2020 года отклоняется или уходит на проверку |
| S3 | Сначала захватить ключ идемпотентности, потом выполнять команду. `SAVEPOINT` на каждую команду. Проверка ревизии в `UPDATE`. `source_event_id = sync:{device}:{key}`. Временные отказы не кэшировать | `service.ts:672, 702, 774, 832, 936` | Две параллельные отправки с одним ключом выполняются один раз; одна плохая команда не откатывает весь пакет |
| S4 | Начальная загрузка: только точка устройства, только активные сотрудники, ограниченное окно дат, пагинация в SQL | `service.ts:~380-590, 448` | Устройство не получает уволенных и чужие точки |
| S5 | Курсор не теряет данные при `has_more`. Порядок — по фиксации транзакций, а не по `BIGSERIAL`. Изменения из портала видны устройству. Повторная начальная загрузка при устаревшем курсоре, как обещает протокол | `service.ts:343, 595-600` | — |
| S6 | Отметки через синхронизацию пишут outbox так же, как онлайн-маршрут. Проверять `status = 'active'` сотрудника. Сохранять `org_unit_id` | `service.ts:720-780` | — |
| S9 | Внешний ключ `(tenant_id, org_unit_id) ON DELETE SET NULL` обнуляет и `tenant_id`, поэтому удаление точки падает. Заменить на `SET NULL (org_unit_id)` или `RESTRICT` новой миграцией | `migrations/0011_offline_sync_backend.up.sql:21` | Точку с устройством можно удалить или получить понятный отказ |
| S7 | Очистка входящих должна получать `tenant_id`, а не идентификатор системного актора. Запускать её по расписанию | `service.ts:1056` | — |
| S8 | Проверка Origin на маршрутах управления устройствами. Белый список scope. `no-store` на ответе с токеном устройства | `src/sync.ts:74`, `service.ts:190` | — |
## Часть 2 — уведомления
| ID | Что сделать | Где | Готово, когда |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| K12 (N3, P1) | Разрешать только известные push-сервисы: FCM, Mozilla, Apple, WNS. После разрешения DNS запрещать приватные, loopback и link-local адреса. `redirect: 'manual'`, таймаут 5–10 с, тело ответа не сохранять | `src/domain/notification/push-dispatcher.ts:80`, `web-push.ts:226-258` | Подписка на `https://127.0.0.1:…` отклоняется; сценарий N3 не даёт входящего соединения |
| N9 | Конфликт endpoint с другим сотрудником → 409. Перепривязка — только тем же браузером | `push-dispatcher.ts:100-111` | Сценарий N9 отвечает 409 |
| N8 | В production без `VAPID_*` сервер не стартует. Публичный ключ отдавать с `no-cache` | `web-push.ts:80-87`, `src/portal.ts:121-123` | — |
| U1 | Проверять ключи подписки при регистрации. Ошибки отправки обрабатывать отдельно для каждой подписки | `web-push.ts:230`, `push-dispatcher.ts:283` | Неверная подписка не мешает остальным устройствам сотрудника |
| U2 | Не больше 5–10 подписок на сотрудника, таймаут, чтение тела ответа не больше 1 КБ, ограничение параллельности | `web-push.ts:235-258` | — |
| U3, U4 | Атомарный захват строки перед отправкой: статус `sending` плюс аренда. Повторы с backoff и учётом `Retry-After`. Отдельный статус dead letter. Срок хранения `last_error` | `push-dispatcher.ts:233-367` | При двух экземплярах сервера сообщение уходит один раз |
| U5, U6 | Scope service worker должен покрывать `/staff`. Выход из кабинета отзывает push-подписку устройства | `src/portal-ui.ts` (регистрация service worker и выход) | — |
| U7 | Составной внешний ключ с `tenant_id` в `staff_notification_deliveries` | `migrations/0010…up.sql:44` (новой миграцией) | — |
## Часть 3 — оповещения процесса подтверждения
Решение владельца: бухгалтер отправляет пакет с расчётом и выплатами на подтверждение, руководитель получает оповещение, проверяет и подписывает, после чего всё регистрируется. Процесс, подпись и события в outbox делает Codex (его этап 4). От тебя — доставка.
| Событие | Кому | Что в оповещении |
| --------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `staff.payroll.package_submitted` | Всем с ролью «Руководитель» в арендаторе | Период, число сотрудников, итог, число предупреждений; ссылка сразу на экран подписи |
| `staff.payroll.package_returned` | Бухгалтеру, отправившему пакет | Комментарий руководителя |
| `staff.payroll.package_signed` | Бухгалтеру; сотрудникам из пакета | Сотрудникам — только «начисление за период доступно», без сумм в тексте; суммы видны лишь в приложении |
- Основной канал — push в приложении. Если push не доставлен (нет подписки или ошибка), руководителю уходит сообщение в Telegram — без персональных данных и сумм.
- Если пакет не подписан за настраиваемое время (по умолчанию 24 ч), руководителю приходит повторное напоминание.
- Адресат определяется по роли и арендатору, а не по фиксированному списку: при смене руководителя оповещения получает новый.
**Готово, когда** на живом стенде отправка пакета даёт ровно одно оповещение каждому руководителю, а перезапуск сервера его не дублирует. Сотрудник получает уведомление без сумм и только после подписи.
## Часть 4 — публикатор outbox
| ID | Что сделать | Где | Готово, когда |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| F6, D7 | Заменить `setImmediate` фоновым публикатором. Он повторяет строки в `pending` и `failed`, ставит `published_at`, обеспечивает идемпотентность у получателя через inbox и соблюдает политику хранения. Альтернатива — убрать из `module.json` события, которые никто не публикует | `src/portal.ts:830-842`, `push-dispatcher.ts:333-367`, `module.json` | После перезапуска сервера неотправленные события уходят; `staff_outbox` не растёт бесконечно |
## Порядок работы с остальными
1. **Сразу:** часть 0.
2. **Параллельно с этапами 1–3 у Codex:** части 1 и 2. Часть S6 делай после того, как Codex сообщит, что влит общий хелпер outbox (K3).
3. **После этапа 4 у Codex** (события пакета): часть 3.
4. **Часть 4** — в любой момент после K3.
## Отчёт после каждой части
Таблица «ID — что сделано — коммит — тест» и список того, что не удалось, с причиной.

View file

@ -1,219 +0,0 @@
# Задание для Codex: исправления по аудиту и решения владельца
- Репозиторий: https://git.ochenstarik.ru/ochenstarik/krona-staff
- Основа: ветка `codex/bootstrap-platform-foundation`, коммит `778ba2d`
- Материалы в репозитории: `docs/audit/2026-09-26/` — `AUDIT.md` (полный аудит) и `evidence/` (сценарии живой проверки и их вывод). Идентификаторы K, N, D, T, A, F ниже — из аудита.
## Контекст
Аудит на живой PostgreSQL 17 показал:
- на реальной базе не работают создание сотрудника, подтверждение смены, расчёт и утверждение зарплаты — везде 500;
- без токенов сервер открыт всем;
- одна смена может быть оплачена трижды;
- утверждённую смену можно отклонить задним числом без сторно;
- импорт из Excel теряет суммы;
- отметки терминала не доходят до сервера.
Юнит-тесты при этом зелёные, потому что работают на поддельной базе.
## Зона ответственности
**Твоя зона:**
- сервер: авторизация, сотрудники, смены, расчёт, импорт, выплаты, процесс подтверждения;
- база и миграции;
- развёртывание пилота;
- портал;
- Windows-терминал, служба и установщик;
- мобильное приложение в части экранов согласия и подписи.
**Не трогай:**
- `src/domain/notification/**`, маршруты `/push/*`, диспетчер и публикатор outbox — это Antigravity;
- `src/sync.ts`, `src/domain/sync/**`, миграцию `0011` — это тоже Antigravity;
- `tests/e2e/**`, `tests/integration/tenant-isolation.test.ts`, `.forgejo/workflows/ci.yml` — это Grok.
Если нужна правка в чужой зоне, попроси исполнителя.
**Общий хелпер вставки в outbox** (задача K3) делаешь ты. Antigravity будет пользоваться им для своих событий, поэтому сделай его первым и сообщи, когда он влит.
## Правила
- Ветки `codex/fix-<тема>` от основной, отдельный PR на каждый этап.
- Маленькие коммиты. **В теле каждого коммита объясни причину** (AGENTS.md). Сейчас у 40 последних коммитов тела нет.
- Перед пушем должны быть зелёными `npm run check` и `npm run format:check`.
- Каждое исправление SQL или маршрута сопровождай интеграционным тестом **на настоящей PostgreSQL** (переменная `DATABASE_TEST_URL`, роль приложения `krona_staff_app`). Тесты на `fakeDatabase` подтверждением не считаются.
- Пункт считается закрытым, только когда соответствующий сценарий из `evidence/live-audit.mjs.txt` перестаёт воспроизводить дефект. Каждый пункт независимо перепроверит Grok.
- Реальные ФИО и суммы из книги владельца в тесты и фикстуры не копировать.
- Миграции проверяй вверх и вниз на чистой PostgreSQL 17 мигратором без SUPERUSER.
## Решения владельца
**Роли.**
| Роль | Может | Не может |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Руководитель | Всё по всем точкам. Просматривает пакет на подтверждение, подписывает или возвращает его. **Проводит оплаты:** только его подпись регистрирует начисления и выплаты | — |
| Бухгалтер | Просмотр по всем точкам, расчёт, ведомость выплат, **отправка пакета на подтверждение**, выгрузки | Подписывать; регистрировать начисления и выплаты; менять правила оплаты и смены |
| Управляющий | Сотрудники, смены, выручка и черновик расчёта **по своим точкам** | Отправлять на подтверждение, подписывать, выплачивать; видеть данные чужих точек |
| Сотрудник | Только свои смены, начисления, выплаты и остаток | Всё остальное |
**Точки.**
- У каждого сотрудника и управляющего есть основная точка и дополнительные, в том числе временные (подмена), с датами действия.
- Работать на другой точке можно. Смена относится к точке, где она отработана, и считается по правилам и фонду этой точки.
**Процесс оплаты.** Бухгалтер отправляет пакет на подтверждение, руководитель получает оповещение, проверяет, подписывает — и всё регистрируется.
**Согласие.** Согласие на обработку персональных данных и биометрии обязательно. Сотрудник подтверждает его в мобильном приложении при авторизации.
## Этап 0 — форматирование (первым коммитом, до всех остальных)
Одним коммитом выполни `npm run format` по всему репозиторию (сейчас 16 файлов не проходят проверку). Коммит сделай до того, как остальные исполнители начнут работу, чтобы не было конфликтов.
## Этап 1 — разблокировать работу на реальной базе (сегодня)
| ID | Что сделать | Где | Готово, когда |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| K3 (N2) | Во вставках в `staff_outbox` нет `occurred_at`, а столбец `NOT NULL` без значения по умолчанию. Вынеси вставку в один общий хелпер outbox, который всегда заполняет время, и замени им все вставки | `src/portal.ts:1145-1163`, `src/domain/payroll/service.ts:770-784`, `917-935`; эталон — `src/portal.ts:810-823` | Подтверждение смены, расчёт и утверждение отвечают 200 на живой базе; тест на PostgreSQL |
| K4 (N1) | Параметр `$2` выводится PostgreSQL как `text` и как `varchar` (ошибка `42P08`). Добавь явные приведения или вынеси поиск профессии в отдельный запрос | `src/portal.ts:465-483` | `POST /employees` → 201 на живой базе; тест на PostgreSQL |
| — | Проверь остальные запросы на тот же дефект: один `$N` в разных типах | весь `src/` | — |
## Этап 2 — закрыть открытый доступ и привести пилот в порядок
| ID | Что сделать | Где | Готово, когда |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| K1 (F2, P0) | Без токенов сейчас любой анонимный запрос получает права `STANDALONE_ACCESS`. Сделай fail-closed: сервер не стартует без токенов, если `HOST` не loopback. Во всех compose токены и пароли — через `${VAR:?}` | `src/adapters/identity.ts:32-49`, `src/config.ts:45-47`, `compose.yaml`, `deploy/pilot/compose.yaml:14-15` | Запуск без токенов на `0.0.0.0` падает с понятной ошибкой; анонимный `GET /portal` → 401 |
| K2 (F1, P0) | Пилот работает с `NODE_ENV=development`, чтобы обойти запрет standalone в production. Сделай явный профиль `pilot`: обязательные токены и HTTPS, никакого development-поведения. Платформенный JWT — отдельной задачей, когда будет контракт Core | `deploy/pilot/compose.yaml:8`, `compose.yaml:5`, `src/config.ts:51-66` | В пилотном compose нет `NODE_ENV=development`; проверки `loadConfig` действуют |
| K10 (F3) | Серверные сессии: в cookie — случайный идентификатор, в базе — хеш, срок жизни, отзыв при выходе и при смене ключа. Токену сотрудника — срок жизни | `src/portal.ts:262-276` | После `DELETE /session` старая cookie → 401 |
| K11 (F4, A2) | Ограничение частоты по IP на `/session` и на неуспешную аутентификацию. Для заведомо неверного токена не открывать транзакцию в БД: пул всего на 10 соединений | `src/portal.ts:1276-1296`, `src/infrastructure/database.ts:9` | 60 неверных входов подряд дают 429 |
| A4 | Глобальный обработчик ошибок: при 5xx — общий текст и correlation id, детали только в лог | `src/app.ts` | В ответе 500 нет кода и текста ошибки PostgreSQL |
| F10, A6 | Проверку Origin для мутаций по cookie сделать fail-closed. Пропускать её только при `Authorization: Bearer` | `src/portal.ts:1359-1374` | Мутация по cookie без Origin → 403 |
| A5, A7, A9 | Аутентификацию делать до валидации тела; `/openapi.json` — только менеджеру или в dev. `no-store` на выдаче токена сотрудника. Correlation id от клиента хранить отдельно от серверного | `src/portal.ts:734`, `src/app.ts` | — |
| D13 | Лишние поля в теле запроса отклонять ответом 400 (`removeAdditional: false`), а не удалять молча, как сейчас | `src/app.ts` | Поведение совпадает с `additionalProperties: false` в OpenAPI |
| K18 (P1) | Резервное копирование пилота: `pg_dump -Fc` по расписанию, шифрование, копия вне хоста, срок хранения. Бэкап перед каждой миграцией в `setup.sh`. Провести restore drill и записать результат | `deploy/pilot/`, `docs/BACKUP-RESTORE.md` | Есть скрипт, расписание и протокол успешного восстановления |
| N6 | Задавать атрибуты роли только в `CREATE ROLE`, затем `ALTER ROLE … PASSWORD`, затем проверять `rolsuper` и `rolbypassrls` и при нарушении отказывать | `scripts/create-app-role.mjs:19`, `docker/postgres/init-app-role.sh:17` | Скрипт работает мигратором без SUPERUSER |
| N7 | Пиннинг сертификата вместо отключения проверки TLS; токен только из переменной окружения; убрать поле `code` из тела `/professions` | `scripts/import-owner-workbook.py:241, 255, 278` | — |
| F9 | Healthcheck образа по HTTPS | `Dockerfile:21` | — |
| D3 | TLS пилота: локальный CA, установленный на устройства, или домен с ACME; пиннинг SPKI или CA вместо листового сертификата; ключ не хранить незашифрованным рядом с pfx; runbook продления | `deploy/pilot/setup.sh:37-47` | На телефоне сотрудника регистрируется service worker (иначе PWA и push не работают) |
| D4, D11, D12 | Образы с тегами и возможность отката; `lock_timeout` в миграциях; миграции не от root и без dev-зависимостей; smoke-тест проверяет коды ответов и не пишет в боевую базу | `deploy/pilot/setup.sh`, `scripts/migrate.mjs`, `deploy/pilot/smoke-test.sh` | — |
| D9, D10, D14, D15 | Лимиты памяти, CPU и числа процессов, `cap_drop`, ротация логов; `.dockerignore` для `**/.env` и `deploy/pilot/secrets`; `redact` в логгере, ошибки пула — через pino; безопасные значения по умолчанию в корневом compose | compose-файлы, `.dockerignore`, `src/app.ts:42`, `src/infrastructure/database.ts` | — |
## Этап 3 — денежная логика (до первого боевого расчёта)
| ID | Что сделать | Где | Готово, когда |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| K5 (N4) | Каждая смена начисляется ровно один раз: `session_id` в строке ведомости и уникальность среди неаннулированных ведомостей (или exclusion constraint на пересечение периодов, включая сочетание «одна точка» и «все точки»). При пересчёте обновлять `period_end` | `src/domain/payroll/service.ts:425-454, 759-768, 860-903`; индексы `migrations/0006:196-199` | Три пересекающихся расчёта дают одно начисление 2 400 ₽ или 409 (сейчас 7 200 ₽) |
| K6 (D5) | Смены и строки ведомости после подписи неизменяемы на уровне БД: триггер или политика, у роли приложения нет DELETE и UPDATE. Исправление — только сторнирующей записью | `src/portal.ts:1024-1106`, `migrations/0006:296-300` | Отклонение оплаченной смены → 409 или создаётся сторно |
| K7 (D2) | Импорт считает предыдущую сумму по всем записям дня, а пишет по точному ключу — суммы теряются. Считать по точному `external_key`, корректировку писать с отдельным ключом ревизии | `src/operations.ts:1017-1052`, `scripts/import-owner-workbook.py:147, 168, 176` | Две точки в один день и повторный импорт с изменённой суммой дают верный итог; тест |
| K8 (D1) | Сделать версии правил настоящими: v1 неизменяема, любое изменение создаёт новую версию, учитываются даты действия правил и условий точки. В строке ведомости хранить JSON дерева правила, версию, id назначения, id и ревизию смены | `service.ts:152-180, 517-529, 686-695` | Подписанную ведомость можно пересчитать и получить то же число; тест |
| K9 (D3) | Сохранять произвольные параметры из `param_declarations` со значениями по умолчанию. Загружать все метрики и позиции, которые требует дерево правила | `service.ts:295-299, 488-500`, `src/portal-ui.ts` | Пресеты «официант» и «премия за порог выручки» дают ожидаемые суммы (сейчас 0 ₽); тест |
| N12, D9 | Ограничить ставки сверху (не больше 10¹² коп.), проверять `Number.isSafeInteger` и реальность даты и месяца | `src/operations.ts:560-585, 665-671` | `rate_minor = 1e20` → 400; месяц `2026-13` → 400 (сейчас 200 и 500) |
| N11 | Строгая схема импорта: `kind` из списка, знак выплаты, обязательные строки | `src/operations.ts:776-812, 1168-1210` | Некорректный импорт → 400, а не 500 |
| N13, N14 | Первый расчёт периода без гонки (`ON CONFLICT … RETURNING` или advisory lock). GET-запросы не пишут в базу; начальные правила создаются один раз | `service.ts:152-180, 446-454` | — |
| F7 | `Idempotency-Key` для расчёта, отправки, подписи, импорта и выплат | — | Повтор с тем же ключом не создаёт дублей |
| D7, F12 | Остаток округления фонда не выплачивается сверх фонда. Деньги в расчётах — `bigint` или проверенные безопасные целые | `src/domain/payroll/calculator.ts` | — |
## Этап 4 — роли, точки, подтверждение и согласие (решения владельца)
### 4.1 Роли и точки
- Роли — по таблице в разделе «Решения владельца». Права проверяются на сервере в каждом запросе, включая расчёт и выгрузки. Интерфейс только прячет недоступное.
- Привязки «человек — точка» хранить в отдельной таблице с датами действия: одна основная точка и сколько угодно дополнительных, в том числе временных.
- Управляющий видит и подтверждает смены всех, кто работал на его точке, включая приходящих. Их начисления на других точках он не видит.
- В режиме `standalone` роль и список точек задаются при выдаче доступа (через серверные сессии из K10). В режиме `platform` они берутся из прав Core.
- Каждое действие пишется в журнал аудита с конкретным человеком. Сейчас все менеджеры записываются одним `STANDALONE_ACTOR_ID` (A8).
### 4.2 Подтверждение и оплата
```
Бухгалтер: расчёт → ведомость выплат → «Отправить на подтверждение»
↓ оповещение руководителю (делает Antigravity)
Руководитель: просмотр пакета → «Подписать» или «Вернуть с комментарием»
↓ подпись
Система: начисления и выплаты регистрируются в реестре, пакет и его смены
становятся неизменяемыми; бухгалтеру и сотрудникам уходят оповещения
```
- **Пакет** — расчётная ведомость за период и ведомость выплат (выплат может не быть). Руководитель подписывает весь пакет одной подписью.
- **Статусы пакета:** `draft → calculated → submitted → signed`; возврат: `submitted → returned → calculated`.
- **Отправка** фиксирует снимок пакета: строки, итоги, предупреждения расчёта и хеш содержимого.
- Если после отправки изменились данные пакета (смена, выручка, ставка, правило), отправка отменяется. Пакет возвращается бухгалтеру с пометкой «данные изменились».
- Подписать устаревший пакет нельзя (закрывает D4).
- **Экран руководителя** в портале, позже и в приложении. На нём:
- итоги по точкам и сотрудникам и сравнение с прошлым периодом;
- все предупреждения: нет выручки, нет профиля оплаты, аномальные смены, выплата больше остатка;
- расшифровка любой строки.
Сотрудник без профиля оплаты блокирует подпись, а не выпадает из фонда молча. Руководитель пакет не редактирует — только подписывает или возвращает.
- **Подпись** — простая электронная. В момент подписи руководитель повторно подтверждает личность: в приложении PIN или биометрией телефона, в портале паролем.
- Сохраняется: кто, когда, устройство, IP, хеш подписанного снимка и версия соглашения об электронной подписи.
- Подписывает только роль «Руководитель». Бухгалтер не может подписать свой пакет, даже если у него есть обе роли.
- **Регистрация при подписи** идёт одной транзакцией:
- начисления и выплаты записываются в реестр идемпотентно по пакету;
- пакет и его смены становятся неизменяемыми (K6);
- в outbox через общий хелпер записываются события `staff.payroll.package_submitted`, `staff.payroll.package_returned`, `staff.payroll.package_signed`. Оповещения по ним делает Antigravity.
- **Возврат** — только с обязательным комментарием. Бухгалтер правит данные и отправляет новую версию пакета. История версий и комментариев сохраняется.
- **Выплаты только через подпись.** Закрыть ручные выплаты в обход подписи, включая импорт. Импорт исторических выплат из Excel — отдельная операция, которую тоже подписывает руководитель.
- **API:** отправить, вернуть, подписать, история пакета. Добавь эти маршруты в OpenAPI.
### 4.3 Согласие
**Сервер.**
- Журнал согласий только на вставку: сотрудник, вид согласия, версия документа, хеш текста, время по серверу, устройство, IP, способ подписания, время отзыва.
- Три отдельных вида согласия: обработка персональных данных, **биометрия**, передача оповещений через иностранные мессенджеры (Telegram).
- API: текущие версии документов, принять, отозвать, статус по сотруднику (для терминала).
- Тексты хранятся в базе с версиями, чтобы менять их без релиза. Новая версия текста требует повторного согласия при следующем входе.
**Приложение сотрудника** (дополнение к `docs/APP-CORE.md`).
- После приглашения и установки пароля и PIN — обязательный экран согласий, до входа в кабинет.
- Без согласия на обработку ПДн дальше не пустит. Без согласия на биометрию кабинет работает, но отпечаток зарегистрировать нельзя.
- В профиле — подписанные версии и кнопка отзыва.
**Без смартфона.** Управляющий отмечает бумажное согласие в кабинете и прикладывает скан; отметка идёт в журнал аудита.
**Юридически.** Для биометрии закон требует письменной формы. Электронное согласие равнозначно письменному, если подписано электронной подписью (в том числе простой) и есть соглашение о её использовании. Тексты согласий и соглашения готовит юрист; в коде предусмотри только их подстановку.
Этап 4 готов, когда на живой базе:
- управляющий точки А получает 403 на расчёт точки Б и на отправку пакета;
- бухгалтер отправляет пакет, но при попытке подписать получает 403;
- начисления и выплаты появляются в реестре только после подписи руководителя;
- изменение смены после отправки не даёт подписать пакет;
- возврат с комментарием возвращает пакет бухгалтеру;
- смена сотрудника точки А, отработанная на точке Б, попадает в расчёт точки Б;
- без согласия на биометрию сервер отвечает терминалу «регистрация запрещена».
## Этап 5 — терминал и служба
| ID | Что сделать | Где | Готово, когда |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- |
| K14 (T4, P1) | Терминал создаёт сотрудников со своими ULID, сервер их не знает и отвечает 404, отметки повторяются бесконечно. Нужна синхронизация справочника сотрудников с сервера или передача `personnel_number`. Привести `docs/TERMINAL-API-REQUIREMENTS.md` к фактическому контракту; поля, которых нет в схеме сервера, добавить на сервере или не отправлять | `apps/KronaStaffTerminal/MainPage.xaml.cs:479-492`, `Models/TerminalModels.cs:157` | Отметка с терминала появляется на сервере; бесконечных повторов нет |
| K15 (T1, P1) | Служба создаёт pipe `global\KronaStaffTerminalPipe`, клиент подключается к `KronaStaffTerminalPipe`, поэтому IPC не работает (проверено запуском). Нужно: одно имя; `PipeOptions.FirstPipeInstance`; проверка клиентом, что сервер — процесс службы или SYSTEM; `TokenImpersonationLevel.Identification`; интеграционный тест на реальном pipe | `apps/KronaStaffTerminal/Services/TerminalIpc.cs:84, 236` | Клиент подключается к службе; посторонний процесс не может занять имя |
| K16 (T2, P1) | Служба от LocalSystem выдаёт операторам полный доступ к каталогу данных и сама меняет в нём ACL и ротирует логи — путь к SYSTEM через junction. Данные службы и логи — только для SYSTEM и Администраторов, с проверкой reparse-точек. Интерфейс работает через IPC. Служба — под виртуальной учётной записью | `Services/TerminalStore.cs:305-360`, `Services/CrashLogService.cs:331-371`, `installer/KronaStaffTerminal.nsi:119` | — |
| K17 (T5) | Регистрация отпечатка разрешена только при действующем согласии на биометрию (статус с сервера, кэшируется для офлайна). При отзыве согласия, блокировке и увольнении шаблоны удаляются на следующей синхронизации, включая `.bak1-3` и `*.corrupt-*` | `MainPage.xaml.cs:685-776`, `TerminalStore.cs:96-100, 376-384` | Без согласия регистрация недоступна; после отзыва шаблонов нет ни в одном файле |
| T3, T6 | Единственный писатель файла состояния — служба (или межпроцессная блокировка с перечитыванием). Секреты недоступны группе операторов | `KronaStaffWorker.cs:375-393`, `TerminalStore.cs:164, 263, 325-351` | — |
| T7, T8 | Установщик: ACL на каталог установки; владелец каталога данных — Администраторы; терминал не запускается с повышенными правами ни после установки, ни после обновления | `installer/KronaStaffTerminal.nsi:49, 56, 110-111`; `MainPage.xaml.cs:1529-1530` | — |
| T9, T10 | Проверенный файл обновления держать открытым с запретом записи или копировать в каталог только для администраторов. Токен обновлений с узкими правами. `libzkfp.dll` загружать по абсолютному пути | `Services/UpdateService.cs:118-127, 200-212`; `FingerprintScanner.cs:605-617` | — |
| D5 | Скрипт настройки терминала пишет в `%ProgramData%` с DPAPI LocalMachine | `deploy/pilot/configure-terminal-pilot.ps1:11, 24-27, 43` | — |
| T11–T13 | Ограничить IPC до проверки HMAC; добавить backoff в синхронизацию; уведомлять об откате к резервной копии; ввести порог совпадения отпечатка | — | — |
## Этап 6 — портал и документация
- W1: маршрут `/staff/*` отвечает 200 и HTML на любой путь (`src/app.ts:146`). Оставить явный список разделов, остальное — 404.
- D8: привести к коду `ARCHITECTURE.md`, `ROADMAP.md`, `PLATFORM-INTEGRATION.md`, `README.md`, `.env.example` и `SECURITY.md`. `AUDIT-REMEDIATION-2026-09-18.md` пометить устаревшим.
## Порядок работы с остальными
1. **Сразу:** этап 0 и этап 1. Как только общий хелпер outbox из K3 влит, сообщи Antigravity.
2. **Параллельно:** этапы 2 и 3. Antigravity в это время исправляет синхронизацию и push, Grok строит тестовый контур.
3. **Этап 4.** События пакета нужны Antigravity для оповещений. Согласие нужно этапу 5.
4. **Этап 5:** K14 и K15 можно начинать сразу после этапа 1; K17 — после серверной части согласия.
## Отчёт после каждого этапа
Таблица «ID — что сделано — коммит — тест» и список того, что не удалось, с причиной.

View file

@ -1,93 +0,0 @@
# Задание для Grok, круг 2: Windows, сопоставление ID, недостающие сценарии, приёмка
- Репозиторий: https://git.ochenstarik.ru/ochenstarik/krona-staff
- Основа: текущая основная ветка `codex/bootstrap-platform-foundation` (`331e490`) и твоя ветка `grok/e2e-harness` (`421da72`)
- Полный аудит владельца теперь в репозитории: `docs/audit/2026-09-26/AUDIT.md`; таблица соответствия ID ниже дублирует главное.
## Итог приёмки прошлого круга
Ветку `grok/e2e-harness` проверили на живой PostgreSQL 17.10. Вердикт: **принять после правок из пункта 1**.
**Что сделано хорошо:**
- Зона соблюдена: код продукта не тронут.
- Все коммиты с объяснением причины.
- Прогон дал ровно те же 38 красных и 9 зелёных сценариев, что в твоём отчёте.
- Логика `known-defects.json` верная.
- SYNC-C0 — настоящая находка, которой не было в аудите владельца: начальная загрузка синхронизации на реальной базе отвечает 500 (`column "status" does not exist`).
- Перекрёстная проверка: исправление Antigravity (`antigravity/fix-reject-device-shifts`) на твоих сценариях переводит SYNC-A и SYNC-B в зелёные.
**Что не так:**
1. **Под Windows стенд не запускается** (проект разрабатывается под Windows). Все три места падают с `ENOENT`, потому что в Windows это `.cmd`:
- `scripts/test/run-e2e.mjs:35` — `spawn('npx', …)`;
- `tests/e2e/harness/global-setup.ts:67` — `spawn(node_modules/.bin/tsx, …)`;
- `scripts/test/n13-race.mjs:102` — то же, что в предыдущем пункте.
2. **ID аудита владельца не сопоставлены** — таблица ниже.
3. **`tests/e2e/evidence/` коммитится в репозиторий** и будет меняться при каждом прогоне.
## Правила — как раньше
- Ветка `grok/e2e-harness` (дописывай в неё), маленькие коммиты с причиной в теле.
- Твоя зона: `tests/e2e/**`, `tests/integration/**` (только очистка и стенд), `.forgejo/workflows/ci.yml`, `scripts/test/**`.
- `src/`, `apps/`, `migrations/`, `deploy/` не трогать. Нужна правка продукта — пиши в `tests/e2e/NOTES-FOR-EXECUTORS.md`.
## 1. Правки, без которых ветку не влить (сегодня)
| Что сделать | Готово, когда |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Запуск без `.cmd`-обёрток: `spawn(process.execPath, [<путь к tsx/dist/cli.mjs>, 'src/server.ts'])`, vitest — через `process.execPath` и его `vitest.mjs`, либо `shell: true` на `win32`. Добавить в CI проверку запуска на Windows, если есть раннер; если нет — записать это в REPORT | `node scripts/test/run-e2e.mjs` работает на Windows 11 с Node 22+ без правок |
| `tests/e2e/evidence/` убрать из git и добавить в `.gitignore`. Результаты прогона — артефакт CI. В репозитории оставить `REPORT.md` и таблицу | Повторный прогон не меняет отслеживаемые файлы |
| Перебазировать ветку на `331e490` | Вливается без конфликтов |
## 2. Сопоставление с ID аудита владельца
Переименуй теги в названиях сценариев в формат `[K3/N2]`, а ключи в `known-defects.json` — в двойные.
| ID владельца | Твой сценарий | Суть |
| -------------------------- | -------------- | ----------------------------------------------------------------------------------- |
| K1 | F2 | Без токенов анонимный запрос получает права |
| K3 | N2 | Вставка в outbox без `occurred_at`: подтверждение, расчёт, утверждение падают с 500 |
| K4 | N1 | `POST /employees` падает с 500 (`42P08`) |
| K5 | N4 | Пересекающиеся расчёты начисляют смену повторно |
| K10 | F3 | Сырой токен в cookie, выход не отзывает сессию |
| K11 | F4 | Нет ограничения частоты |
| K12 | N3 | SSRF через push-подписку |
| K13 (S1) | SYNC-A, SYNC-B | Устройство создаёт подтверждённые смены и табель |
| S2 | SYNC-J | Отметка задним числом через синхронизацию |
| S3 | SYNC-G | Одна битая команда откатывает пакет |
| S4 | SYNC-E, SYNC-F | Лишние данные на устройство, отметки уволенных, чужая точка |
| S5 | SYNC-C, SYNC-D | Курсор теряет изменения |
| S8 | SYNC-H | CSRF на управлении устройствами |
| K19 (D4) | OWN-07 | Подпись устаревшего пакета |
| D6 | OWN-01, OWN-02 | Управляющий вне своих точек |
| K17 | OWN-10, OWN-11 | Согласие на биометрию |
| N9, N10, N11, N12, F7, F10 | те же | — |
## 3. Недостающие сценарии
Все проверяют правильное поведение. Сейчас они красные — внеси их в `known-defects.json`.
| ID владельца | Сценарий | Ожидаемое поведение |
| ------------ | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| K6 (D5) | Подтверждённую смену включают в расчёт, руководитель подписывает, затем смену отклоняют | 409 или создаётся сторнирующая запись. Сейчас: 200, сторно нет, начисление остаётся |
| K7 (D2) | Импорт книги: начисления за один день на двух точках, затем повторный импорт с изменённой суммой | Итог в реестре равен сумме по книге. Сейчас теряется: вторая точка пишется как отрицательная корректировка, изменение суммы пропадает |
| K8 (D1) | Расчёт подписан, затем меняется правило оплаты или ставка, затем подписанную ведомость пересчитывают для проверки | Сумма та же, что в подписанной ведомости |
| K9 (D3) | Сотрудник с пресетом «официант» (оклад смены, процент от личных продаж, допродажи, премия за средний чек) | Начисление по параметрам пресета. Сейчас 0 ₽: сохраняются только ставка, процент и гарантия |
| S9 | Удаление точки, к которой привязано устройство синхронизации | Точка удалена или получен понятный отказ. Сейчас 500, `23502 null value in column "tenant_id"` |
| A4 | Любой ответ 500 | Без кода и текста ошибки PostgreSQL в теле. Сейчас наружу уходят, например, `42P08` и `23502` с текстом |
| N12-дата | Расчёт с `month = 2026-13` | 400. Сейчас 500 |
## 4. Приёмка
1. **Ветка Antigravity `antigravity/fix-reject-device-shifts`.** После того как Antigravity исправит очистку в `sync-rejection.test.ts` и ветку вольют, убери SYNC-A и SYNC-B из `known-defects.json` отдельным коммитом.
2. **Ветки Codex `codex/fix-format-baseline` и `codex/fix-live-database`** (этапы 0 и 1: форматирование, K3, K4). Прогони стенд на каждой и дай таблицу «ID — было — стало — доказательство». Если K3 и K4 зелёные, убери их из списка известных дефектов после влития.
3. **Дальше** — каждая новая ветка Codex и Antigravity, по той же схеме. На слово ничего не принимать.
## Порядок
Пункт 1 → пункт 2 → пункт 3. Приёмку из пункта 4 веди параллельно, по мере появления веток.
## Отчёт
Обновлённый `tests/e2e/REPORT.md`: что изменилось, таблица «ID владельца / твой ID — цвет — фактический вывод», приёмочные таблицы по веткам исполнителей.

View file

@ -1,84 +0,0 @@
# Задание для Grok: тестовый контур на живой базе и независимая приёмка
- Репозиторий: https://git.ochenstarik.ru/ochenstarik/krona-staff
- Основа: ветка `codex/bootstrap-platform-foundation`, коммит `778ba2d`
- Материалы в репозитории: `docs/audit/2026-09-26/` — `AUDIT.md` и `evidence/` со сценариями живой проверки и их выводом.
## Контекст
`AUDIT.md` сверен с твоим аудитом `2026-09-26_full-project-audit_grok_3e20544.md`. Итог сверки:
- 22 находки подтверждены;
- 4 подтверждены частично (F8, F11, N7, N10);
- 1 уже исправлена (F5);
- 1 не воспроизвелась (N13).
После твоего аудита в основную ветку влиты офлайн-синхронизация и новое оформление портала. Находки по синхронизации (S1–S9) в `AUDIT.md` уже учтены.
Главный урок: 156 зелёных тестов на поддельной базе не заметили, что создание сотрудника, подтверждение смены и расчёт зарплаты на реальной PostgreSQL всегда падают.
## Твоя роль
Продукт ты не исправляешь — это делают Codex и Antigravity.
От тебя нужно две вещи:
- построить тестовый контур, который ловит дефекты на настоящей базе;
- независимо принимать каждое исправление.
## Зона ответственности
**Твоя зона:**
- `tests/e2e/**` — новый набор сквозных сценариев: живой сервер на живой PostgreSQL;
- `tests/integration/tenant-isolation.test.ts`;
- `.forgejo/workflows/ci.yml` и вспомогательные скрипты для тестов.
**Не трогай:** `src/`, `apps/`, `migrations/`, `deploy/`. Это зоны Codex и Antigravity. Если тесту нужна правка продукта, оставь замечание исполнителю.
## Правила
- Ветка `grok/e2e-harness`, маленькие коммиты. В теле каждого коммита объясни причину (AGENTS.md).
- Токены и ключи в тестах генерируй случайно. Реальные ФИО и суммы не используй.
- К каждому выводу прикладывай команду и фактический вывод. То, что не удалось проверить, помечай «не проверено» явно, как ты уже делаешь.
## Задачи
| № | Что сделать | Готово, когда |
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 1 | **N5.** В тесте изоляции арендаторов очистка идёт ролью приложения, а у неё нет права DELETE на сотрудников. Перенеси очистку на роль мигратора или оберни в транзакцию с откатом | Тест проходит на живой базе; CI с `DATABASE_TEST_URL` из-за него больше не красный |
| 2 | **Набор `tests/e2e`.** Поднять сервер на реальной PostgreSQL 17 и прогнать сценарии по всем находкам P0 и P1. За основу взять `evidence/live-audit.mjs.txt` и `evidence/live-sync.mjs.txt`. Каждый сценарий проверяет правильное поведение, поэтому сейчас он красный. Список красных сценариев и есть список открытых дефектов | Есть сценарии для K1, K3, K4, K5, K6, K10, K11, K12, S1, S2, S9, N9, N12 и A4; отчёт «зелёный / красный» по каждому ID |
| 3 | **Сценарии по решениям владельца (роли, точки, процесс подтверждения, согласие).** Подробности — в таблице ниже | Сценарии есть и пока красные; это ожидаемо |
| 4 | **CI.** Сервис PostgreSQL; роли как в пилоте, но мигратор **без** SUPERUSER. Миграции вверх, откат всех, снова вверх. Запуск `tests/e2e`. `docker build` перенести туда, где есть docker, либо вынести в отдельную задачу. Закрепить действия по SHA (F13) | CI реально проверяет схему и маршруты на живой базе |
| 5 | **Проверка пилотного compose** тестом, как сейчас проверяется корневой: переменные с `:?`, нет `NODE_ENV=development`, у приложения нет учётных данных мигратора | — |
| 6 | **Приёмка.** Первым проверь немедленную меру Antigravity по S1: устройство больше не создаёт и не меняет смену. Дальше после каждого PR от Codex и Antigravity прогоняй `tests/e2e` и целевые сценарии. На слово ничего не принимай | По каждому закрытому ID есть независимое подтверждение: таблица «ID — было — стало — доказательство» |
| 7 | **Повторить N13** (гонка первого расчёта) под нагрузкой: 10–50 параллельных запросов. У меня на двух запросах не воспроизвелось | Вердикт с числом попыток |
| 8 | **Snyk** — только если владелец выдаст токен. Без токена не запускать | — |
Сценарии для задачи 3:
| Сценарий | Ожидаемый результат |
| --------------------------------------------- | -------------------------------------------------------------------- |
| Управляющий точки А запускает расчёт точки Б | 403 |
| Управляющий отправляет пакет на подтверждение | 403 |
| Бухгалтер отправляет пакет | успешно; оповещение каждому руководителю ровно одно |
| Бухгалтер пытается подписать пакет | 403 |
| Реестр до подписи руководителя | начислений и выплат нет |
| Руководитель подписывает | начисления и выплаты зарегистрированы; пакет и его смены неизменяемы |
| Изменение смены после отправки | подписать пакет нельзя, он возвращается бухгалтеру |
| Возврат с комментарием | пакет у бухгалтера, комментарий сохранён |
| Сотрудник точки А отработал смену на точке Б | смена попадает в расчёт точки Б |
| Сотрудник без согласия на биометрию | сервер отвечает терминалу «регистрация запрещена» |
| Отзыв согласия | статус для терминала меняется |
Проверки, которым нужна Windows (DPAPI, ACL каталога данных, установщик, WinUI, реальный pipe), в твоём окружении недоступны. Отмечай их «не проверено» и ссылайся на тесты Codex.
## Порядок работы с остальными
1. **Сразу:** задачи 1, 2, 4 и 5. Это не зависит от других исполнителей.
2. **Задача 3** — сразу. Сценарии будут красными, пока Codex не сделает этап 4.
3. **Задача 6** — по мере поступления PR. Первым — немедленная мера Antigravity по S1, затем этап 1 Codex (K3, K4).
## Отчёт
Первый PR — после задач 1, 2, 4 и 5. В нём набор сценариев и краткий отчёт: какие сценарии красные. Дальше — приёмочная таблица после каждого PR исполнителей.

View file

@ -1,17 +0,0 @@
# Доказательства аудита 2026-09-26
| Файл | Что это |
| ---------------------- | ---------------------------------------------------------------------------------------------------------- |
| `live-audit.mjs.txt` | Сценарии живой проверки основной ветки `3e20544`: сервер на реальной PostgreSQL 17, настоящие HTTP-запросы |
| `live-audit-final.txt` | Вывод последнего прогона на базе в UTF-8 |
| `live-sync.mjs.txt` | Сценарии для ветки синхронизации `5ee7517` |
| `live-sync.txt` | Вывод прогона |
| `format-check.txt` | Вывод `npm run format:check` |
Сценарии сохранены с расширением `.mjs.txt`, чтобы их не проверял линтер проекта. Для запуска скопируйте файл вне репозитория и уберите `.txt`. Поддерживаемая рабочая версия этих проверок — стенд Grok в `tests/e2e/`.
Как запускались: рабочая копия нужного коммита (`git worktree add --detach … <commit>`), `npm ci`, PostgreSQL 17 на порту 55432 с суперпользователем `postgres`, мигратор `krona_migrator` без SUPERUSER (владелец базы), роль приложения `krona_staff_app`, база в UTF-8, миграции `node scripts/migrate.mjs up`. Пути к рабочим копиям в начале скриптов (`REPO`) — локальные, их нужно поправить под своё окружение.
Токены в сценариях генерируются случайно при каждом запуске и никуда не выводятся. Пароли ролей — одноразовые для локального стенда.
Для сценариев N4, D5 и S1 скрипт временно задаёт значение по умолчанию для `staff_outbox.occurred_at` (иначе мешает дефект N2) и снимает его после сценария. После исправления N2 эти строки нужно удалить.

View file

@ -1,6 +0,0 @@
[S9] ПОДТВЕРЖДЕНО — удаление точки с устройством → 23502 null value in column "tenant_id" of relation "staff_sync_devices" violates not-null constraint
device registration → 201; scopes ["attendance:sync"]
device push → 200 {"results":[{"idempotency_key":"forge-1790409261814","command_type":"upsert_work_session","status":"rejected","error_code":"COMMAND_NOT_SUPPORTED","error_message":"Команда не поддерживается: прямое создание или изменение смен и табелей с устройств запрещено"},…
[S1] не подтверждено — смена от устройства: статус undefined, минут undefined, подтвердил никто, записей в журнале аудита арендатора: 0
[S2] ПОДТВЕРЖДЕНО — отметка с временем 2020-01-01 через синхронизацию сохранена: true
[S1→payroll] расчёт сентября → 200; начислено по поддельной смене: 0 ₽ (48 ч × 300 ₽)

View file

@ -1,40 +0,0 @@
× [N1] менеджер создаёт сотрудника через POST /employees → 201 487ms
× [N2] подтверждение смены, расчёт и утверждение зарплаты проходят (200) и начисляют 8 ч × ставка 1795ms
× [N4] пересекающиеся расчёты не начисляют одну смену дважды 943ms
× [N3] push-подписка на внутренний адрес отклоняется, сервер не подключается к 127.0.0.1 2834ms
× [N9] чужой push-endpoint нельзя перепривязать к другому сотруднику 421ms
× [N12] PUT pay-assignment отвергает лишние поля и нереальные суммы (400) 386ms
× [N10] терминальный токен не читает справочники профессий и точек (403) 31ms
× [F2] standalone без токенов не выдаёт права менеджера анонимному запросу (401) 322ms
× [F3] cookie сессии не содержит сырой токен и отзывается при выходе 50ms
× [F10] мутация по cookie без Origin отклоняется (CSRF, 403) 21ms
× [F7] повтор Idempotency-Key с другим телом не создаёт второе событие 790ms
× [N11] импорт с неверным kind начисления → 400, а не 500 602ms
× [F4] перебор ключей входа ограничивается (429 не позже 30 неверных попыток) 744ms
× [OWN-01] менеджер точки A запускает расчёт для точки B → 403 978ms
× [OWN-02] менеджер точки отправляет пакет на согласование → 403 750ms
× [OWN-03] бухгалтер отправляет пакет → успех, каждый директор получает ровно одно уведомление 10ms
× [OWN-04] бухгалтер пытается подписать пакет → 403 20ms
× [OWN-05] до подписи директора в ledger нет начислений и выплат 5ms
× [OWN-06] подпись директора → начисления и выплаты в ledger, пакет и смены неизменяемы 10ms
× [OWN-07] смена изменена после отправки → подписать нельзя (409), пакет возвращён бухгалтеру 5ms
× [OWN-08] возврат с комментарием → пакет у бухгалтера, комментарий сохранён 10ms
× [OWN-09] сотрудник точки A отработал смену в точке B → смена попадает в зарплату точки B 16ms
× [OWN-10] сотрудник без согласия на биометрию → сервер сообщает терминалу «регистрация запрещена» 250ms
× [OWN-11] согласие отозвано → статус для терминала меняется 297ms
× [SYNC-A] устройство не может само подтвердить смену (status=confirmed отклоняется) 791ms
× [SYNC-B] устройство не может утвердить табель (status=approved отклоняется) 392ms
× [SYNC-C0] начальная загрузка (pull без курсора) работает на реальной БД (200) 427ms
× [SYNC-C] начальная загрузка >100 сущностей отдаёт все сущности постранично 960ms
× [SYNC-D] изменения, сделанные через портал, попадают в инкрементальный pull 518ms
× [SYNC-E] отметка уволенного сотрудника через sync отклоняется 279ms
× [SYNC-F] отметка через sync сохраняет точку устройства; чужая точка в payload отклоняется 664ms
× [SYNC-G] битая команда в пакете отклоняется по отдельности, остальные применяются (не 500) 350ms
× [SYNC-H] регистрация устройства по cookie с чужим Origin отклоняется (CSRF, 403) 180ms
× [SYNC-I] без настроенных токенов анонимный запрос не регистрирует устройство (401) 180ms
× [SYNC-J] отметка через sync вне окна времени (2001 год) отклоняется, как в POST /attendance/events 308ms
× [SYNC-K] ack курсора из будущего (больше выданного сервером) отклоняется (400) 25ms
× [PILOT-1] все подставляемые переменные обязательны: ${VAR:?сообщение} 103ms
× [PILOT-2] ни один сервис не запускается с NODE_ENV=development 4ms
⎯⎯⎯⎯⎯⎯ Failed Tests 38 ⎯⎯⎯⎯⎯⎯⎯
Tests 38 failed | 9 passed (47)

View file

@ -1,12 +0,0 @@
× [SYNC-C0] начальная загрузка (pull без курсора) работает на реальной БД (200) 466ms
× [SYNC-C] начальная загрузка >100 сущностей отдаёт все сущности постранично 624ms
× [SYNC-D] изменения, сделанные через портал, попадают в инкрементальный pull 372ms
× [SYNC-E] отметка уволенного сотрудника через sync отклоняется 223ms
× [SYNC-F] отметка через sync сохраняет точку устройства; чужая точка в payload отклоняется 477ms
× [SYNC-G] битая команда в пакете отклоняется по отдельности, остальные применяются (не 500) 213ms
× [SYNC-H] регистрация устройства по cookie с чужим Origin отклоняется (CSRF, 403) 136ms
× [SYNC-I] без настроенных токенов анонимный запрос не регистрирует устройство (401) 33ms
× [SYNC-J] отметка через sync вне окна времени (2001 год) отклоняется, как в POST /attendance/events 283ms
× [SYNC-K] ack курсора из будущего (больше выданного сервером) отклоняется (400) 27ms
⎯⎯⎯⎯⎯⎯ Failed Tests 10 ⎯⎯⎯⎯⎯⎯⎯
Tests 10 failed | 3 passed (13)

View file

@ -1,18 +0,0 @@
Checking formatting...
[warn] apps/KronaStaffService/README.md
[warn] deploy/pilot/compose.yaml
[warn] docs/DRIVER-DISTRIBUTION.md
[warn] docs/HARDWARE-TEST-SLK20R.md
[warn] docs/TERMINAL-API-REQUIREMENTS.md
[warn] scripts/check-migrations.mjs
[warn] src/adapters/identity.ts
[warn] src/app.ts
[warn] src/config.ts
[warn] src/domain/attendance/work-session.ts
[warn] src/domain/notification/web-push.ts
[warn] src/portal.ts
[warn] tests/unit/config.test.ts
[warn] tests/unit/employee-push.test.ts
[warn] tests/unit/tenant-sql.test.ts
[warn] tests/unit/work-session.test.ts
[warn] Code style issues found in 16 files. Run Prettier with --write to fix.

View file

@ -1,16 +0,0 @@
[F2] ПОДТВЕРЖДЕНО — STANDALONE_ACCESS=manager, без токенов и без Authorization: GET /portal 200, GET /payroll 200, GET /finance 200, POST /professions 201; POST /session 403
[F2] ПОДТВЕРЖДЕНО — STANDALONE_ACCESS=employee, без токенов и без Authorization: GET /portal 200, GET /payroll 200, GET /finance 403, POST /professions 403; POST /session 403
[F4] ПОДТВЕРЖДЕНО — 60 неверных POST /session → {"401":60}
[F3] ПОДТВЕРЖДЕНО — вход 200, выход 204; cookie содержит сам токен менеджера: true; после DELETE /session старая cookie → GET /portal 200; флаги: Path=/; Max-Age=28800; HttpOnly; Secure; SameSite=Strict
[N1] ПОДТВЕРЖДЕНО — POST /employees → 500 {"statusCode":500,"code":"42P08","error":"Internal Server Error","message":"inconsistent types deduced for parameter $2"}
[N2] ПОДТВЕРЖДЕНО — PATCH /work-sessions (confirmed) → 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}; GET /pay-rules → 200 (6 правил, выбрано hourly); PUT pay-assignment → 200; POST /payroll/calculate → 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
[N4] ПОДТВЕРЖДЕНО — повторное подтверждение смены → 200; {"month":"2026-09"}: calculate 200, approve 200; {"from":"2026-09-02","to":"2026-09-30"}: calculate 200, approve 200; {"month":"2026-09","org_unit_id":"01M3E6YN08K537W6JNRANDR3X3"}: calculate 200, approve 200; в реестре начислений за одну смену 8 ч × 300 ₽: записей 3, сумма 7200 ₽
[D5] ПОДТВЕРЖДЕНО — отклонение смены, уже начисленной в утверждённой ведомости → 200; записей в реестре после этого: 3 (сторно не создано)
[N13] не воспроизведено — два одновременных первых расчёта октября → 200 {"run_id":"01M3E6YXA273MH6XX04CSAQJK9","status":"calculated","org_unit_id":null,"period_st | 200 {"run_id":"01M3E6YXA273MH6XX04CSAQJK9","status":"calculated","org_unit_id":null,"period_st
[D9] проверка — month=2026-13 → 500; rate_minor=1e20 и лишнее поле → 200 {"id":"01M3E6YXHHCBJPWMF6VT7MYZGY","employee_id":"01M3E6YN08XJM58HP60FWVJSJ5","org_unit_id":"01M3E6YN08K537W6JNRANDR3X3"
[N3] ПОДТВЕРЖДЕНО — выдача ключа сотруднику → 200; подписка на https://127.0.0.1:18443 → 201; отметка терминала → 201; входящих соединений на внутренний адрес: 1, TLS ClientHello: true
[N9] ПОДТВЕРЖДЕНО — сотрудник Б подписывает endpoint сотрудника А → 201; подписка теперь принадлежит сотруднику Б: true
[A4] проверка — 500 с деталями: POST /employees с несуществующей профессией → 500 {"statusCode":500,"code":"42P08","error":"Internal Server Error","message":"inconsistent types deduced for parameter $2"}
[N10] проверка — терминал: GET /professions → 200 ({"professions":[{"id":"01M3E6YEJRAZQ9ZRQM1XZXWJ8T","code":"profession-01m3e6yejrazq9zrqm1xzxwj8t","name":"audit-open-manager-1790404672076","status":"active","created_at":"2026-09-26T06:37:52.089Z","updated_at":"2026-09-…); GET /org-units → 200 {"org_units":[]}
[HDR] проверка — GET /staff: content-security-policy="default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests", strict-transport-security="max-age=31536000; includeSubDomains"

View file

@ -1,426 +0,0 @@
// Live audit of krona-staff against a real PostgreSQL 17. Read-only for the repository:
// data is seeded in a throwaway local database, tokens are random and never printed.
import { createRequire } from 'node:module';
import { spawn } from 'node:child_process';
import { randomBytes, createECDH } from 'node:crypto';
import net from 'node:net';
const REPO = 'C:/Users/Ochenstarik/Agent_projects/krona-staff-audit';
const require = createRequire(`${REPO}/package.json`);
const pg = require('pg');
const { ulid } = require('ulid');
const SUPER = 'postgres://postgres:audit-superuser@127.0.0.1:55432/krona_staff';
const APP = 'postgres://krona_staff_app:audit-app-password@127.0.0.1:55432/krona_staff';
const PORT = 18080;
const BASE = `http://127.0.0.1:${PORT}/api/v1/staff`;
const TENANT = ulid();
const ACTOR = ulid();
const TERMINAL_ACTOR = ulid();
const MANAGER_TOKEN = randomBytes(32).toString('base64url');
const TERMINAL_TOKEN = randomBytes(32).toString('base64url');
const results = [];
function record(id, verdict, detail) {
results.push({ id, verdict, detail });
console.log(`[${id}] ${verdict} — ${detail}`);
}
async function superQuery(sql, params = []) {
const client = new pg.Client({ connectionString: SUPER });
await client.connect();
try {
return await client.query(sql, params);
} finally {
await client.end();
}
}
function startServer(extraEnv) {
const env = {
...process.env,
NODE_ENV: 'development',
HOST: '127.0.0.1',
PORT: String(PORT),
LOG_LEVEL: 'silent',
STAFF_RUNTIME_MODE: 'standalone',
DATABASE_URL: APP,
STANDALONE_TENANT_ID: TENANT,
STANDALONE_ACTOR_ID: ACTOR,
STANDALONE_TERMINAL_ACTOR_ID: TERMINAL_ACTOR,
...extraEnv,
};
for (const [key, value] of Object.entries(env)) if (value === undefined) delete env[key];
const child = spawn(process.execPath, ['node_modules/tsx/dist/cli.mjs', 'src/server.ts'], {
cwd: REPO,
env,
stdio: ['ignore', 'ignore', 'pipe'],
});
let stderr = '';
child.stderr.on('data', (chunk) => (stderr += chunk));
child.stderrText = () => stderr;
return child;
}
async function waitReady() {
for (let attempt = 0; attempt < 120; attempt += 1) {
try {
const response = await fetch(`${BASE}/live`);
if (response.ok) return;
} catch {}
await new Promise((resolve) => setTimeout(resolve, 500));
}
throw new Error('server did not start');
}
async function stop(child) {
child.kill();
await new Promise((resolve) => setTimeout(resolve, 800));
}
async function call(method, path, { token, body, headers = {} } = {}) {
const response = await fetch(`${BASE}${path}`, {
method,
headers: {
...(body !== undefined ? { 'content-type': 'application/json' } : {}),
...(token ? { authorization: `Bearer ${token}` } : {}),
...headers,
},
body: body !== undefined ? JSON.stringify(body) : undefined,
});
const text = await response.text();
let json;
try {
json = JSON.parse(text);
} catch {
json = text;
}
return { status: response.status, json, headers: response.headers };
}
function brief(value) {
const text = typeof value === 'string' ? value : JSON.stringify(value);
return text.length > 220 ? `${text.slice(0, 220)}…` : text;
}
// ---------------------------------------------------------------- scenario A
async function scenarioOpenMode(access) {
const server = startServer({ STANDALONE_ACCESS: access });
try {
await waitReady();
const portal = await call('GET', '/portal');
const payroll = await call('GET', '/payroll');
const finance = await call('GET', '/finance');
const writeProfession = await call('POST', '/professions', {
body: { name: `audit-open-${access}-${Date.now()}` },
});
const session = await call('POST', '/session', {
body: { access_token: 'x'.repeat(40) },
headers: { origin: `http://127.0.0.1:${PORT}` },
});
record(
'F2',
portal.status === 200 || payroll.status === 200 ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено',
`STANDALONE_ACCESS=${access}, без токенов и без Authorization: GET /portal ${portal.status}, GET /payroll ${payroll.status}, GET /finance ${finance.status}, POST /professions ${writeProfession.status}; POST /session ${session.status}`,
);
} finally {
await stop(server);
}
}
// ---------------------------------------------------------------- scenario B
async function seed() {
const orgUnit = ulid();
const employee = ulid();
const pushEmployee = ulid();
const session = ulid();
await superQuery(
`INSERT INTO staff_org_units (id, tenant_id, code, name) VALUES ($1, $2, 'audit-unit', 'Аудиторская точка')`,
[orgUnit, TENANT],
);
await superQuery(
`INSERT INTO staff_employees (id, tenant_id, personnel_number, display_name, status)
VALUES ($1, $3, 'A-001', 'Аудит Сотрудник', 'active'), ($2, $3, 'A-002', 'Аудит Push', 'active')`,
[employee, pushEmployee, TENANT],
);
await superQuery(
`INSERT INTO staff_work_sessions
(id, tenant_id, employee_id, org_unit_id, business_date, started_at, ended_at, worked_minutes, status)
VALUES ($1, $2, $3, $4, '2026-09-10', '2026-09-10T02:00:00Z', '2026-09-10T10:00:00Z', 480, 'pending_review')`,
[session, TENANT, employee, orgUnit],
);
return { orgUnit, employee, pushEmployee, session };
}
async function scenarioWithTokens() {
const ids = await seed();
const server = startServer({
STANDALONE_ACCESS: 'employee',
STANDALONE_MANAGER_TOKEN: MANAGER_TOKEN,
STANDALONE_TERMINAL_TOKEN: TERMINAL_TOKEN,
});
try {
await waitReady();
const origin = { origin: `http://127.0.0.1:${PORT}` };
// F4: brute force on /session
const statuses = {};
for (let index = 0; index < 60; index += 1) {
const response = await call('POST', '/session', {
body: { access_token: randomBytes(32).toString('base64url') },
});
statuses[response.status] = (statuses[response.status] ?? 0) + 1;
}
record(
'F4',
statuses[429] ? 'не подтверждено' : 'ПОДТВЕРЖДЕНО',
`60 неверных POST /session → ${JSON.stringify(statuses)}`,
);
// F3: cookie carries the raw token and survives logout
const login = await call('POST', '/session', { body: { access_token: MANAGER_TOKEN } });
const setCookie = login.headers.get('set-cookie') ?? '';
const cookieValue = decodeURIComponent(setCookie.split(';')[0].split('=').slice(1).join('='));
const cookieIsToken = cookieValue === MANAGER_TOKEN;
const cookieHeader = setCookie.split(';')[0];
const logout = await call('DELETE', '/session', { headers: { cookie: cookieHeader } });
const afterLogout = await call('GET', '/portal', { headers: { cookie: cookieHeader } });
record(
'F3',
cookieIsToken && afterLogout.status === 200 ? 'ПОДТВЕРЖДЕНО' : 'частично',
`вход ${login.status}, выход ${logout.status}; cookie содержит сам токен менеджера: ${cookieIsToken}; после DELETE /session старая cookie → GET /portal ${afterLogout.status}; флаги: ${setCookie.split(';').slice(1).map((part) => part.trim()).join('; ')}`,
);
// N1: create employee
const created = await call('POST', '/employees', {
token: MANAGER_TOKEN,
body: { personnel_number: 'A-100', display_name: 'Новый Сотрудник', position: 'Повар' },
});
record(
'N1',
created.status >= 500 ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено',
`POST /employees → ${created.status} ${brief(created.json)}`,
);
// N2: confirm session and calculate
const confirm = await call('PATCH', `/work-sessions/${ids.session}`, {
token: MANAGER_TOKEN,
body: { status: 'confirmed' },
});
const rules = await call('GET', '/pay-rules', { token: MANAGER_TOKEN });
const ruleList = rules.json?.pay_rules ?? [];
const hourlyRule =
ruleList.find((rule) => /hour/.test(String(rule.code))) ?? ruleList[0];
const assignment = hourlyRule
? await call('PUT', `/employees/${ids.employee}/pay-assignment`, {
token: MANAGER_TOKEN,
body: {
pay_rule_id: hourlyRule.id,
org_unit_id: ids.orgUnit,
rate_minor: 30000,
effective_from: '2026-09-01',
},
})
: { status: 'нет правил', json: rules.json };
const calculate = await call('POST', '/payroll/calculate', {
token: MANAGER_TOKEN,
body: { month: '2026-09' },
});
record(
'N2',
confirm.status >= 500 || calculate.status >= 500 ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено',
`PATCH /work-sessions (confirmed) → ${confirm.status} ${brief(confirm.json)}; GET /pay-rules → ${rules.status} (${ruleList.length} правил, выбрано ${hourlyRule?.code}); PUT pay-assignment → ${assignment.status}; POST /payroll/calculate → ${calculate.status} ${brief(calculate.json)}`,
);
// N4: overlapping runs, after bypassing N2 in this throwaway database only
await superQuery('ALTER TABLE staff_outbox ALTER COLUMN occurred_at SET DEFAULT now()');
try {
const confirmAgain = await call('PATCH', `/work-sessions/${ids.session}`, {
token: MANAGER_TOKEN,
body: { status: 'confirmed' },
});
const periods = [
{ month: '2026-09' },
{ from: '2026-09-02', to: '2026-09-30' },
{ month: '2026-09', org_unit_id: ids.orgUnit },
];
const steps = [];
for (const period of periods) {
const run = await call('POST', '/payroll/calculate', { token: MANAGER_TOKEN, body: period });
const runId = run.json?.run_id ?? run.json?.id ?? run.json?.run?.id;
const approve = runId
? await call('POST', `/payroll/runs/${runId}/approve`, { token: MANAGER_TOKEN })
: { status: 'нет run_id', json: run.json };
steps.push(`${JSON.stringify(period)}: calculate ${run.status}, approve ${approve.status}`);
}
const ledger = await superQuery(
`SELECT count(*)::int AS entries, COALESCE(sum(amount_minor), 0)::bigint AS total
FROM staff_payroll_ledger WHERE tenant_id = $1 AND employee_id = $2 AND kind = 'accrual'`,
[TENANT, ids.employee],
);
const { entries, total } = ledger.rows[0];
record(
'N4',
entries > 1 ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено',
`повторное подтверждение смены → ${confirmAgain.status}; ${steps.join('; ')}; в реестре начислений за одну смену 8 ч × 300 ₽: записей ${entries}, сумма ${Number(total) / 100} ₽`,
);
// D5: a session already paid by an approved run can still be rejected or edited
const rejectPaid = await call('PATCH', `/work-sessions/${ids.session}`, {
token: MANAGER_TOKEN,
body: { status: 'rejected', correction_note: 'audit: after approval' },
});
const ledgerAfter = await superQuery(
`SELECT count(*)::int AS entries FROM staff_payroll_ledger
WHERE tenant_id = $1 AND employee_id = $2`,
[TENANT, ids.employee],
);
record(
'D5',
rejectPaid.status < 300 ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено',
`отклонение смены, уже начисленной в утверждённой ведомости → ${rejectPaid.status}; записей в реестре после этого: ${ledgerAfter.rows[0].entries} (сторно не создано)`,
);
// N13: two first calculations of the same new period at once
await superQuery(
`INSERT INTO staff_work_sessions
(id, tenant_id, employee_id, org_unit_id, business_date, worked_minutes, status)
VALUES ($1, $2, $3, $4, '2026-10-05', 480, 'confirmed')`,
[ulid(), TENANT, ids.employee, ids.orgUnit],
);
const race = await Promise.all([
call('POST', '/payroll/calculate', { token: MANAGER_TOKEN, body: { month: '2026-10' } }),
call('POST', '/payroll/calculate', { token: MANAGER_TOKEN, body: { month: '2026-10' } }),
]);
record(
'N13',
race.some((response) => response.status >= 500) ? 'ПОДТВЕРЖДЕНО' : 'не воспроизведено',
`два одновременных первых расчёта октября → ${race.map((response) => `${response.status} ${brief(response.json).slice(0, 90)}`).join(' | ')}`,
);
// Validation holes: impossible month and effective date
const badMonth = await call('POST', '/payroll/calculate', {
token: MANAGER_TOKEN,
body: { month: '2026-13' },
});
const hugeRate = await call('PUT', `/employees/${ids.employee}/pay-assignment`, {
token: MANAGER_TOKEN,
body: {
pay_rule_id: hourlyRule?.id,
org_unit_id: ids.orgUnit,
rate_minor: 1e20,
effective_from: '2026-11-01',
unexpected_field: 'accepted?',
},
});
record(
'D9',
'проверка',
`month=2026-13 → ${badMonth.status}; rate_minor=1e20 и лишнее поле → ${hugeRate.status} ${brief(hugeRate.json).slice(0, 120)}`,
);
} finally {
await superQuery('ALTER TABLE staff_outbox ALTER COLUMN occurred_at DROP DEFAULT');
}
// N3: SSRF through a push subscription
const inbound = { connections: 0, tlsHello: false };
const listener = net.createServer((socket) => {
inbound.connections += 1;
socket.once('data', (chunk) => {
if (chunk[0] === 0x16) inbound.tlsHello = true;
socket.destroy();
});
});
await new Promise((resolve) => listener.listen(18443, '127.0.0.1', resolve));
try {
const issued = await call('POST', `/employees/${ids.pushEmployee}/access-token`, {
token: MANAGER_TOKEN,
});
const employeeToken = issued.json?.access_token;
const ecdh = createECDH('prime256v1');
ecdh.generateKeys();
const subscribe = await call('POST', '/push/subscriptions', {
token: employeeToken,
body: {
endpoint: 'https://127.0.0.1:18443/internal-admin',
keys: {
p256dh: ecdh.getPublicKey().toString('base64url'),
auth: randomBytes(16).toString('base64url'),
},
},
});
const clock = await call('POST', '/attendance/events', {
token: TERMINAL_TOKEN,
body: {
employee_id: ids.pushEmployee,
event_type: 'check_in',
occurred_at: new Date().toISOString(),
source_event_id: `audit-${Date.now()}`,
org_unit_id: ids.orgUnit,
},
});
await new Promise((resolve) => setTimeout(resolve, 3000));
record(
'N3',
inbound.connections > 0 ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено',
`выдача ключа сотруднику → ${issued.status}; подписка на https://127.0.0.1:18443 → ${subscribe.status}; отметка терминала → ${clock.status}; входящих соединений на внутренний адрес: ${inbound.connections}, TLS ClientHello: ${inbound.tlsHello}`,
);
// N9: another employee re-binds the same endpoint
const other = await call('POST', `/employees/${ids.employee}/access-token`, {
token: MANAGER_TOKEN,
});
const rebind = await call('POST', '/push/subscriptions', {
token: other.json?.access_token,
body: {
endpoint: 'https://127.0.0.1:18443/internal-admin',
keys: { p256dh: ecdh.getPublicKey().toString('base64url'), auth: randomBytes(16).toString('base64url') },
},
});
const owner = await superQuery(
`SELECT employee_id FROM staff_push_subscriptions WHERE tenant_id = $1 AND endpoint = $2`,
[TENANT, 'https://127.0.0.1:18443/internal-admin'],
).catch((error) => ({ rows: [{ employee_id: `ошибка: ${error.message}` }] }));
record(
'N9',
rebind.status < 300 && owner.rows[0]?.employee_id === ids.employee ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено',
`сотрудник Б подписывает endpoint сотрудника А → ${rebind.status}; подписка теперь принадлежит сотруднику Б: ${owner.rows[0]?.employee_id === ids.employee}`,
);
// A4: internal error details leak in 500 responses
const badFk = await call('POST', '/employees', {
token: MANAGER_TOKEN,
body: { personnel_number: 'A-200', display_name: 'X', profession_id: ulid() },
});
record('A4', 'проверка', `500 с деталями: POST /employees с несуществующей профессией → ${badFk.status} ${brief(badFk.json)}`);
// N10: reference data without permission checks
const professionsByTerminal = await call('GET', '/professions', { token: TERMINAL_TOKEN });
const orgUnitsByTerminal = await call('GET', '/org-units', { token: TERMINAL_TOKEN });
record(
'N10',
'проверка',
`терминал: GET /professions → ${professionsByTerminal.status} (${Array.isArray(professionsByTerminal.json) ? professionsByTerminal.json.length : brief(professionsByTerminal.json)}); GET /org-units → ${orgUnitsByTerminal.status} ${brief(orgUnitsByTerminal.json)}`,
);
// Security headers on the portal
const page = await fetch(`http://127.0.0.1:${PORT}/staff`);
record(
'HDR',
'проверка',
`GET /staff: content-security-policy="${page.headers.get('content-security-policy')}", strict-transport-security="${page.headers.get('strict-transport-security')}"`,
);
} finally {
listener.close();
}
} finally {
const serverErrors = server.stderrText();
await stop(server);
if (serverErrors.trim()) console.log(`server stderr: ${brief(serverErrors)}`);
}
}
await scenarioOpenMode('manager');
await scenarioOpenMode('employee');
await scenarioWithTokens();
console.log('\nJSON', JSON.stringify(results));

View file

@ -1,213 +0,0 @@
// Live check of the offline sync branch (5ee7517) on a real PostgreSQL 17.
import { createRequire } from 'node:module';
import { spawn } from 'node:child_process';
import { randomBytes } from 'node:crypto';
const REPO = 'C:/Users/Ochenstarik/Agent_projects/krona-staff-sync';
const require = createRequire(`${REPO}/package.json`);
const pg = require('pg');
const { ulid } = require('ulid');
const SUPER = 'postgres://postgres:audit-superuser@127.0.0.1:55432/krona_staff_sync';
const APP = 'postgres://krona_staff_app:audit-app-password@127.0.0.1:55432/krona_staff_sync';
const PORT = 18081;
const BASE = `http://127.0.0.1:${PORT}/api/v1/staff`;
const TENANT = ulid();
const MANAGER_TOKEN = randomBytes(32).toString('base64url');
const TERMINAL_TOKEN = randomBytes(32).toString('base64url');
async function superQuery(sql, params = []) {
const client = new pg.Client({ connectionString: SUPER });
await client.connect();
try {
return await client.query(sql, params);
} finally {
await client.end();
}
}
async function call(method, path, { token, body } = {}) {
const response = await fetch(`${BASE}${path}`, {
method,
headers: {
...(body !== undefined ? { 'content-type': 'application/json' } : {}),
...(token ? { authorization: `Bearer ${token}` } : {}),
},
body: body !== undefined ? JSON.stringify(body) : undefined,
});
const text = await response.text();
try {
return { status: response.status, json: JSON.parse(text) };
} catch {
return { status: response.status, json: text };
}
}
const brief = (value) => {
const text = typeof value === 'string' ? value : JSON.stringify(value);
return text.length > 260 ? `${text.slice(0, 260)}…` : text;
};
// S9: deleting an org unit referenced by a sync device
const s9Unit = ulid();
const s9Device = ulid();
await superQuery(`INSERT INTO staff_org_units (id, tenant_id, code, name) VALUES ($1, $2, 's9', 'S9')`, [
s9Unit,
TENANT,
]);
const deviceColumns = (
await superQuery(
`SELECT column_name, is_nullable, column_default FROM information_schema.columns
WHERE table_name = 'staff_sync_devices' ORDER BY ordinal_position`,
)
).rows;
const values = {
id: s9Device,
tenant_id: TENANT,
device_code: 's9-device',
name: 'S9',
token_hash: 'a'.repeat(64),
token_hint: 'hint',
org_unit_id: s9Unit,
created_by: ulid(),
status: 'active',
};
const insertable = deviceColumns.filter(
(column) => values[column.column_name] !== undefined,
);
await superQuery(
`INSERT INTO staff_sync_devices (${insertable.map((c) => c.column_name).join(', ')})
VALUES (${insertable.map((_, index) => `$${index + 1}`).join(', ')})`,
insertable.map((column) => values[column.column_name]),
).catch((error) => console.log(`S9 setup: ${error.code} ${error.message}`));
try {
await superQuery(`DELETE FROM staff_org_units WHERE id = $1`, [s9Unit]);
console.log('[S9] не подтверждено — точку с привязанным устройством удалить удалось');
} catch (error) {
console.log(`[S9] ПОДТВЕРЖДЕНО — удаление точки с устройством → ${error.code} ${error.message}`);
}
// Seed an employee and a unit for S1
const orgUnit = ulid();
const employee = ulid();
await superQuery(
`INSERT INTO staff_org_units (id, tenant_id, code, name) VALUES ($1, $2, 'sync-unit', 'Точка')`,
[orgUnit, TENANT],
);
await superQuery(
`INSERT INTO staff_employees (id, tenant_id, personnel_number, display_name, status)
VALUES ($1, $2, 'S-001', 'Сотрудник Синхронизации', 'active')`,
[employee, TENANT],
);
const server = spawn(process.execPath, ['node_modules/tsx/dist/cli.mjs', 'src/server.ts'], {
cwd: REPO,
env: {
...process.env,
NODE_ENV: 'development',
HOST: '127.0.0.1',
PORT: String(PORT),
LOG_LEVEL: 'silent',
STAFF_RUNTIME_MODE: 'standalone',
STANDALONE_ACCESS: 'employee',
STANDALONE_MANAGER_TOKEN: MANAGER_TOKEN,
STANDALONE_TERMINAL_TOKEN: TERMINAL_TOKEN,
DATABASE_URL: APP,
STANDALONE_TENANT_ID: TENANT,
STANDALONE_ACTOR_ID: ulid(),
},
stdio: 'ignore',
});
try {
for (let attempt = 0; attempt < 120; attempt += 1) {
try {
if ((await fetch(`${BASE}/live`)).ok) break;
} catch {}
await new Promise((resolve) => setTimeout(resolve, 500));
}
const registered = await call('POST', '/sync/devices', {
token: MANAGER_TOKEN,
body: { device_code: 'kiosk-1', name: 'Киоск', org_unit_id: orgUnit },
});
const deviceToken = registered.json?.token;
console.log(`device registration → ${registered.status}; scopes ${JSON.stringify(registered.json?.device?.allowed_scopes)}`);
const forged = await call('POST', '/sync/push', {
token: deviceToken,
body: {
commands: [
{
command_type: 'upsert_work_session',
schema_version: 1,
idempotency_key: `forge-${Date.now()}`,
correlation_id: ulid(),
created_at: new Date().toISOString(),
payload: {
employee_id: employee,
org_unit_id: orgUnit,
business_date: '2026-09-15',
worked_minutes: 2880,
status: 'confirmed',
},
},
{
command_type: 'record_attendance',
schema_version: 1,
idempotency_key: `old-${Date.now()}`,
correlation_id: ulid(),
created_at: new Date().toISOString(),
payload: {
employee_id: employee,
event_type: 'check_in',
occurred_at: '2020-01-01T00:00:00Z',
},
},
],
},
});
console.log(`device push → ${forged.status} ${brief(forged.json)}`);
const session = await superQuery(
`SELECT status, worked_minutes, confirmed_by, correction_note
FROM staff_work_sessions WHERE tenant_id = $1 AND employee_id = $2 AND business_date = '2026-09-15'`,
[TENANT, employee],
);
const oldEvent = await superQuery(
`SELECT occurred_at FROM staff_attendance_events
WHERE tenant_id = $1 AND employee_id = $2 AND occurred_at < '2021-01-01'`,
[TENANT, employee],
);
const audit = await superQuery(
`SELECT count(*)::int AS entries FROM staff_audit_log WHERE tenant_id = $1`,
[TENANT],
);
const row = session.rows[0];
console.log(
`[S1] ${row?.status === 'confirmed' ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено'} — смена от устройства: статус ${row?.status}, минут ${row?.worked_minutes}, подтвердил ${row?.confirmed_by ?? 'никто'}, записей в журнале аудита арендатора: ${audit.rows[0].entries}`,
);
console.log(
`[S2] ${oldEvent.rowCount > 0 ? 'ПОДТВЕРЖДЕНО' : 'не подтверждено'} — отметка с временем 2020-01-01 через синхронизацию сохранена: ${oldEvent.rowCount > 0}`,
);
// The forged session flows into payroll (outbox default only in this throwaway database, see N2)
await superQuery('ALTER TABLE staff_outbox ALTER COLUMN occurred_at SET DEFAULT now()');
try {
const rules = await call('GET', '/pay-rules', { token: MANAGER_TOKEN });
const hourly = (rules.json?.pay_rules ?? []).find((rule) => /hour/.test(rule.code));
await call('PUT', `/employees/${employee}/pay-assignment`, {
token: MANAGER_TOKEN,
body: { pay_rule_id: hourly?.id, org_unit_id: orgUnit, rate_minor: 30000, effective_from: '2026-09-01' },
});
const run = await call('POST', '/payroll/calculate', { token: MANAGER_TOKEN, body: { month: '2026-09' } });
const total = run.json?.total_accrued_minor ?? run.json?.totals?.accrued_minor;
console.log(
`[S1→payroll] расчёт сентября → ${run.status}; начислено по поддельной смене: ${total !== undefined ? Number(total) / 100 : brief(run.json)} ₽ (48 ч × 300 ₽)`,
);
} finally {
await superQuery('ALTER TABLE staff_outbox ALTER COLUMN occurred_at DROP DEFAULT');
}
} finally {
server.kill();
}

View file

@ -1,5 +0,0 @@
[S9] ПОДТВЕРЖДЕНО — удаление точки с устройством → 23502 null value in column "tenant_id" of relation "staff_sync_devices" violates not-null constraint
device push → 200 {"results":[{"idempotency_key":"forge-1790405052967","command_type":"upsert_work_session","status":"applied","result":{"id":"01M3E7A2JB9PQ3YZQ4J5TE2V49","revision":1,"status":"applied"}},{"idempotency_key":"old-1790405052969","command_type":"record_attendance"…
[S1] ПОДТВЕРЖДЕНО — смена от устройства: статус confirmed, минут 2880, подтвердил никто, записей в журнале аудита арендатора: 0
[S2] ПОДТВЕРЖДЕНО — отметка с временем 2020-01-01 через синхронизацию сохранена: true
[S1→payroll] расчёт сентября → 200; начислено по поддельной смене: 14400 ₽ (48 ч × 300 ₽)

View file

@ -18,7 +18,6 @@ import { createServer } from 'node:net';
import { tmpdir } from 'node:os';
import path from 'node:path';
import pg from 'pg';
import { baseEnv, nodeWithTsx } from './node-commands.mjs';
const repoRoot = path.resolve(import.meta.dirname, '../..');
const args = process.argv.slice(2);
@ -78,7 +77,7 @@ runNode(
const dbEnv = parseEnvFile(path.join(secretsDir, 'db.env'));
rmSync(secretsDir, { recursive: true, force: true });
runNode(['scripts/test/migrate-roundtrip.mjs', 'up'], {
...baseEnv(),
PATH: process.env.PATH ?? '',
DATABASE_MIGRATION_URL: dbEnv.DATABASE_MIGRATION_URL,
});
const migrator = new pg.Client({ connectionString: dbEnv.DATABASE_MIGRATION_URL });
@ -100,11 +99,10 @@ for (const line of runNode(['scripts/generate-vapid-keys.mjs'], process.env).spl
}
const port = await freePort();
const log = createWriteStream(path.join(repoRoot, `tests/e2e/evidence/server-n13-${mode}.txt`));
const server = nodeWithTsx(['src/server.ts']);
const child = spawn(server.command, server.args, {
const child = spawn(path.join(repoRoot, 'node_modules/.bin/tsx'), ['src/server.ts'], {
cwd: repoRoot,
env: {
...baseEnv(),
PATH: process.env.PATH ?? '',
NODE_ENV: 'test',
HOST: '127.0.0.1',
PORT: String(port),

View file

@ -1,9 +0,0 @@
export type Tool = 'tsx' | 'vitest' | 'prettier';
export declare function toolEntry(tool: Tool): string;
export declare function nodeTool(tool: Tool, args?: string[]): { command: string; args: string[] };
export declare function nodeWithTsx(args?: string[]): { command: string; args: string[] };
export declare function baseEnv(
platform?: NodeJS.Platform,
env?: NodeJS.ProcessEnv,
): Record<string, string>;
export declare const repoRoot: string;

View file

@ -1,76 +0,0 @@
// Запуск инструментов из node_modules без .cmd-обёрток и без npx.
// Под Windows `node_modules/.bin/tsx` и `npx` — это .cmd-файлы: spawn() без shell
// падает с ENOENT. Поэтому всегда запускаем текущий node (process.execPath) с
// JS-точкой входа пакета, найденной через require.resolve.
import { createRequire } from 'node:module';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
const repoRoot = path.resolve(import.meta.dirname, '../..');
const require = createRequire(path.join(repoRoot, 'package.json'));
function packageBin(name, binName = name) {
const manifestPath = require.resolve(`${name}/package.json`);
const manifest = require(manifestPath);
const bin = typeof manifest.bin === 'string' ? manifest.bin : manifest.bin?.[binName];
if (!bin) throw new Error(`${name}: в package.json нет bin "${binName}"`);
return path.join(path.dirname(manifestPath), bin);
}
/** Абсолютный путь к JS-точке входа CLI (не .cmd, не .bin). */
export function toolEntry(tool) {
switch (tool) {
case 'tsx':
return require.resolve('tsx/cli');
case 'vitest':
return packageBin('vitest');
case 'prettier':
return packageBin('prettier');
default:
throw new Error(`неизвестный инструмент: ${tool}`);
}
}
/** Команда для spawn(command, args): всегда process.execPath + JS-файл CLI. */
export function nodeTool(tool, args = []) {
return { command: process.execPath, args: [toolEntry(tool), ...args] };
}
/**
* Запуск TypeScript-файла (например, src/server.ts) в ОДНОМ процессе node с
* загрузчиком tsx (`node --import tsx`). CLI tsx запускает дочерний node, и под
* Windows kill() родителя (TerminateProcess) оставил бы сервер-сироту на порту.
*/
export function nodeWithTsx(args = []) {
const loader = pathToFileURL(require.resolve('tsx')).href;
return { command: process.execPath, args: ['--import', loader, ...args] };
}
/**
* Минимальное окружение дочернего процесса: PATH и (под Windows) системные
* переменные, без которых node не может работать с сетью/криптографией
* (SystemRoot, WINDIR, TEMP и т. п.). Секреты родителя не наследуются.
*/
export function baseEnv(platform = process.platform, env = process.env) {
const keys = ['PATH'];
if (platform === 'win32') {
keys.push(
'SystemRoot',
'WINDIR',
'TEMP',
'TMP',
'USERPROFILE',
'LOCALAPPDATA',
'APPDATA',
'ComSpec',
'PATHEXT',
);
}
const result = {};
for (const key of keys) {
if (env[key] !== undefined) result[key] = env[key];
}
return result;
}
export { repoRoot };

View file

@ -7,11 +7,9 @@
// убрать из списка — иначе регрессию потом никто не заметит).
// * --no-known-defects: строгий режим, exit = код vitest (все дефекты красные).
// Полный вывод пишется в tests/e2e/evidence/e2e-run.txt, таблица — в e2e-table.md.
// tests/e2e/evidence/ не хранится в git (.gitignore): в CI это артефакт задачи e2e.
import { spawn } from 'node:child_process';
import { spawn, spawnSync } from 'node:child_process';
import { createWriteStream, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
import path from 'node:path';
import { nodeTool } from './node-commands.mjs';
const repoRoot = path.resolve(import.meta.dirname, '../..');
const evidence = path.join(repoRoot, 'tests/e2e/evidence');
@ -22,6 +20,7 @@ const logPath = path.join(evidence, 'e2e-run.txt');
const extra = process.argv.slice(2).filter((arg) => !arg.startsWith('--no-known-defects'));
const vitestArgs = [
'vitest',
'run',
'--config',
'tests/e2e/vitest.e2e.config.ts',
@ -31,10 +30,9 @@ const vitestArgs = [
...extra,
];
const log = createWriteStream(logPath);
const vitest = nodeTool('vitest', vitestArgs);
log.write(`$ node <vitest.mjs> ${vitestArgs.join(' ')}\n`);
log.write(`$ npx ${vitestArgs.join(' ')}\n`);
const exitCode = await new Promise((resolve) => {
const child = spawn(vitest.command, vitest.args, { cwd: repoRoot, env: process.env });
const child = spawn('npx', vitestArgs, { cwd: repoRoot, env: process.env });
for (const stream of [child.stdout, child.stderr]) {
stream.on('data', (chunk) => {
process.stdout.write(chunk);
@ -59,7 +57,7 @@ const known = strict
const byId = new Map();
for (const file of results.testResults) {
for (const test of file.assertionResults) {
const id = /^\[([A-Z0-9/-]+)\]/.exec(test.title)?.[1] ?? 'UNTAGGED';
const id = /^\[([A-Z0-9-]+)\]/.exec(test.title)?.[1] ?? 'UNTAGGED';
const entry = byId.get(id) ?? { passed: 0, failed: 0, tests: [] };
if (test.status === 'passed') entry.passed += 1;
else if (test.status === 'failed') entry.failed += 1;
@ -108,6 +106,12 @@ for (const id of Object.keys(known)) {
}
const table = ['| ID | Цвет | Зелёных/всего | Вердикт |', '|---|---|---|---|', ...rows].join('\n');
writeFileSync(path.join(evidence, 'e2e-table.md'), `${table}\n`);
// Сгенерированные json/md приводятся к prettier, чтобы `npm run format:check` не
// краснел из-за evidence (tests/e2e/evidence не в .prettierignore).
spawnSync('npx', ['prettier', '--write', jsonPath, path.join(evidence, 'e2e-table.md')], {
cwd: repoRoot,
stdio: 'ignore',
});
console.log(`\n[run-e2e] vitest exit=${exitCode}\n${table}`);
if (strict) {

View file

@ -17,15 +17,5 @@ main{width:min(100%,1480px);margin:0 auto;padding:var(--omni-space-5)}.app-view{
.auth-screen{min-height:100vh;display:grid;place-items:center;padding:var(--omni-space-6);background:var(--omni-bg-workspace)}.auth-card{width:min(100%,460px);padding:var(--omni-space-8);border:1px solid var(--omni-border);border-radius:var(--omni-radius-xl);background:var(--omni-surface-raised);box-shadow:var(--omni-shadow-strong)}.auth-brand{display:flex;align-items:center;gap:var(--omni-space-3);margin-bottom:var(--omni-space-8);font-size:1.2rem}.auth-card h1{margin:var(--omni-space-1) 0 var(--omni-space-3);font-size:1.875rem}.auth-copy{margin:0 0 var(--omni-space-5);color:var(--omni-text-secondary)}.auth-card form{display:grid;gap:var(--omni-space-2)}.auth-card label{font-size:var(--omni-text-label);font-weight:700}.auth-card input,.auth-card button{width:100%;min-height:48px}.auth-card small{display:block;margin-top:var(--omni-space-4);color:var(--omni-text-secondary)}@keyframes view-enter{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
@media(max-width:900px){:root{--omni-control-height:44px;--omni-control-height-sm:40px;--omni-row-height:48px}.topbar{align-items:flex-start;flex-wrap:wrap;padding:var(--omni-space-3) var(--omni-space-4)}.actions{width:100%;justify-content:flex-start;overflow-x:auto}.section-nav{top:108px;padding-inline:var(--omni-space-4)}.period-control{margin-left:var(--omni-space-2)}main{padding:var(--omni-space-4)}.layout,.finance-layout{grid-template-columns:1fr}.stats{grid-template-columns:repeat(2,minmax(0,1fr))}.inline-form{grid-template-columns:repeat(2,minmax(0,1fr))}.inline-form button{grid-column:1/-1}.timesheet-create{grid-template-columns:repeat(2,minmax(0,1fr))}.timesheet-create .grow,.timesheet-create button{grid-column:1/-1}}
@media(max-width:600px){.status,.theme-control{display:none}.section-nav{top:112px}.nav-item{min-height:var(--omni-touch-target)}main{padding:var(--omni-space-3)}.hero,.view-head{display:block}.hero{padding:var(--omni-space-4)}.today{margin-top:var(--omni-space-4);padding:var(--omni-space-3) 0 0;border-left:0;border-top:1px solid var(--omni-border)}.view-head button,.view-head .actions{margin-top:var(--omni-space-3)}.stats{grid-template-columns:1fr}.panel{padding:var(--omni-space-3)}.event{grid-template-columns:36px minmax(0,1fr)}.event time{grid-column:2}.person{grid-template-columns:36px minmax(0,1fr)}.person button{grid-column:2;width:100%}.directory-toolbar{align-items:stretch;flex-direction:column}.timesheet-create,.inline-form,.form-row-2{grid-template-columns:1fr}.calendar-weekdays,.calendar-grid{min-width:840px;grid-template-columns:repeat(7,120px)}.employee-dialog form{padding:var(--omni-space-4)}}
/* Workspace composition follows the supplied Krona Staff layouts while every visual value stays on Krona Library tokens. */
.platform-bar{min-height:44px;display:grid;grid-template-columns:auto minmax(280px,560px) auto;align-items:center;gap:var(--omni-space-4);padding:var(--omni-space-1) var(--omni-space-5);background:var(--omni-surface-raised);border-bottom:1px solid var(--omni-border-subtle)}.platform-context,.platform-actions{display:flex;align-items:center;gap:var(--omni-space-2);white-space:nowrap}.platform-context{color:var(--omni-text-secondary)}.platform-context strong{color:var(--omni-primary)}.app-grid{min-width:34px;min-height:34px;padding:0;background:transparent;border-color:transparent;color:var(--omni-primary);font-size:1.25rem}.global-search{min-height:34px;display:flex;align-items:center;gap:var(--omni-space-2);padding:0 var(--omni-space-3);border:1px solid var(--omni-border-subtle);border-radius:var(--omni-radius-sm);background:var(--omni-surface-muted);color:var(--omni-text-muted)}.global-search input{width:100%;min-height:30px;padding:0;border:0;background:transparent}.platform-actions{justify-content:flex-end}.module-bar{position:sticky;top:0;z-index:var(--omni-z-sticky);min-height:62px;display:flex;align-items:center;gap:var(--omni-space-5);padding:0 var(--omni-space-5);background:color-mix(in srgb,var(--omni-surface-raised) 96%,transparent);border-bottom:1px solid var(--omni-border-subtle);backdrop-filter:blur(14px)}.module-bar .brand{flex:0 0 auto}.module-bar .brand>span:last-child{display:grid}.module-bar .brand small{color:var(--omni-text-secondary);font-size:.67rem;font-weight:500}.module-bar .section-nav{position:static;flex:1;padding:0;background:transparent;border:0}.module-bar .nav-item{min-height:38px;padding-inline:var(--omni-space-2);font-size:var(--omni-text-label)}.module-bar .nav-item>span{font-size:1rem}
main{width:min(100%,1720px);padding:var(--omni-space-4) var(--omni-space-5) var(--omni-space-8)}.page-title-row{min-height:62px;display:flex;align-items:center;justify-content:space-between;gap:var(--omni-space-4);margin-bottom:var(--omni-space-3)}.page-title-row h1{margin:0;font-size:clamp(1.55rem,2vw,2rem);letter-spacing:-.025em}.page-title-row p{margin:var(--omni-space-1) 0 0;color:var(--omni-text-secondary)}.page-context{display:grid;justify-items:end;color:var(--omni-text-secondary)}.page-context small{color:var(--omni-text-muted)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.text-action{min-height:32px;padding:0;border:0;background:transparent;color:var(--omni-primary)}.text-action:hover{background:transparent;color:var(--omni-primary-hover)}
.metric-strip{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--omni-space-3);margin-bottom:var(--omni-space-3)}.metric-strip article{min-height:106px;display:flex;align-items:center;gap:var(--omni-space-3);padding:var(--omni-space-4);border:1px solid var(--omni-border-subtle);border-radius:var(--omni-radius-lg);background:var(--omni-surface-raised);box-shadow:var(--omni-shadow-soft)}.metric-strip small,.metric-strip span{display:block;color:var(--omni-text-secondary)}.metric-strip strong{display:block;margin:var(--omni-space-1) 0;font-size:1.55rem;font-variant-numeric:tabular-nums}.metric-icon{width:46px;height:46px;flex:0 0 auto;display:grid!important;place-items:center;border-radius:var(--omni-radius-pill);background:var(--omni-primary-soft);color:var(--omni-primary)!important;font-size:1.25rem;font-weight:750}.metric-icon.danger{background:var(--omni-danger-soft);color:var(--omni-danger)!important}.compact-metrics{grid-template-columns:repeat(3,minmax(0,1fr))}.compact-metrics article{min-height:84px;padding-block:var(--omni-space-3)}
.dashboard-grid{display:grid;grid-template-columns:minmax(420px,1.45fr) minmax(380px,1.15fr) minmax(290px,.8fr);grid-template-areas:"people attendance terminal" "payroll analytics alerts";gap:var(--omni-space-3)}.dashboard-grid>.panel{min-width:0}.dashboard-people{grid-area:people}.dashboard-attendance{grid-area:attendance}.dashboard-terminal{grid-area:terminal}.dashboard-payroll{grid-area:payroll}.dashboard-analytics{grid-area:analytics}.dashboard-alerts{grid-area:alerts}.dense-list,.alert-list{display:grid;gap:var(--omni-space-1)}.dense-row,.alert-row{min-height:46px;display:grid;grid-template-columns:34px minmax(0,1fr) auto;align-items:center;gap:var(--omni-space-2);padding:var(--omni-space-1) var(--omni-space-2);border-bottom:1px solid var(--omni-border-subtle)}.dense-row:last-child,.alert-row:last-child{border-bottom:0}.dense-row strong,.dense-row small,.alert-row strong,.alert-row small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dense-row small,.alert-row small,.dense-row time{color:var(--omni-text-secondary);font-size:var(--omni-text-label)}.alert-mark{width:28px;height:28px;display:grid;place-items:center;border-radius:var(--omni-radius-pill);background:var(--omni-warning-soft);color:var(--omni-warning);font-weight:800}.terminal-device{display:flex;align-items:center;gap:var(--omni-space-4);padding:var(--omni-space-4);margin-bottom:var(--omni-space-3);background:var(--omni-surface-muted);border-radius:var(--omni-radius-md)}.terminal-device strong,.terminal-device small{display:block}.terminal-device small{color:var(--omni-text-secondary)}.terminal-glyph{width:58px;height:72px;display:grid;place-items:center;border-radius:var(--omni-radius-sm);background:var(--omni-text-primary);color:var(--omni-success);font-size:1.8rem}.terminal-glyph.large{width:88px;height:112px;font-size:2.5rem}.dashboard-terminal dl,.terminal-card dl,.system-list,.inspector-list,.summary-dl{display:grid;gap:var(--omni-space-2);margin:0 0 var(--omni-space-3)}.dashboard-terminal dl div,.terminal-card dl div,.system-list div,.inspector-list div,.summary-dl div{display:flex;justify-content:space-between;gap:var(--omni-space-3);padding-bottom:var(--omni-space-2);border-bottom:1px solid var(--omni-border-subtle)}dl dt{color:var(--omni-text-secondary)}dl dd{margin:0;text-align:right;font-weight:650}.dashboard-totals{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--omni-space-2)}.dashboard-totals>div{padding:var(--omni-space-3);background:var(--omni-surface-muted);border-radius:var(--omni-radius-md)}.dashboard-totals small,.dashboard-totals strong{display:block}.rule-chips{display:flex;flex-wrap:wrap;gap:var(--omni-space-1);margin-top:var(--omni-space-3)}.mini-chart svg{width:100%;height:150px}.mini-chart .chart-legend{margin-top:var(--omni-space-2)}.quick-bar{position:sticky;bottom:var(--omni-space-2);z-index:5;display:flex;align-items:center;gap:var(--omni-space-2);margin-top:var(--omni-space-3);padding:var(--omni-space-2) var(--omni-space-3);border:1px solid var(--omni-border);border-radius:var(--omni-radius-lg);background:color-mix(in srgb,var(--omni-surface-raised) 96%,transparent);box-shadow:var(--omni-shadow-medium);backdrop-filter:blur(12px)}
.employee-workspace{display:grid;grid-template-columns:minmax(620px,1fr) minmax(300px,360px);gap:var(--omni-space-3)}.employee-list-panel{min-width:0}.directory-list{display:grid;gap:0}.directory-list .person{min-height:58px;grid-template-columns:38px minmax(180px,1fr) auto auto;border-width:0 0 1px;border-radius:0;background:transparent;cursor:pointer}.directory-list .person.selected{background:var(--omni-surface-selected);box-shadow:inset 3px 0 var(--omni-primary)}.inspector{position:sticky;top:78px;align-self:start}.inspector-head{display:flex;align-items:center;gap:var(--omni-space-3);padding-bottom:var(--omni-space-4);border-bottom:1px solid var(--omni-border-subtle)}.inspector-head h2{margin:0 0 var(--omni-space-2)}.avatar.large{width:64px;height:64px;font-size:1.35rem}.inspector-list{margin-top:var(--omni-space-4)}.inspector-actions{display:grid;grid-template-columns:1fr 1fr;gap:var(--omni-space-2)}
.segmented{display:inline-flex;align-items:center;padding:2px;border-radius:var(--omni-radius-sm);background:var(--omni-surface-muted)}.segmented button{min-height:34px;background:transparent;border-color:transparent;color:var(--omni-text-secondary)}.segmented button.selected{background:var(--omni-primary);border-color:var(--omni-primary);color:var(--omni-text-inverse)}.attendance-workspace{display:grid;grid-template-columns:minmax(600px,1.5fr) minmax(280px,.55fr);gap:var(--omni-space-3)}.attendance-workspace .event{border-width:0 0 1px;border-radius:0;background:transparent}.summary-dl dd{font-size:1.15rem}.finance-workspace{display:grid;grid-template-columns:minmax(680px,1.5fr) minmax(340px,.65fr);gap:var(--omni-space-3)}.finance-side{display:grid;align-content:start;gap:var(--omni-space-3)}.payroll-workspace{display:grid;grid-template-columns:minmax(720px,1.4fr) minmax(420px,.8fr);gap:var(--omni-space-3)}.payroll-workspace>.panel{min-width:0}.payroll-detail table{min-width:620px}.payroll-row{cursor:pointer}.rules-workspace,.terminal-workspace,.settings-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--omni-space-3)}.rule-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--omni-space-2)}.rule-card{display:grid;grid-template-columns:46px minmax(0,1fr) auto;align-items:center;gap:var(--omni-space-3);padding:var(--omni-space-3);border:1px solid var(--omni-border-subtle);border-radius:var(--omni-radius-md);background:var(--omni-surface)}.rule-card strong,.rule-card small{display:block}.rule-card small{color:var(--omni-text-secondary)}.terminal-card{display:flex;align-items:flex-start;gap:var(--omni-space-5)}.terminal-card h2{margin-top:0}.settings-field{display:grid;gap:var(--omni-space-2);color:var(--omni-text-secondary)}.calendar-legend{display:flex;justify-content:flex-end;gap:var(--omni-space-4);margin-bottom:var(--omni-space-2);color:var(--omni-text-secondary);font-size:var(--omni-text-label)}.calendar-legend i{width:9px;height:9px;display:inline-block;margin-right:var(--omni-space-1);border-radius:var(--omni-radius-pill);background:var(--omni-primary)}.calendar-legend .actual{background:var(--omni-info)}.calendar-legend .warning{background:var(--omni-warning)}.schedule-tabs{margin-bottom:var(--omni-space-3)}
@media(max-width:1380px){.module-bar{align-items:flex-start;flex-direction:column;gap:0;padding-top:var(--omni-space-2)}.module-bar .section-nav{width:100%}.dashboard-grid{grid-template-columns:1fr 1fr;grid-template-areas:"people attendance" "payroll analytics" "terminal alerts"}.metric-strip{grid-template-columns:repeat(3,minmax(0,1fr))}.employee-workspace{grid-template-columns:minmax(560px,1fr) 320px}.finance-workspace,.payroll-workspace{grid-template-columns:1fr}.payroll-detail{max-height:440px}}
@media(max-width:900px){.platform-bar{grid-template-columns:1fr auto}.global-search{grid-column:1/-1;grid-row:2}.module-bar{position:static}.module-bar .section-nav{top:auto}.dashboard-grid{grid-template-columns:1fr;grid-template-areas:"people" "attendance" "terminal" "payroll" "analytics" "alerts"}.metric-strip,.compact-metrics{grid-template-columns:repeat(2,minmax(0,1fr))}.employee-workspace,.attendance-workspace,.rules-workspace,.terminal-workspace,.settings-grid{grid-template-columns:1fr}.inspector{position:static}.quick-bar{position:static;flex-wrap:wrap}.finance-workspace{grid-template-columns:1fr}.rule-grid{grid-template-columns:1fr}}
@media(max-width:600px){.platform-context span,.platform-context b,.platform-actions .status{display:none}.platform-bar{padding-inline:var(--omni-space-3)}.module-bar{padding-inline:var(--omni-space-3)}.module-bar .brand{display:none}.page-title-row{align-items:flex-start;flex-direction:column}.page-title-row .actions{width:100%;overflow-x:auto}.metric-strip,.compact-metrics{grid-template-columns:1fr}.metric-strip article{min-height:82px}.dashboard-totals{grid-template-columns:1fr}.employee-workspace{display:block}.inspector{margin-top:var(--omni-space-3)}.directory-toolbar select{width:100%}.directory-list .person{grid-template-columns:36px minmax(0,1fr)}.directory-list .person .tag,.directory-list .person button{grid-column:2}.inspector-actions,.rule-grid{grid-template-columns:1fr}.terminal-card{display:grid}.quick-bar>*{width:100%}}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;transition-duration:.01ms!important}}
`;

File diff suppressed because one or more lines are too long

View file

@ -1,129 +0,0 @@
export const portalWorkspaceHtml = `<!doctype html>
<html lang="ru" data-omni-theme="noble-green" data-omni-density="workspace">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#315F46">
<title>Krona Staff</title>
<link rel="manifest" href="/staff/manifest.webmanifest">
<link rel="icon" type="image/svg+xml" href="/staff/icon-192.svg">
<link rel="apple-touch-icon" href="/staff/icon-192.svg">
<link rel="stylesheet" href="/staff/styles.css">
</head>
<body>
<section id="auth-screen" class="auth-screen" aria-labelledby="login-title">
<div class="auth-card">
<div class="auth-brand"><span class="mark">К</span><span>Krona <b>Staff</b></span></div>
<p class="eyebrow">Защищённый кабинет</p>
<h1 id="login-title">Вход в Krona Staff</h1>
<p class="auth-copy">Введите ключ руководителя или личный ключ сотрудника.</p>
<form id="login-form"><label for="login-token">Ключ доступа</label><input id="login-token" type="password" autocomplete="current-password" required minlength="32" autofocus><button id="login-submit" type="submit">Войти</button></form>
<div id="login-error" class="login-error" role="alert" hidden></div>
<small>Сессия действует 8 часов и хранится только в защищённой cookie.</small>
</div>
</section>
<div id="app-shell" hidden>
<header class="platform-bar">
<div class="platform-context"><button class="app-grid" type="button" aria-label="Модули платформы">⠿</button><span>Бизнес-платформа</span><b>/</b><strong>KRONA Staff</strong></div>
<label class="global-search"><span aria-hidden="true">⌕</span><input id="global-search" type="search" placeholder="Поиск по сотрудникам, операциям, документам…" aria-label="Глобальный поиск"></label>
<div class="platform-actions"><span id="connection" class="status">Подключение…</span><button id="refresh" class="quiet compact" type="button">Обновить</button><button id="logout" class="quiet compact" type="button">Выйти</button></div>
</header>
<header class="module-bar">
<a class="brand" href="/staff/dashboard" aria-label="Krona Staff"><span class="mark">К</span><span><b>KRONA Staff</b><small>Люди. Время. Развитие.</small></span></a>
<nav class="section-nav" aria-label="Разделы Krona Staff">
<button class="nav-item selected" type="button" data-target="overview-view" data-route="/staff/dashboard"><span>▦</span>Дашборд</button>
<button class="nav-item manager-only" type="button" data-target="employees-view" data-route="/staff/employees"><span>♟</span>Сотрудники</button>
<button class="nav-item" type="button" data-target="attendance-view" data-route="/staff/attendance"><span>◷</span>Посещаемость</button>
<button class="nav-item" type="button" data-target="shifts-view" data-route="/staff/shifts"><span>◫</span>Смены</button>
<button class="nav-item" type="button" data-target="schedule-view" data-route="/staff/schedules"><span>▦</span>Графики</button>
<button class="nav-item manager-only" type="button" data-target="finance-view" data-route="/staff/finance"><span>◎</span>Финансы</button>
<button class="nav-item" type="button" data-target="payroll-view" data-route="/staff/payroll"><span>▤</span>Зарплата</button>
<button class="nav-item manager-only" type="button" data-target="rules-view" data-route="/staff/rules"><span>⌘</span>Правила</button>
<button class="nav-item manager-only" type="button" data-target="terminal-view" data-route="/staff/terminal"><span>▣</span>Терминал</button>
<button class="nav-item" type="button" data-target="notifications-view" data-route="/staff/notifications"><span>♢</span>Уведомления</button>
<button class="nav-item" type="button" data-target="reports-view" data-route="/staff/reports"><span>▥</span>Отчёты</button>
<button class="nav-item" type="button" data-target="settings-view" data-route="/staff/settings"><span>⚙</span>Настройки</button>
</nav>
</header>
<main>
<div id="message" class="message" hidden></div>
<section id="overview-view" class="app-view">
<div class="page-title-row"><div><h1>Дашборд</h1><p id="viewer">Кабинет руководителя</p></div><div class="page-context"><span id="today">—</span><small id="last-refresh">Данные загружаются</small></div></div>
<h2 id="greeting" class="sr-only">Команда и рабочее время</h2>
<section class="metric-strip" aria-label="Оперативная сводка">
<article><span class="metric-icon">♟</span><div><small>Всего сотрудников</small><strong id="employees-count">—</strong><span>В штате компании</span></div></article>
<article><span class="metric-icon">◷</span><div><small>Отметок сегодня</small><strong id="today-count">—</strong><span>Приходы и уходы</span></div></article>
<article><span class="metric-icon">◫</span><div><small>Часов в табеле</small><strong id="hours-count">—</strong><span>За доступный период</span></div></article>
<article class="manager-only"><span class="metric-icon">◎</span><div><small>Финансовый результат</small><strong id="dashboard-profit">—</strong><span>За выбранный месяц</span></div></article>
<article><span class="metric-icon">!</span><div><small>Требуют внимания</small><strong id="dashboard-attention">—</strong><span>Смены и проверки</span></div></article>
</section>
<div class="dashboard-grid">
<section class="panel dashboard-people"><div class="panel-head"><h2>Сотрудники</h2><button class="text-action" type="button" data-open-view="employees-view">Все сотрудники →</button></div><div id="dashboard-employees" class="dense-list"><div class="empty">Загрузка…</div></div></section>
<section class="panel dashboard-attendance"><div class="panel-head"><h2>Посещаемость сегодня</h2><button class="text-action" type="button" data-open-view="attendance-view">Подробнее →</button></div><div id="dashboard-attendance" class="dense-list"><div class="empty">Загрузка…</div></div></section>
<aside class="panel dashboard-terminal"><div class="panel-head"><h2>Терминал учёта</h2><span class="status ok">Онлайн</span></div><div class="terminal-device"><span class="terminal-glyph">▣</span><div><strong>SLK20R</strong><small>Локальный терминал отпечатков</small></div></div><dl><div><dt>Последнее событие</dt><dd id="terminal-last-event">—</dd></div><div><dt>Синхронизация</dt><dd id="terminal-last-sync">Ожидание данных</dd></div></dl><button class="quiet" type="button" data-open-view="terminal-view">Открыть терминал</button></aside>
<section class="panel dashboard-payroll manager-only"><div class="panel-head"><h2>Расчёт зарплаты</h2><button class="text-action" type="button" data-open-view="payroll-view">Подробнее →</button></div><div class="dashboard-totals"><div><small>Начислено</small><strong id="dashboard-accrued">—</strong></div><div><small>Выплачено</small><strong id="dashboard-paid">—</strong></div><div><small>Остаток</small><strong id="dashboard-balance">—</strong></div></div><div class="rule-chips" id="dashboard-rules"></div></section>
<section class="panel dashboard-analytics manager-only"><div class="panel-head"><h2>Финансы месяца</h2><button class="text-action" type="button" data-open-view="finance-view">Подробнее →</button></div><div id="dashboard-finance-chart" class="mini-chart"><div class="empty">Загрузка…</div></div></section>
<section class="panel dashboard-alerts"><div class="panel-head"><h2>Уведомления</h2><button class="text-action" type="button" data-open-view="notifications-view">Все →</button></div><div id="dashboard-alert-list" class="alert-list"><div class="empty">Нет новых данных</div></div></section>
</div>
<div class="quick-bar manager-only"><strong>Быстрые действия</strong><button type="button" id="dashboard-add-employee">+ Добавить сотрудника</button><button type="button" class="quiet" data-open-view="shifts-view">Открыть смены</button><button type="button" class="quiet" data-open-view="payroll-view">Запустить расчёт</button><button type="button" class="quiet" data-open-view="rules-view">Настроить правила</button></div>
</section>
<section id="employees-view" class="app-view manager-only" hidden>
<div class="page-title-row"><div><h1>Сотрудники</h1><p>Персонал, профессии, статусы и зарплатные профили</p></div><div class="actions"><button id="manage-professions-directory" class="quiet" type="button">Профессии</button><button id="add-employee-directory" type="button">+ Добавить сотрудника</button></div></div>
<section class="metric-strip compact-metrics"><article><span class="metric-icon">♟</span><div><small>Всего сотрудников</small><strong id="directory-total">—</strong></div></article><article><span class="metric-icon">✓</span><div><small>Показано</small><strong id="directory-active">—</strong></div></article><article><span class="metric-icon">!</span><div><small>Требуют внимания</small><strong id="directory-attention">—</strong></div></article></section>
<button id="add-employee" type="button" hidden>Добавить сотрудника</button><div class="employee-workspace"><section class="panel employee-list-panel"><div class="directory-toolbar"><input id="employee-search" type="search" placeholder="Поиск по имени, должности или табельному номеру" aria-label="Поиск сотрудников"><select id="employee-status-filter" aria-label="Статус"><option value="">Все статусы</option><option value="active">Работает</option><option value="blocked">Заблокирован</option><option value="dismissed">Уволен</option></select><span id="employee-search-result" class="status">Все сотрудники</span></div><div id="employees-directory" class="people directory-list"></div><div id="employees" hidden></div></section><aside id="employee-inspector" class="panel inspector"><div class="empty">Выберите сотрудника в списке</div></aside></div>
</section>
<section id="attendance-view" class="app-view" hidden>
<div class="page-title-row"><div><h1>Посещаемость</h1><p>Фактические приходы и уходы со сканера</p></div><span class="live">● в реальном времени</span></div>
<div class="attendance-workspace"><section class="panel"><div class="panel-head"><h2>Журнал отметок</h2><div class="segmented"><button class="selected" type="button" data-event-filter="">Все</button><button type="button" data-event-filter="check_in">Приходы</button><button type="button" data-event-filter="check_out">Уходы</button></div></div><div id="attendance" class="feed"></div></section><aside class="panel"><div class="panel-head"><h2>Сводка дня</h2></div><div id="attendance-summary" class="summary-stack"><div class="empty">Загрузка…</div></div></aside></div>
</section>
<section id="shifts-view" class="app-view" hidden>
<div class="page-title-row"><div><h1>Смены</h1><p>Сверка отметок, аномалии и подтверждение рабочего времени</p></div><button id="reconcile-sessions" type="button">Сверить 7 дней</button></div>
<section class="panel"><div class="panel-head"><h2>Рабочие смены</h2><span>План и фактический интервал</span></div><div class="table-wrap"><table><thead><tr><th>Дата</th><th>Сотрудник</th><th>Подразделение</th><th>Интервал</th><th>Часы</th><th>Состояние</th><th>Причина правки</th><th></th></tr></thead><tbody id="work-sessions"></tbody></table></div></section>
</section>
<section id="schedule-view" class="app-view" hidden>
<div class="page-title-row"><div><h1>Графики</h1><p>Планирование смен и контроль фактических выходов</p></div><div class="actions"><label class="period-control">Месяц <input id="period-month" type="month" aria-label="Месяц данных"></label><button id="schedule-refresh" class="quiet" type="button">Обновить</button></div></div>
<div class="schedule-tabs segmented"><button type="button">Год</button><button type="button">Квартал</button><button class="selected" type="button">Месяц</button><button type="button">Неделя</button></div>
<section class="panel manager-only schedule-editor"><form id="schedule-form" class="inline-form"><label>Сотрудник<select id="schedule-employee" required></select></label><label>Точка<select id="schedule-unit" required></select></label><label>Дата<input id="schedule-date" type="date" required></label><label>Часы<input id="schedule-hours" type="number" inputmode="decimal" min="0" max="24" step="0.5" value="12" required></label><label>Начало<input id="schedule-start" type="time" value="10:00"></label><label>Конец<input id="schedule-end" type="time" value="22:00"></label><button type="submit">+ Добавить</button></form></section>
<section class="panel calendar-panel"><div class="calendar-legend"><span><i class="planned"></i>Запланировано</span><span><i class="actual"></i>Есть факты</span><span><i class="warning"></i>Требует внимания</span></div><div class="calendar-weekdays" aria-hidden="true"><span>Пн</span><span>Вт</span><span>Ср</span><span>Чт</span><span>Пт</span><span>Сб</span><span>Вс</span></div><div id="calendar-grid" class="calendar-grid"></div></section>
</section>
<section id="finance-view" class="app-view manager-only" hidden>
<div class="page-title-row"><div><h1>Финансы</h1><p>Выручка, расходы и финансовый результат</p></div><div class="actions"><button id="finance-refresh" class="quiet" type="button">Обновить</button></div></div>
<section class="metric-strip compact-metrics"><article><span class="metric-icon">↗</span><div><small>Доход</small><strong id="finance-income">—</strong></div></article><article><span class="metric-icon danger">↘</span><div><small>Расход</small><strong id="finance-expense">—</strong></div></article><article><span class="metric-icon">◕</span><div><small>Прибыль</small><strong id="finance-profit">—</strong></div></article></section>
<div class="finance-workspace"><section class="panel finance-journal"><div class="panel-head"><h2>Журнал операций</h2><span id="finance-count">0 записей</span></div><div class="table-wrap"><table><thead><tr><th>Дата</th><th>Точка</th><th>Категория</th><th>Тип</th><th>Сумма</th></tr></thead><tbody id="finance-entries"></tbody></table></div></section><aside class="finance-side"><section class="panel"><div class="panel-head"><h2>Быстрое внесение</h2></div><form id="finance-form" class="stack-form"><label>Дата<input id="finance-date" type="date" required></label><label>Торговая точка<select id="finance-unit" required></select></label><label>Категория<select id="finance-category" required></select></label><label>Сумма, ₽<input id="finance-amount" type="number" inputmode="decimal" min="0" step="0.01" required></label><button type="submit">Сохранить операцию</button></form></section><section class="panel"><div class="panel-head"><h2>Доходы и расходы</h2><span>₽</span></div><div id="finance-chart" class="finance-chart" role="img" aria-label="График доходов и расходов"></div></section></aside></div>
</section>
<section id="payroll-view" class="app-view" hidden>
<div class="page-title-row"><div><h1>Зарплата</h1><p>Расчёт начислений, выплат и остатка по сотрудникам</p></div><div class="actions"><button id="payroll-calc-btn" class="manager-only" type="button">▶ Запустить расчёт</button><button id="payroll-refresh" class="quiet" type="button">Пересчитать</button></div></div>
<div id="payroll-calc-status" class="message" hidden></div><div id="payroll-warnings" class="payroll-warnings message" hidden></div>
<section class="metric-strip compact-metrics"><article><span class="metric-icon">◎</span><div><small>Начислено</small><strong id="payroll-accrued">—</strong></div></article><article><span class="metric-icon">▣</span><div><small>Выплачено</small><strong id="payroll-paid">—</strong></div></article><article><span class="metric-icon">◷</span><div><small>Остаток</small><strong id="payroll-balance">—</strong></div></article></section>
<section id="payroll-preview-card" class="panel manager-only" hidden><div class="panel-head"><h2 id="payroll-preview-title">Предварительный результат</h2><button id="payroll-approve-btn" type="button">Утвердить расчёт</button></div><div class="table-wrap"><table><thead><tr><th>Сотрудник</th><th>Должность</th><th>Дней</th><th>Факт, часов</th><th>Начислено</th></tr></thead><tbody id="payroll-preview-rows"></tbody></table></div></section>
<div class="payroll-workspace"><section class="panel"><div class="panel-head"><h2>Расчёт по сотрудникам</h2><span>По подтверждённым сменам</span></div><div class="table-wrap"><table><thead><tr><th>Сотрудник</th><th>Должность</th><th>Факт, часов</th><th>Начислено</th><th>Выплачено</th><th>Остаток</th></tr></thead><tbody id="payroll-rows"></tbody></table></div></section><aside class="panel payroll-detail"><div class="panel-head"><h2>История операций</h2></div><div class="table-wrap"><table><thead><tr><th>Дата</th><th>Сотрудник</th><th>Операция</th><th>Сумма</th><th>Примечание</th></tr></thead><tbody id="payroll-entries"></tbody></table></div></aside></div>
</section>
<section id="rules-view" class="app-view manager-only" hidden><div class="page-title-row"><div><h1>Правила начислений</h1><p>Схемы оплаты и профессии сотрудников</p></div><button id="manage-professions" class="quiet" type="button">+ Профессия</button></div><div class="rules-workspace"><section class="panel"><div class="panel-head"><h2>Активные схемы оплаты</h2></div><div id="rules-list" class="rule-grid"><div class="empty">Загрузка…</div></div></section><section class="panel"><div class="panel-head"><h2>Профессии</h2></div><div id="rules-professions" class="dense-list"><div class="empty">Загрузка…</div></div></section></div></section>
<section id="terminal-view" class="app-view manager-only" hidden><div class="page-title-row"><div><h1>Терминал</h1><p>Состояние локального сканера и последние события</p></div><span class="status ok">Сервер онлайн</span></div><div class="terminal-workspace"><section class="panel terminal-card"><span class="terminal-glyph large">▣</span><div><h2>BioLink SLK20R</h2><p>Локальный агент фиксирует отпечатки и безопасно передаёт события на сервер.</p><dl><div><dt>Последняя синхронизация</dt><dd id="terminal-sync-detail">—</dd></div><div><dt>Последняя отметка</dt><dd id="terminal-event-detail">—</dd></div></dl></div></section><section class="panel"><div class="panel-head"><h2>Последние события терминала</h2></div><div id="terminal-events" class="dense-list"><div class="empty">Загрузка…</div></div></section></div></section>
<section id="notifications-view" class="app-view" hidden><div class="page-title-row"><div><h1>Уведомления</h1><p>События, требующие внимания руководителя</p></div><button id="notify" class="quiet" type="button">Включить push</button></div><section class="panel"><div id="notifications-list" class="alert-list"><div class="empty">Нет новых уведомлений</div></div></section></section>
<section id="reports-view" class="app-view" hidden><div class="page-title-row"><div><h1>Отчёты</h1><p>Табель рабочего времени и подтверждённые данные</p></div><span id="timesheet-help">Изменения сохраняет руководитель</span></div><section class="panel"><form id="timesheet-create" class="timesheet-create"><label>Сотрудник<select id="new-time-employee" required></select></label><label>Дата<input id="new-time-date" type="date" required></label><label>Часы<input id="new-time-hours" type="number" min="0" max="24" step="0.25" value="8" required></label><label>Статус<select id="new-time-status"><option value="draft">Черновик</option><option value="submitted">На проверке</option><option value="approved">Утверждён</option><option value="rejected">Возвращён</option></select></label><label class="grow">Примечание<input id="new-time-note" maxlength="1000" placeholder="Необязательно"></label><button type="submit">Добавить строку</button></form><div class="table-wrap"><table><thead><tr><th>Дата</th><th>Сотрудник</th><th>Часы</th><th>Статус</th><th>Примечание</th><th></th></tr></thead><tbody id="timesheet"></tbody></table></div></section></section>
<section id="settings-view" class="app-view" hidden><div class="page-title-row"><div><h1>Настройки</h1><p>Внешний вид, уведомления и состояние подключения</p></div></div><div class="settings-grid"><section class="panel"><div class="panel-head"><h2>Интерфейс</h2></div><label class="settings-field">Тема<select id="theme-select" aria-label="Тема интерфейса"><option value="noble-green">Благородный зелёный</option><option value="parchment-light">Пергамент</option><option value="graphite-forest-dark">Тёмная</option></select></label></section><section class="panel"><div class="panel-head"><h2>О системе</h2></div><dl class="system-list"><div><dt>Модуль</dt><dd>Krona Staff</dd></div><div><dt>Режим</dt><dd>Автономный с интеграцией платформы</dd></div><div><dt>Данные</dt><dd>PostgreSQL с tenant isolation</dd></div></dl></section></div></section>
</main>
<input id="employee-position" type="hidden">
<dialog id="employee-dialog" class="employee-dialog"><form id="employee-form" method="dialog"><div class="dialog-head"><div><p class="eyebrow">Карточка сотрудника</p><h2 id="employee-dialog-title">Новый сотрудник</h2></div><button id="employee-close" class="icon-button" type="button" aria-label="Закрыть">×</button></div><input id="employee-id" type="hidden"><label>Табельный номер<input id="employee-number" maxlength="80" required></label><label>Фамилия, имя и отчество<input id="employee-name" maxlength="240" required></label><label>Профессия<select id="employee-profession"><option value="">Не указана</option></select></label><p class="role-note">Роли и права платформы управляются в Krona Core отдельно от кадровой профессии.</p><label>Пол<select id="employee-gender"><option value="">Не указан</option><option value="female">Женский</option><option value="male">Мужской</option></select></label><label id="employee-status-wrap" hidden>Статус<select id="employee-status"><option value="active">Работает</option><option value="blocked">Заблокирован</option><option value="dismissed">Уволен</option></select></label><div id="employee-pay-section" class="pay-profile-section manager-only"><p class="eyebrow">Зарплатный профиль</p><label>Торговая точка<select id="employee-pay-unit"></select></label><label>Схема расчёта<select id="employee-pay-rule"></select></label><div class="form-row-2"><label>Ставка в час, ₽<input id="employee-pay-rate" type="number" min="0" step="1" value="100"></label><label>Процент от выручки, %<input id="employee-pay-percent" type="number" min="0" max="100" step="0.1" value="0"></label></div><div class="form-row-2"><label>Гарантия за смену, ₽<input id="employee-pay-guarantee" type="number" min="0" step="100" value="0"></label><label>Доля в фонде, %<input id="employee-pay-pool-weight" type="number" min="0" max="200" step="10" value="100"></label></div><label>Действует с даты<input id="employee-pay-effective" type="date"></label><small>Новая версия действует с выбранной даты.</small></div><div id="employee-error" class="login-error" role="alert" hidden></div><div class="dialog-actions"><button id="employee-cancel" class="quiet" type="button">Отмена</button><button id="employee-save" type="submit">Сохранить</button></div></form></dialog>
<dialog id="profession-dialog" class="employee-dialog"><form id="profession-form" method="dialog"><div class="dialog-head"><div><p class="eyebrow">Кадровый справочник</p><h2>Профессии</h2></div><button id="profession-close" class="icon-button" type="button" aria-label="Закрыть">×</button></div><label>Новая профессия<input id="profession-name" maxlength="160" required placeholder="Например, Повар"></label><button type="submit">Добавить профессию</button><div id="profession-list" class="people"></div><div id="profession-error" class="login-error" role="alert" hidden></div></form></dialog>
<dialog id="access-dialog" class="employee-dialog"><form method="dialog"><div class="dialog-head"><div><p class="eyebrow">Личный кабинет</p><h2>Ключ сотрудника</h2></div><button id="access-close" class="icon-button" type="submit" aria-label="Закрыть">×</button></div><p>Скопируйте ключ сейчас. Повторно показать его нельзя.</p><label>Ключ доступа<input id="access-token" readonly></label><div class="dialog-actions"><button id="access-copy" type="button">Скопировать</button><button class="quiet" type="submit">Закрыть</button></div></form></dialog>
<footer>Krona Business Platform · Staff</footer>
</div>
<script src="/staff/app.js" defer></script>
</body>
</html>`;

View file

@ -42,7 +42,7 @@ async function accrualsFor(employeeId: string) {
}
describe('Основной API на реальной PostgreSQL', () => {
it('[K4/N1] менеджер создаёт сотрудника через POST /employees → 201', async () => {
it('[N1] менеджер создаёт сотрудника через POST /employees → 201', async () => {
const number = `E2E-${randomUlid().slice(-8)}`;
const response = await api('POST', '/employees', {
token: ctx().managerToken,
@ -59,7 +59,7 @@ describe('Основной API на реальной PostgreSQL', () => {
expect(rows).toHaveLength(1);
});
it('[K3/N2] подтверждение смены, расчёт и утверждение зарплаты проходят (200) и начисляют 8 ч × ставка', async () => {
it('[N2] подтверждение смены, расчёт и утверждение зарплаты проходят (200) и начисляют 8 ч × ставка', async () => {
const [unit] = await createOrgUnits(1);
const [employee] = await importEmployees(1);
await assignHourly(employee!.id, unit!.id);
@ -88,7 +88,7 @@ describe('Основной API на реальной PostgreSQL', () => {
expect(total).toBe(BigInt(8 * SYNTHETIC_RATE_MINOR));
});
it('[K5/N4] пересекающиеся расчёты не начисляют одну смену дважды', async () => {
it('[N4] пересекающиеся расчёты не начисляют одну смену дважды', async () => {
const [unit] = await createOrgUnits(1);
const [employee] = await importEmployees(1);
await assignHourly(employee!.id, unit!.id);
@ -136,7 +136,7 @@ describe('Основной API на реальной PostgreSQL', () => {
);
});
it('[K12/N3] push-подписка на внутренний адрес отклоняется, сервер не подключается к 127.0.0.1', async () => {
it('[N3] push-подписка на внутренний адрес отклоняется, сервер не подключается к 127.0.0.1', async () => {
const [employee] = await importEmployees(1);
const employeeToken = await issueEmployeeToken(employee!.id);
let connections = 0;
@ -227,7 +227,7 @@ describe('Основной API на реальной PostgreSQL', () => {
});
});
it('[K1/F2] standalone без токенов не выдаёт права менеджера анонимному запросу (401)', async () => {
it('[F2] standalone без токенов не выдаёт права менеджера анонимному запросу (401)', async () => {
const portal = await api('GET', '/portal', { base: 'open' });
const payroll = await api('GET', '/payroll', { base: 'open' });
const write = await api('POST', '/professions', {
@ -241,7 +241,7 @@ describe('Основной API на реальной PostgreSQL', () => {
});
});
it('[K10/F3] cookie сессии не содержит сырой токен и отзывается при выходе', async () => {
it('[F3] cookie сессии не содержит сырой токен и отзывается при выходе', async () => {
const login = await api('POST', '/session', { body: { access_token: ctx().managerToken } });
expect(login.status, describeResponse(login)).toBe(200);
const setCookie = login.headers.get('set-cookie') ?? '';
@ -311,7 +311,7 @@ describe('Основной API на реальной PostgreSQL', () => {
expect(response.status, describeResponse(response)).toBe(400);
});
it('[K11/F4] перебор ключей входа ограничивается (429 не позже 30 неверных попыток)', async () => {
it('[F4] перебор ключей входа ограничивается (429 не позже 30 неверных попыток)', async () => {
const statuses: number[] = [];
for (let attempt = 0; attempt < 30; attempt += 1) {
const response = await api('POST', '/session', {

View file

@ -57,7 +57,7 @@ async function pullAll(device: Device, cursor: string | null = null) {
}
describe('Офлайн-синхронизация на реальной PostgreSQL', () => {
it('[K13/SYNC-A] устройство не может само подтвердить смену (status=confirmed отклоняется)', async () => {
it('[SYNC-A] устройство не может само подтвердить смену (status=confirmed отклоняется)', async () => {
const [unit] = await createOrgUnits(1);
const [employee] = await importEmployees(1);
const device = await registerDevice(unit!.id);
@ -86,7 +86,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
).toEqual({ http: 200, result: 'rejected', stored: null });
});
it('[K13/SYNC-B] устройство не может утвердить табель (status=approved отклоняется)', async () => {
it('[SYNC-B] устройство не может утвердить табель (status=approved отклоняется)', async () => {
const [employee] = await importEmployees(1);
const device = await registerDevice();
const entryId = randomUlid();
@ -124,7 +124,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
expect(types.has('employee') && types.has('org_unit')).toBe(true);
});
it('[S5/SYNC-C] начальная загрузка >100 сущностей отдаёт все сущности постранично', async () => {
it('[SYNC-C] начальная загрузка >100 сущностей отдаёт все сущности постранично', async () => {
const employees = await importEmployees(120);
const device = await registerDevice();
const { changes } = await pullAll(device, null);
@ -135,7 +135,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
expect(missing, `не доставлено сотрудников: ${missing} из ${employees.length}`).toBe(0);
});
it('[S5/SYNC-D] изменения, сделанные через портал, попадают в инкрементальный pull', async () => {
it('[SYNC-D] изменения, сделанные через портал, попадают в инкрементальный pull', async () => {
const device = await registerDevice();
// Курсор берём из /sync/status, чтобы сценарий не зависел от начальной загрузки (SYNC-C0).
const status = await api('GET', '/sync/status', { token: device.token });
@ -153,7 +153,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
);
});
it('[S4/SYNC-E] отметка уволенного сотрудника через sync отклоняется', async () => {
it('[SYNC-E] отметка уволенного сотрудника через sync отклоняется', async () => {
const [employee] = await importEmployees(1);
const dismiss = await api('PATCH', `/employees/${employee!.id}`, {
token: ctx().managerToken,
@ -171,7 +171,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
expect(response.body?.results?.[0]?.status, describeResponse(response)).toBe('rejected');
});
it('[S4/SYNC-F] отметка через sync сохраняет точку устройства; чужая точка в payload отклоняется', async () => {
it('[SYNC-F] отметка через sync сохраняет точку устройства; чужая точка в payload отклоняется', async () => {
const [unitA, unitB] = await createOrgUnits(2);
const [employee] = await importEmployees(1);
const device = await registerDevice(unitA!.id);
@ -202,7 +202,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
).toEqual({ ownOrgUnit: unitA!.id, foreign: 'rejected' });
});
it('[S3/SYNC-G] битая команда в пакете отклоняется по отдельности, остальные применяются (не 500)', async () => {
it('[SYNC-G] битая команда в пакете отклоняется по отдельности, остальные применяются (не 500)', async () => {
const [employee] = await importEmployees(1);
const device = await registerDevice();
const good = command('attendance_event', {
@ -225,7 +225,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
).toEqual({ http: 200, statuses: ['applied', 'rejected'] });
});
it('[S8/SYNC-H] регистрация устройства по cookie с чужим Origin отклоняется (CSRF, 403)', async () => {
it('[SYNC-H] регистрация устройства по cookie с чужим Origin отклоняется (CSRF, 403)', async () => {
const login = await api('POST', '/session', { body: { access_token: ctx().managerToken } });
const cookie =
/(__Host-krona_staff_session=[^;]*)/.exec(login.headers.get('set-cookie') ?? '')?.[1] ?? '';
@ -236,7 +236,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
expect(response.status, describeResponse(response)).toBe(403);
});
it('[K1/SYNC-I] без настроенных токенов анонимный запрос не регистрирует устройство (401)', async () => {
it('[SYNC-I] без настроенных токенов анонимный запрос не регистрирует устройство (401)', async () => {
const response = await api('POST', '/sync/devices', {
base: 'open',
body: {
@ -247,7 +247,7 @@ describe('Офлайн-синхронизация на реальной PostgreS
expect(response.status, describeResponse(response)).toBe(401);
});
it('[S2/SYNC-J] отметка через sync вне окна времени (2001 год) отклоняется, как в POST /attendance/events', async () => {
it('[SYNC-J] отметка через sync вне окна времени (2001 год) отклоняется, как в POST /attendance/events', async () => {
const [employee] = await importEmployees(1);
const device = await registerDevice();
const response = await push(device, [

View file

@ -89,7 +89,7 @@ async function ledgerFor(employeeId: string) {
}
describe('Решения владельца: роли, пакеты зарплаты, согласие на биометрию', () => {
it('[D6/OWN-01] менеджер точки A запускает расчёт для точки B → 403', async () => {
it('[OWN-01] менеджер точки A запускает расчёт для точки B → 403', async () => {
const w = await world(false);
const managerA = await grant('point_manager', [w.unitA.id]);
const batch = await createBatch(managerA, w.unitB.id, w.day);
@ -100,7 +100,7 @@ describe('Решения владельца: роли, пакеты зарпла
expect({ batch: batch.status, legacy: legacy.status }).toEqual({ batch: 403, legacy: 403 });
});
it('[D6/OWN-02] менеджер точки отправляет пакет на согласование → 403', async () => {
it('[OWN-02] менеджер точки отправляет пакет на согласование → 403', async () => {
const w = await world(false);
const managerA = await grant('point_manager', [w.unitA.id]);
const created = await createBatch(managerA, w.unitA.id, w.day);
@ -169,7 +169,7 @@ describe('Решения владельца: роли, пакеты зарпла
}).toEqual({ accrual: true, payout: true, editShift: 409, resubmit: 409 });
});
it('[K19/OWN-07] смена изменена после отправки → подписать нельзя (409), пакет возвращён бухгалтеру', async () => {
it('[OWN-07] смена изменена после отправки → подписать нельзя (409), пакет возвращён бухгалтеру', async () => {
const accountant = await grant('accountant');
const director = await grant('director');
const w = await world();
@ -233,7 +233,7 @@ describe('Решения владельца: роли, пакеты зарпла
});
});
it('[K17/OWN-10] сотрудник без согласия на биометрию → сервер сообщает терминалу «регистрация запрещена»', async () => {
it('[OWN-10] сотрудник без согласия на биометрию → сервер сообщает терминалу «регистрация запрещена»', async () => {
const [employee] = await importEmployees(1);
const response = await api('GET', `/terminal/employees/${employee!.id}/enrollment`, {
token: ctx().terminalToken,
@ -242,7 +242,7 @@ describe('Решения владельца: роли, пакеты зарпла
expect(response.body).toMatchObject({ registration_allowed: false, reason: 'consent_missing' });
});
it('[K17/OWN-11] согласие отозвано → статус для терминала меняется', async () => {
it('[OWN-11] согласие отозвано → статус для терминала меняется', async () => {
const [employee] = await importEmployees(1);
const setConsent = (status: 'granted' | 'revoked') =>
api('PUT', `/employees/${employee!.id}/biometric-consent`, {

View file

@ -27,14 +27,14 @@ function environmentOf(service: string): Record<string, string> {
}
describe('deploy/pilot/compose.yaml', () => {
it('[K1/PILOT-1] все подставляемые переменные обязательны: ${VAR:?сообщение}', () => {
it('[PILOT-1] все подставляемые переменные обязательны: ${VAR:?сообщение}', () => {
const interpolations = [...raw.matchAll(/\$\{([^}]*)\}/g)].map((match) => match[1]!);
expect(interpolations.length).toBeGreaterThan(0);
const optional = interpolations.filter((inner) => !/^[A-Z0-9_]+:\?.+$/.test(inner));
expect(optional, 'переменные без :? — пустое значение молча попадёт в контейнер').toEqual([]);
});
it('[K2/PILOT-2] ни один сервис не запускается с NODE_ENV=development', () => {
it('[PILOT-2] ни один сервис не запускается с NODE_ENV=development', () => {
const offenders = Object.keys(compose.services).filter(
(service) => environmentOf(service).NODE_ENV === 'development',
);

View file

@ -1,287 +0,0 @@
// Недостающие сценарии из аудита владельца (TASK-GROK-2 §3): денежная логика K6–K9,
// удаление точки с устройством (S9), утечка ошибок PostgreSQL (A4), дата расчёта (N12-DATE).
// Каждый тест проверяет ПРАВИЛЬНОЕ поведение: красный = открытый дефект. Где путь
// упирается в K3 (outbox без occurred_at), assert предусловия прямо называет K3.
/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
import pg from 'pg';
import { describe, expect, it } from 'vitest';
import { api, ctx, dbQuery, describeResponse, type ApiResponse } from './harness/client.js';
import { randomUlid, synthetic } from './harness/context.js';
import {
SYNTHETIC_RATE_MINOR,
assignHourly,
createOrgUnits,
daysAgo,
importEmployees,
isoDate,
workedShift,
} from './harness/fixtures.js';
const monthOf = (date: Date) => date.toISOString().slice(0, 7);
async function ledgerTotal(employeeId: string, kinds = ['accrual', 'adjustment']) {
const rows = await dbQuery<{ total: string }>(
`SELECT COALESCE(SUM(amount_minor), 0)::text AS total FROM staff_payroll_ledger
WHERE employee_id = $1 AND kind = ANY($2::text[])`,
[employeeId, kinds],
);
return BigInt(rows[0]!.total);
}
async function confirmShift(sessionId: string) {
const confirm = await api('PATCH', `/work-sessions/${sessionId}`, {
token: ctx().managerToken,
body: { status: 'confirmed' },
});
expect(
confirm.status,
`подтверждение смены (предусловие; падает, пока открыт K3): ${describeResponse(confirm)}`,
).toBe(200);
}
/** Расчёт и утверждение (подпись) ведомости точки за месяц дня `day`. */
async function calculateAndApprove(unitId: string, day: Date): Promise<string> {
const calculate = await api('POST', '/payroll/calculate', {
token: ctx().managerToken,
body: { month: monthOf(day), org_unit_id: unitId },
});
expect(calculate.status, `расчёт (предусловие, K3): ${describeResponse(calculate)}`).toBe(200);
const runId = (calculate.body.run_id ?? calculate.body.id) as string;
const approve = await api('POST', `/payroll/runs/${runId}/approve`, {
token: ctx().managerToken,
});
expect(approve.status, `утверждение (предусловие, K3): ${describeResponse(approve)}`).toBe(200);
return runId;
}
async function payRuleId(code: string): Promise<string> {
const response = await api('GET', '/pay-rules', { token: ctx().managerToken });
expect(response.status, describeResponse(response)).toBe(200);
const rule = (response.body.pay_rules as Array<{ id: string; code: string }>).find(
(item) => item.code === code,
);
expect(rule, `правило ${code} должно быть в пресете`).toBeTruthy();
return rule!.id;
}
/** Признаки ошибки PostgreSQL в теле ответа клиенту (SQLSTATE, имена отношений/столбцов). */
function postgresLeak(response: ApiResponse): string[] {
const leaks: string[] = [];
const body = (response.body ?? {}) as Record<string, unknown>;
if (typeof body.code === 'string' && /^[0-9A-Z]{5}$/.test(body.code)) {
leaks.push(`code=${body.code}`);
}
if (
/relation "|column "|violates|constraint|syntax for type|deduced for parameter/i.test(
response.text,
)
) {
leaks.push(`text=${response.text.slice(0, 120)}`);
}
return leaks;
}
describe('Деньги, S9, A4 и даты на реальной PostgreSQL', () => {
it('[K6/D5] отклонение смены из подписанной ведомости → 409 или сторно (начисление не остаётся)', async () => {
const [unit] = await createOrgUnits(1);
const [employee] = await importEmployees(1);
await assignHourly(employee!.id, unit!.id);
const day = daysAgo(4);
const sessionId = await workedShift(employee!.id, unit!.id, day, 8);
await confirmShift(sessionId);
await calculateAndApprove(unit!.id, day);
expect(await ledgerTotal(employee!.id)).toBe(BigInt(8 * SYNTHETIC_RATE_MINOR));
const reject = await api('PATCH', `/work-sessions/${sessionId}`, {
token: ctx().managerToken,
body: { status: 'rejected', correction_note: synthetic('отказ после подписи') },
});
if (reject.status === 409) return; // смена подписанной ведомости неизменяема — верно
expect(reject.status, describeResponse(reject)).toBe(200);
expect(
await ledgerTotal(employee!.id),
'после отклонения оплаченной смены должно быть сторно: итог начислений 0',
).toBe(0n);
});
it('[K7/D2] повторный импорт книги: итог в реестре равен сумме по книге (две точки в один день)', async () => {
const [employee] = await importEmployees(1);
const date = isoDate(daysAgo(5));
const keyA = `xlsx:payroll:accrual:e2e-${randomUlid()}-unit-a`;
const keyB = `xlsx:payroll:accrual:e2e-${randomUlid()}-unit-b`;
const entry = (externalKey: string, amount: number) => ({
external_key: externalKey,
employee_external_ref: employee!.external_ref,
business_date: date,
kind: 'accrual',
amount_minor: amount,
});
const importBook = (amountA: number, amountB: number) =>
api('POST', '/imports/owner-workbook', {
token: ctx().managerToken,
body: {
source_name: synthetic('import-book'),
payroll_entries: [entry(keyA, amountA), entry(keyB, amountB)],
},
});
const first = await importBook(11_100, 22_200);
expect(first.status, describeResponse(first)).toBeLessThan(300);
const afterFirst = await ledgerTotal(employee!.id);
const second = await importBook(15_500, 22_200);
expect(second.status, describeResponse(second)).toBeLessThan(300);
const afterSecond = await ledgerTotal(employee!.id);
expect({ afterFirst, afterSecond }).toEqual({
afterFirst: 33_300n, // 111,00 ₽ + 222,00 ₽ по книге
afterSecond: 37_700n, // 155,00 ₽ + 222,00 ₽ после исправления суммы точки A
});
});
it('[K8/D1] подписанная ведомость воспроизводится после смены ставки (сумма та же)', async () => {
const [unit] = await createOrgUnits(1);
const [employee] = await importEmployees(1);
await assignHourly(employee!.id, unit!.id);
const day = daysAgo(6);
const sessionId = await workedShift(employee!.id, unit!.id, day, 8);
await confirmShift(sessionId);
const runId = await calculateAndApprove(unit!.id, day);
const signed = await api('GET', `/payroll/runs/${runId}`, { token: ctx().managerToken });
expect(signed.status, describeResponse(signed)).toBe(200);
// Меняем ставку «задним числом» (то же effective_from) после подписи.
const change = await api('PUT', `/employees/${employee!.id}/pay-assignment`, {
token: ctx().managerToken,
body: {
pay_rule_id: await payRuleId('hourly'),
org_unit_id: unit!.id,
rate_minor: SYNTHETIC_RATE_MINOR * 3,
effective_from: '2026-01-01',
},
});
expect(change.status, describeResponse(change)).toBe(200);
// Предполагаемый контракт C4 (NOTES-FOR-EXECUTORS): пересчёт подписанной ведомости
// для проверки по снимку правил и ставок на момент подписи.
const verify = await api('GET', `/payroll/runs/${runId}/verify`, {
token: ctx().managerToken,
});
expect(verify.status, `C4 verify: ${describeResponse(verify)}`).toBe(200);
expect({
matches: verify.body.matches,
recalculated: String(verify.body.recalculated_total_minor),
}).toEqual({ matches: true, recalculated: String(8 * SYNTHETIC_RATE_MINOR) });
});
it('[K9/D3] официант по пресету получает оплату смены из параметров пресета', async () => {
const [unit] = await createOrgUnits(1);
const [employee] = await importEmployees(1);
const shiftRate = 111_100; // синтетические 1 111,00 ₽ за смену (кратно рублю, см. округление)
// Предполагаемый контракт: параметры пресета передаются объектом `params`
// (ключи — param_declarations правила).
const assign = await api('PUT', `/employees/${employee!.id}/pay-assignment`, {
token: ctx().managerToken,
body: {
pay_rule_id: await payRuleId('waiter_upsell'),
org_unit_id: unit!.id,
effective_from: '2026-01-01',
params: {
shift_rate_minor: shiftRate,
percent_bp: 0,
upsell_rate_minor: 0,
avg_check_target_minor: 99_999_999,
avg_check_bonus_minor: 0,
},
},
});
expect(assign.status, describeResponse(assign)).toBe(200);
const saved = await api('GET', `/employees/${employee!.id}/pay-assignment`, {
token: ctx().managerToken,
});
expect(
saved.body.params?.shift_rate_minor,
`параметр пресета должен сохраниться: ${describeResponse(saved)}`,
).toBe(shiftRate);
const day = daysAgo(7);
const sessionId = await workedShift(employee!.id, unit!.id, day, 8);
await confirmShift(sessionId);
await calculateAndApprove(unit!.id, day);
expect(await ledgerTotal(employee!.id)).toBe(BigInt(shiftRate));
});
it('[S9] удаление точки с привязанным устройством: удалена или понятный отказ, не 23502', async () => {
const [unit] = await createOrgUnits(1);
const device = await api('POST', '/sync/devices', {
token: ctx().managerToken,
body: {
device_code: `E2E-${randomUlid().slice(-10)}`,
name: synthetic('Терминал S9'),
org_unit_id: unit!.id,
},
});
expect(device.status, describeResponse(device)).toBe(201);
// Публичного API удаления точки нет, поэтому удаляем так же, как аудит владельца:
// SQL-запросом владельца схемы (мигратор), в tenant-контексте (FORCE RLS).
const migrator = new pg.Client({ connectionString: ctx().migrationDatabaseUrl });
await migrator.connect();
let outcome = 'deleted';
try {
await migrator.query('BEGIN');
await migrator.query("SELECT set_config('app.tenant_id', $1, true)", [ctx().tenantId]);
await migrator.query('DELETE FROM staff_org_units WHERE id = $1', [unit!.id]);
await migrator.query('ROLLBACK');
} catch (error) {
outcome = `${(error as { code?: string }).code} ${(error as Error).message}`;
await migrator.query('ROLLBACK').catch(() => undefined);
} finally {
await migrator.end();
}
// Верно: удалено, либо отказ внешнего ключа 23503 (понятный запрет).
expect(outcome, 'удаление точки с устройством').toMatch(/^(deleted|23503 )/);
});
it('[A4] ответы 500 не содержат кода и текста ошибки PostgreSQL', async () => {
const [unit] = await createOrgUnits(1);
const probes: Array<[string, ApiResponse]> = [
[
'POST /employees',
await api('POST', '/employees', {
token: ctx().managerToken,
body: {
personnel_number: `E2E-${randomUlid().slice(-8)}`,
display_name: synthetic('Сотрудник'),
position: 'E2E-должность',
},
}),
],
[
'POST /payroll/calculate month=2026-13',
await api('POST', '/payroll/calculate', {
token: ctx().managerToken,
body: { month: '2026-13', org_unit_id: unit!.id },
}),
],
];
const leaks = probes
.filter(([, response]) => response.status >= 500)
.map(([name, response]) => ({ name, leaks: postgresLeak(response) }))
.filter((item) => item.leaks.length > 0);
expect(leaks, 'тела 500 с деталями PostgreSQL').toEqual([]);
});
it('[N12-DATE] расчёт с несуществующей датой (month=2026-13, 2026-02-30) → 400', async () => {
const [unit] = await createOrgUnits(1);
const month = await api('POST', '/payroll/calculate', {
token: ctx().managerToken,
body: { month: '2026-13', org_unit_id: unit!.id },
});
const range = await api('POST', '/payroll/calculate', {
token: ctx().managerToken,
body: { from: '2026-02-01', to: '2026-02-30', org_unit_id: unit!.id },
});
expect(
{ month: month.status, range: range.status },
`${describeResponse(month)} | ${describeResponse(range)}`,
).toEqual({ month: 400, range: 400 });
});
});

View file

@ -66,65 +66,40 @@ API пока нет, поэтому сценарии `tests/e2e/30-owner-decisio
сервер хранит только факт согласия. Тот же флаг стоит отдать в `/sync/pull` (employee payload).
Сейчас все OWN красные с `404 Route ... not found` (C1–C3 не реализованы);
OWN-03..09 дополнительно упрутся в K3/N2 (подтверждение смены падает 500).
ID в названиях тестов — двойные «владелец/мой» (`[K3/N2]`, `[D6/OWN-01]`, `[K17/OWN-10]`,
`[K19/OWN-07]`), по таблице TASK-GROK-2 §2 и AUDIT.md.
### C4. Проверочный пересчёт подписанной ведомости (K8/D1)
- `GET /payroll/runs/:id/verify` (право `staff:payroll:read`) →
`200 { "run_id", "stored_total_minor", "recalculated_total_minor", "matches": boolean }`.
- Пересчёт идёт по снимку версий правил, параметров и ставок, действовавших при подписи
(и ревизиям смен), а не по текущим значениям. После смены ставки `matches` остаётся `true`.
### C5. Параметры пресета в назначении оплаты (K9/D3)
- `PUT /employees/:id/pay-assignment` принимает `params: { <key>: integer }`, ключи — из
`param_declarations` выбранного правила (например, `shift_rate_minor`, `percent_bp`,
`upsell_rate_minor`, `avg_check_target_minor`, `avg_check_bonus_minor` у `waiter_upsell`);
неизвестный ключ → 400. `GET .../pay-assignment` возвращает их в `params`.
- Старые поля `rate_minor`/`percent_bp`/`guarantee_minor` можно оставить как сокращения.
OWN-03..09 дополнительно упрутся в N2 (подтверждение смены падает 500).
## 2. Дефекты продукта, найденные сценариями (все красные сейчас)
Команда и фактический вывод — `tests/e2e/evidence/e2e-run.txt`; таблица — `tests/e2e/REPORT.md`.
| ID | Файл | Что исправить |
| ---------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| K4/N1 | `src/portal.ts` POST /employees | `42P08 inconsistent types deduced for parameter $2`: явные `$2::varchar(26)`, `$5::text` или отдельный запрос профессии |
| K3/N2 | `src/portal.ts` PATCH /work-sessions, `src/domain/payroll/service.ts` calculate/approve | `staff_outbox.occurred_at` NULL (23502): передавать `occurred_at` или `DEFAULT now()` новой миграцией |
| K5/N4 | `service.ts` | после N2 проверить: пересекающийся период не должен начислять смену повторно (409 или исключение уже начисленных смен) |
| K12/N3 | push-подписки | allowlist push-сервисов / запрет приватных адресов, `redirect:'manual'`; сейчас сервер подключается к `127.0.0.1` |
| N9 | `push-dispatcher.ts` | `ON CONFLICT ... DO UPDATE SET employee_id` → 409 для чужого endpoint |
| N10 | GET /professions, /org-units | требовать право справочника; терминал сейчас получает 200 |
| N11 | импорт | валидировать `kind` и схему `items` → 400 вместо 500 (23514) |
| N12 | PUT pay-assignment | `additionalProperties:false`, верхние границы сумм |
| N12-DATE | `POST /payroll/calculate` | `month=2026-13` → 500 `22008`; проверять месяц 01–12 → 400 (диапазон `2026-02-30` уже даёт 400) |
| K6/D5 | `portal.ts` PATCH /work-sessions | смена подписанной ведомости: `409`, либо сторно в ledger; сейчас (на fix-live-database) 200 и начисление остаётся |
| K7/D2 | `operations.ts` импорт `payroll_entries` | дельта по сумме всех записей дня, вставка по ключу: две точки за день → 222,00 вместо 333,00 ₽; считать дельту по ключу |
| K8/D1 | расчёт/подпись | снимок правил и ставок в подписанной ведомости; контракт проверки C4 (ниже) |
| K9/D3 | PUT pay-assignment | сохранять `params` по `param_declarations` правила (C5 ниже); сейчас `shift_rate_minor` официанта теряется |
| S9 | миграция 0011 FK устройств | `ON DELETE SET NULL` на составном `(tenant_id, org_unit_id)` обнуляет `tenant_id` → 23502; `SET NULL (org_unit_id)` или RESTRICT |
| A4 | обработчик ошибок | в теле 5xx нет SQLSTATE (`code`) и текста PostgreSQL; подробности только в лог |
| K1/F2 | `config.ts`/`identity.ts` | standalone без токенов не должен выдавать права (процесс без токенов отдаёт 200 на /portal, /payroll, POST /professions) |
| K10/F3 | POST/DELETE /session | в cookie — идентификатор сессии, а не сырой токен; logout отзывает сессию |
| K11/F4 | вход | rate limit (тест ждёт 429 не позже 30 неверных попыток; идёт на отдельном процессе, чтобы лимит не мешал другим сценариям) |
| F7 | POST /attendance/events | использовать `Idempotency-Key` / `staff_idempotency_keys` |
| F10 | `assertSameOrigin` | мутации по cookie без `Origin` отклонять |
| K13/SYNC-A, K13/SYNC-B | `src/domain/sync/service.ts` | устройство не должно выставлять `confirmed`/`approved` (сейчас `applied`) |
| SYNC-C0 | `pull()` bootstrap | `SELECT ... status FROM staff_org_units` — такого столбца нет → 500 на любой начальной загрузке |
| S5/SYNC-C | `pull()` bootstrap | при `has_more=true` отдаётся `next_cursor=latest`, остаток после 100 сущностей теряется; нужен курсор снимка |
| S5/SYNC-D | портал/импорт | изменения вне sync не пишутся в `staff_sync_change_log` → терминал не узнаёт о новых/изменённых сотрудниках |
| S4/SYNC-E | `executeCommand` | проверять `status='active'` сотрудника |
| S4/SYNC-F | `executeCommand` | сохранять `org_unit_id` в `staff_attendance_events`; payload не может переопределить точку устройства |
| S3/SYNC-G | `push()` | ошибки БД одной команды → `rejected` для неё, а не 500 и откат всего пакета |
| S8/SYNC-H | `/sync/devices` | `assertCookieMutationOrigin` как в портале |
| K1/SYNC-I | `requireManagerContext` | без токенов не выдавать права (как F2) |
| S2/SYNC-J | `executeCommand` | окно времени отметки как в POST /attendance/events (−180 дней … +5 мин) |
| SYNC-K | `acknowledge()` | отклонять курсор больше `MAX(cursor_seq)` |
| ID | Файл | Что исправить |
| -------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| N1 | `src/portal.ts` POST /employees | `42P08 inconsistent types deduced for parameter $2`: явные `$2::varchar(26)`, `$5::text` или отдельный запрос профессии |
| N2 | `src/portal.ts` PATCH /work-sessions, `src/domain/payroll/service.ts` calculate/approve | `staff_outbox.occurred_at` NULL (23502): передавать `occurred_at` или `DEFAULT now()` новой миграцией |
| N4 | `service.ts` | после N2 проверить: пересекающийся период не должен начислять смену повторно (409 или исключение уже начисленных смен) |
| N3 | push-подписки | allowlist push-сервисов / запрет приватных адресов, `redirect:'manual'`; сейчас сервер подключается к `127.0.0.1` |
| N9 | `push-dispatcher.ts` | `ON CONFLICT ... DO UPDATE SET employee_id` → 409 для чужого endpoint |
| N10 | GET /professions, /org-units | требовать право справочника; терминал сейчас получает 200 |
| N11 | импорт | валидировать `kind` и схему `items` → 400 вместо 500 (23514) |
| N12 | PUT pay-assignment | `additionalProperties:false`, верхние границы сумм |
| F2 | `config.ts`/`identity.ts` | standalone без токенов не должен выдавать права (процесс без токенов отдаёт 200 на /portal, /payroll, POST /professions) |
| F3 | POST/DELETE /session | в cookie — идентификатор сессии, а не сырой токен; logout отзывает сессию |
| F4 | вход | rate limit (тест ждёт 429 не позже 30 неверных попыток; идёт на отдельном процессе, чтобы лимит не мешал другим сценариям) |
| F7 | POST /attendance/events | использовать `Idempotency-Key` / `staff_idempotency_keys` |
| F10 | `assertSameOrigin` | мутации по cookie без `Origin` отклонять |
| SYNC-A/B | `src/domain/sync/service.ts` | устройство не должно выставлять `confirmed`/`approved` (сейчас `applied`) |
| SYNC-C0 | `pull()` bootstrap | `SELECT ... status FROM staff_org_units` — такого столбца нет → 500 на любой начальной загрузке |
| SYNC-C | `pull()` bootstrap | при `has_more=true` отдаётся `next_cursor=latest`, остаток после 100 сущностей теряется; нужен курсор снимка |
| SYNC-D | портал/импорт | изменения вне sync не пишутся в `staff_sync_change_log` → терминал не узнаёт о новых/изменённых сотрудниках |
| SYNC-E | `executeCommand` | проверять `status='active'` сотрудника |
| SYNC-F | `executeCommand` | сохранять `org_unit_id` в `staff_attendance_events`; payload не может переопределить точку устройства |
| SYNC-G | `push()` | ошибки БД одной команды → `rejected` для неё, а не 500 и откат всего пакета |
| SYNC-H | `/sync/devices` | `assertCookieMutationOrigin` как в портале |
| SYNC-I | `requireManagerContext` | без токенов не выдавать права (как F2) |
| SYNC-J | `executeCommand` | окно времени отметки как в POST /attendance/events (−180 дней … +5 мин) |
| SYNC-K | `acknowledge()` | отклонять курсор больше `MAX(cursor_seq)` |
## 3. deploy/ (K1/PILOT-1, K2/PILOT-2) — Codex
## 3. deploy/ (PILOT-1, PILOT-2) — Codex
- PILOT-1: все подстановки в `deploy/pilot/compose.yaml` → `${VAR:?VAR is required}`
(сейчас 14 без `:?`: пустой `STANDALONE_MANAGER_TOKEN` молча превращает pilot в F2).
@ -143,11 +118,6 @@ ID в названиях тестов — двойные «владелец/мо
- Задаче `docker-build` нужен раннер с меткой `docker-host` (Docker daemon).
Без него задача ждёт в очереди; остальные задачи не блокируются.
- `format` красная, пока не исправлен F14 (23 файла на замер 2026-09-26, в основном `src/`, `docs/`, `tests/unit/`).
- `format` станет зелёной после влития `codex/fix-format-baseline` (проверено на ветке).
- Задача `windows` выключена, пока нет раннера с меткой `windows`: включается переменной
репозитория `KRONA_WINDOWS_RUNNER=true`; для полного e2e нужен секрет
`WINDOWS_E2E_PG_ADMIN_URL` (локальная PostgreSQL 17 на раннере).
- `tests/e2e/evidence/` не хранится в git; в CI это артефакт `e2e-evidence`.
- Реальный Forgejo-раннер мной не запускался (нет API-токена) — не проверено.
## 5. N13 (гонка первого расчёта) и утечка текста ошибок БД
@ -169,23 +139,3 @@ CONFLICT DO NOTHING` со своим `runId` → строки/UPDATE по нес
- Ответы 500 содержат сырой текст ошибки PostgreSQL (например
`null value in column "occurred_at" of relation "staff_outbox" ...`) — клиенту видна
схема БД. Для 5xx отдавать нейтральное сообщение, подробности — только в лог.
## 6. Приёмка веток исполнителей (2026-09-26)
Подробно — `tests/e2e/REPORT.md` и `tests/e2e/report-evidence/acceptance-*.txt`.
- `codex/fix-live-database` (ea68e12, перепроверено на b289dd6): K3/N2 и K4/N1 зелёные на живой PostgreSQL 17.
Дальше по цепочке открылись K5/N4 (196800 вместо 98400 — двойное начисление) и
K6/D5 (отклонение оплаченной смены: 200, начисление осталось). A4 частично: `POST /employees`
больше не 500, но `month=2026-13` по-прежнему отдаёт `code=22008` с текстом.
- `codex/fix-format-baseline` (fd1ec3d): `prettier --check .` чистый. **Но коммит «style»
содержит функциональное исправление Antigravity**: `src/domain/sync/service.ts` и
`tests/unit/sync.test.ts` после нормализации prettier совпадают с
`antigravity/fix-reject-device-shifts` (0 строк diff) и отличаются от 331e490 на 255/139
строк. Изменение поведения стоит вынести в отдельный коммит с объяснением или влить
ветку Antigravity отдельно, иначе история смешивает темы (AGENTS.md).
- `antigravity/fix-reject-device-shifts` (795bba0, перепроверено на 1df2019 — уже на f5ac179):
K13/SYNC-A и K13/SYNC-B зелёные, остальное без изменений.
- Ни одна ветка не влита в основную (f5ac179), поэтому ID из `known-defects.json` не удалены.
- Суммы в тестах кратны рублю: расчёт округляет строку до `rounding_unit_minor`
(по умолчанию 100 коп.). Если округление должно быть другим — это решение продукта, не теста.

View file

@ -1,256 +1,225 @@
# PR: e2e-стенд на реальной PostgreSQL 17 и независимая приёмка (grok/e2e-harness)
База: `codex/bootstrap-platform-foundation` @ `f5ac179` (содержит `331e490`). Ветка перебазирована
без конфликтов. Сравнение:
База: `codex/bootstrap-platform-foundation` @ `778ba2d`. Сравнение:
<https://git.ochenstarik.ru/ochenstarik/krona-staff/compare/codex/bootstrap-platform-foundation...grok/e2e-harness>
Изменены только `tests/e2e/**`, `tests/integration/tenant-isolation.test.ts`,
`.forgejo/workflows/ci.yml`, `scripts/test/**` и одна строка в корневом `.gitignore`
(`tests/e2e/evidence/`, по требованию TASK-GROK-2 §1). `src/`, `apps/`, `migrations/`,
`deploy/`, `package.json` не тронуты. Всё, что требует правки продукта, — в
`.forgejo/workflows/ci.yml`, `scripts/test/**`. `src/`, `apps/`, `migrations/`, `deploy/`,
`package.json` не тронуты. Всё, что требует правки продукта, — в
[`NOTES-FOR-EXECUTORS.md`](NOTES-FOR-EXECUTORS.md).
## Зачем
156 зелёных тестов на поддельной БД не заметили, что создание сотрудника, подтверждение
смены и расчёт зарплаты на реальной PostgreSQL падают всегда. Стенд запускает реальный сервер
под ролью приложения без привилегий на реальной PostgreSQL 17, миграции применяет мигратор без
SUPERUSER, все токены и пароли случайные (`crypto.randomBytes`). Каждый сценарий проверяет
**правильное** поведение: красный = открытый дефект.
156 зелёных тестов на поддельной БД не заметили, что создание сотрудника,
подтверждение смены и расчёт зарплаты на реальной PostgreSQL падают всегда. Этот PR
добавляет стенд, где реальный сервер (`tsx src/server.ts`) работает с реальной
PostgreSQL 17 под ролью приложения без привилегий, миграции применяет мигратор без
SUPERUSER, а все токены и пароли случайные (`crypto.randomBytes`). Каждый сценарий
проверяет **правильное** поведение, поэтому красный цвет означает открытый дефект.
## Что изменилось во втором круге (TASK-GROK-2)
## Источник ID
| Пункт | Что сделано |
| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| §1 | Запуск без `.cmd`-обёрток: `scripts/test/node-commands.mjs` — всегда `process.execPath` + JS-точка входа из `require.resolve` (`vitest.mjs`, `prettier.cjs`); сервер — один процесс `node --import tsx src/server.ts` (без дочернего процесса CLI tsx, чтобы `kill()` под Windows не оставлял сироту). Проверка на Linux — `tests/e2e/harness/node-commands.test.ts` (в `npm test`) |
| §1 | `tests/e2e/evidence/` убран из git и добавлен в `.gitignore`; в CI — артефакт `e2e-evidence`. Разовые доказательства (N5, N13, приёмка) — в `tests/e2e/report-evidence/`, скрипты туда не пишут |
| §1 | Задача `windows` в CI (включается переменной `KRONA_WINDOWS_RUNNER=true`, раннера пока нет) |
| §1 | Перебазирование на `f5ac179` — без конфликтов |
| §2 | Двойные ID `[владелец/мой]` в названиях тестов и ключах `known-defects.json` |
| §3 | Новые сценарии `[K6/D5]`, `[K7/D2]`, `[K8/D1]`, `[K9/D3]`, `[S9]`, `[A4]`, `[N12-DATE]` (`tests/e2e/50-money-and-errors.e2e.ts`), все красные и в `known-defects.json` |
| §4 | Приёмка `antigravity/fix-reject-device-shifts`, `codex/fix-format-baseline`, `codex/fix-live-database` — таблицы ниже |
| — | Синтетическая ставка 123,45 → 123,00 ₽/ч: расчёт округляет строку до рубля (`rounding_unit_minor`), тест не должен зависеть от округления (выяснилось на fix-live-database) |
Файлы владельца (`AUDIT.md`, `live-audit.mjs`, `live-sync.mjs`) до конца работы в
`/workspace/uploads/krona-staff-owner/` не появились. Сценарии написаны по моему
аудиту `2026-09-26_full-project-audit_grok_3e20544.md` (ID `F*`/`N*`) и по коду. ID владельца
K1, K3, K4, K5, K6, K10, K11, K12, S1, S2, S9, A4 **не сопоставлены — не проверено**.
Синхронизация помечена `SYNC-*` (мои ID, вероятно пересекаются с S1–S9 владельца).
Когда файлы владельца будут доступны, достаточно переименовать теги в названиях
тестов (например `[K3/N1]`) и ключи в `known-defects.json`.
## Коммиты
| SHA | Что |
| --------- | ------------------------------------------------------------------------------------- |
| `29fefc1` | `scripts/test/provision-pg.mjs`, `migrate-roundtrip.mjs`: роли как в pilot, roundtrip |
| `88fc749` | N5: очистка tenant-isolation ролью мигратора |
| `d7e9008` | prettier для tenant-isolation.test.ts |
| `cf7f6f4` | стенд e2e: global-setup, клиент, фикстуры, храповик `run-e2e.mjs` |
| `518494d` | сценарии основного API (N1–N4, N9–N12, F2–F4, F7, F10) |
| `32ced4b` | сценарии `/sync/*` (SYNC-A…L) |
| `9bdfb66` | форматирование сгенерированных evidence |
| `f59be3a` | CI: PostgreSQL 17, роли, roundtrip, e2e, docker-build отдельно, SHA-пины |
| `a19c06b` | проверка `deploy/pilot/compose.yaml` (PILOT-1..3) |
| `1e325a6` | сценарии решений владельца (OWN-01..11) + заметки исполнителям |
| `3388b90` | N13: гонка первого расчёта (скрипт и замер) |
| (этот) | REPORT.md и свежие evidence |
## Как запустить
```sh
export E2E_PG_ADMIN_URL=postgres://<admin>:<pw>@127.0.0.1:55433/postgres # только создание ролей и БД
E2E_MIGRATIONS=roundtrip node scripts/test/run-e2e.mjs # храповик known-defects (как в CI)
node scripts/test/run-e2e.mjs --no-known-defects # строго: любой красный = exit 1
./scripts/test/ci-local.sh # локальный эквивалент verify/format/e2e (bash)
# PostgreSQL 17, bootstrap-админ нужен только для создания ролей и БД
export E2E_PG_ADMIN_URL=postgres://<admin>:<pw>@127.0.0.1:55433/postgres
node scripts/test/run-e2e.mjs # храповик known-defects (как в CI)
node scripts/test/run-e2e.mjs --no-known-defects # строго: любой красный = exit 1
E2E_MIGRATIONS=roundtrip node scripts/test/run-e2e.mjs
./scripts/test/ci-local.sh # локальный эквивалент всех задач CI
```
## Таблица по ID (основная ветка f5ac179 + этот стенд)
Роли (`provision-pg.mjs`): `krona_migrator` — NOSUPERUSER NOCREATEDB NOCREATEROLE,
владелец БД и схемы `public`; `krona_staff_app` — NOSUPERUSER NOBYPASSRLS, права выдают
миграции 0003/0004. Пароли случайные, пишутся в env-файл 0600 во временном каталоге,
который удаляется после запуска.
Команда: `./scripts/test/ci-local.sh` (внутри `E2E_MIGRATIONS=roundtrip node scripts/test/run-e2e.mjs`),
2026-09-26 ~15:28 (UTC+7), PostgreSQL 17.11:
## Таблица green/red по ID
Команда: `E2E_MIGRATIONS=roundtrip node scripts/test/run-e2e.mjs` (в составе
`./scripts/test/ci-local.sh`), 2026-09-26 14:33 (UTC+7), PostgreSQL 17.11. Фактический вывод:
[`evidence/e2e-run.txt`](evidence/e2e-run.txt), [`evidence/ci-local.txt`](evidence/ci-local.txt),
JSON — [`evidence/e2e-results.json`](evidence/e2e-results.json), логи серверов — `evidence/server-*.txt`.
```text
== roundtrip OK: rolledBack=11 reapplied=11
Test Files 5 failed | 1 passed (6)
Tests 45 failed | 9 passed (54)
Test Files 4 failed | 1 passed (5)
Tests 38 failed | 9 passed (47)
[run-e2e] OK: стенд работает, все красные сценарии — известные открытые дефекты
```
| ID владельца / мой | Цвет | Фактический вывод (первая строка assert) |
| ---------------------------- | ----- | ------------------------------------------------------------------------------------------------- |
| HARNESS (×5), CTRL (×2) | GREEN | 7/7 passed — стенд и позитивные контроли |
| K1/F2 | RED | `{ portal: 200, payroll: 200, write: 201 }` вместо 401 |
| K1/SYNC-I | RED | анонимная регистрация устройства `HTTP 201` |
| K1/PILOT-1 | RED | 14 подстановок без `:?` (первая `STANDALONE_MANAGER_TOKEN`) |
| K2/PILOT-2 | RED | `NODE_ENV=development` у сервиса `app` |
| K3/N2 | RED | подтверждение смены `HTTP 500 code 23502 null value in column "occurred_at" of "staff_outbox"` |
| K4/N1 | RED | `HTTP 500 code 42P08 inconsistent types deduced for parameter $2` |
| K5/N4 | RED | блокирован K3 (500 на подтверждении) |
| K6/D5 | RED | блокирован K3 (500 на подтверждении) |
| K7/D2 | RED | `afterFirst: 22200, afterSecond: 22200` вместо `33300, 37700` |
| K8/D1 | RED | блокирован K3 (500 на подтверждении) |
| K9/D3 | RED | `params.shift_rate_minor` не сохранён (`HTTP 200`, в `params` нет ключа) |
| K10/F3 | RED | `rawTokenInCookie: true` |
| K11/F4 | RED | все попытки `401`, 429 нет |
| K12/N3 | RED | подписка на `https://127.0.0.1:<port>` `HTTP 201`, 1 входящее соединение |
| K13/SYNC-A, K13/SYNC-B | RED | `upsert_work_session` / `upsert_timesheet_entry` → `status: applied` |
| K17/OWN-10, K17/OWN-11 | RED | `404 Route GET .../terminal/employees/:id/enrollment` / `PUT .../biometric-consent` (нет API, C3) |
| K19/OWN-07 | RED | `404 Route POST /access-grants` (нет API, C1/C2) |
| D6/OWN-01, D6/OWN-02 | RED | `404 Route POST /access-grants` (нет API, C1) |
| OWN-03..06, OWN-08, OWN-09 | RED | `404 Route POST /access-grants` (нет API, C1/C2) |
| S2/SYNC-J | RED | отметка 2001 года → `status: applied` |
| S3/SYNC-G | RED | `HTTP 500 code 22007` на весь пакет |
| S4/SYNC-E | RED | отметка уволенного → `applied` |
| S4/SYNC-F | RED | `{ ownOrgUnit: null, foreign: "applied" }` |
| S5/SYNC-C | RED | `HTTP 500 code 42703 column "status" does not exist` (блокирован SYNC-C0) |
| S5/SYNC-D | RED | изменение из портала не видно в инкрементальном pull |
| S8/SYNC-H | RED | регистрация устройства по cookie с чужим Origin `HTTP 201` |
| S9 | RED | удаление точки с устройством: `23502 null value in column "tenant_id"` |
| A4 | RED | 2 тела 500 с SQLSTATE/текстом PostgreSQL (`POST /employees` 42P08, `month=2026-13` 22008) |
| N9 | RED | чужой push-endpoint перепривязан `HTTP 201` |
| N10 | RED | терминал: `{ professions: 200, units: 200 }` |
| N11 | RED | импорт с неверным kind `HTTP 500 code 23514` |
| N12 | RED | лишнее поле и нереальная сумма → `HTTP 200` |
| N12-DATE | RED | `month=2026-13` → `HTTP 500 code 22008`; `2026-02-30` уже 400 |
| F7 | RED | повтор Idempotency-Key создал второе событие |
| F10 | RED | мутация по cookie без Origin `HTTP 201` |
| SYNC-C0 (нет ID у владельца) | RED | bootstrap pull `HTTP 500 code 42703 column "status" does not exist` |
| SYNC-K (нет ID у владельца) | RED | ack курсора из будущего `HTTP 200` |
| SYNC-L | GREEN | отозванное устройство получает 403 (позитивный контроль) |
| PILOT-3 | GREEN | у `app` нет учётных данных мигратора |
| N5 (tenant-isolation) | GREEN | в `npm run check` с тестовой БД: `Test Files 20 passed (20)`, `Tests 196 passed (196)` |
| N13 (скрипт, не vitest) | — | не воспроизведено: 0 из 30 попыток при 10/25/50 (обход K3 в одноразовой БД), см. ниже |
| ID | Цвет | Что проверяется (правильное поведение) | Фактически (из вывода) |
| ------------ | ----- | -------------------------------------------------------------------- | ----------------------------------------------------------------- |
| HARNESS (×5) | GREEN | live/ready, PG17, app-роль без SUPERUSER/BYPASSRLS, токены, терминал | 5/5 passed |
| CTRL (×2) | GREEN | RBAC терминала/сотрудника, уволенный теряет доступ | 2/2 passed |
| N1 | RED | POST /employees → 201 | 500 `42P08 inconsistent types deduced for parameter $2` |
| N2 | RED | подтверждение смены, расчёт, утверждение → 200 | 500 `23502 null value in column "occurred_at" of "staff_outbox"` |
| N4 | RED | пересекающиеся расчёты не начисляют смену дважды | блокирован N2 (500 23502 на предусловии) — сам N4 **не проверен** |
| N3 | RED | push на внутренний адрес отклоняется, соединений нет | 201 и 1 входящее соединение на 127.0.0.1 |
| N9 | RED | чужой push-endpoint не перепривязывается | 201 |
| N10 | RED | терминал не читает справочники (403) | professions 200, org-units 200 |
| N11 | RED | импорт с неверным kind → 400 | 500 `23514` check constraint staff_payroll_ledger |
| N12 | RED | лишние поля/нереальные суммы → 400 | 200 |
| F2 | RED | процесс без токенов не даёт прав анониму (401) | /portal 200, /payroll 200, POST /professions 201 |
| F3 | RED | cookie без сырого токена, logout отзывает | `rawTokenInCookie: true` |
| F4 | RED | 429 не позже 30 неверных входов | все 401, 429 нет |
| F7 | RED | повтор Idempotency-Key с другим телом не создаёт событие | второе событие создано (201) |
| F10 | RED | мутация по cookie без Origin → 403 | 201 |
| SYNC-A | RED | устройство не подтверждает смену | `applied` |
| SYNC-B | RED | устройство не утверждает табель | `applied` |
| SYNC-C0 | RED | bootstrap pull без курсора → 200 | 500 `42703 column "status" does not exist` (новая находка) |
| SYNC-C | RED | bootstrap >100 сущностей постранично без потерь | 500 42703 (блокирован SYNC-C0) |
| SYNC-D | RED | изменения из портала видны в инкрементальном pull | изменения нет |
| SYNC-E | RED | отметка уволенного через sync отклоняется | `applied` |
| SYNC-F | RED | точка устройства сохраняется, чужая точка в payload не принимается | `applied`, точка не сохранена |
| SYNC-G | RED | битая команда отклоняется по отдельности | 500 `22007` на весь пакет |
| SYNC-H | RED | регистрация устройства по cookie с чужим Origin → 403 | 201 |
| SYNC-I | RED | без токенов анонимно устройство не регистрируется | 201 |
| SYNC-J | RED | отметка 2001 года через sync отклоняется | `applied` |
| SYNC-K | RED | ack курсора из будущего → 400 | 200 |
| SYNC-L | GREEN | отозванное устройство не синхронизируется (403) | 403 (позитивный контроль) |
| OWN-01 | RED | менеджер точки A считает зарплату точки B → 403 | 404 `Route POST:/api/v1/staff/access-grants not found` (нет API) |
| OWN-02 | RED | менеджер отправляет пакет на согласование → 403 | 404 access-grants (нет API) |
| OWN-03 | RED | бухгалтер отправляет пакет → успех, каждому директору 1 уведомление | 404 access-grants (нет API) |
| OWN-04 | RED | бухгалтер подписывает пакет → 403 | 404 access-grants (нет API) |
| OWN-05 | RED | до подписи в ledger нет начислений/выплат | 404 access-grants (нет API) |
| OWN-06 | RED | подпись директора → ledger, пакет и смены неизменяемы | 404 access-grants (нет API) |
| OWN-07 | RED | смена изменена после отправки → 409, пакет у бухгалтера | 404 access-grants (нет API) |
| OWN-08 | RED | возврат с комментарием → пакет у бухгалтера, комментарий сохранён | 404 access-grants (нет API) |
| OWN-09 | RED | смена сотрудника A в точке B → в расчёт точки B | 404 access-grants (нет API) |
| OWN-10 | RED | без согласия на биометрию → терминалу «регистрация запрещена» | 404 `GET .../terminal/employees/:id/enrollment` (нет API) |
| OWN-11 | RED | согласие отозвано → статус для терминала меняется | 404 `PUT .../biometric-consent` (нет API) |
| PILOT-1 | RED | все подстановки в pilot compose — `${VAR:?}` | 14 переменных без `:?` (первая — `STANDALONE_MANAGER_TOKEN`) |
| PILOT-2 | RED | нет `NODE_ENV=development` | сервис `app` |
| PILOT-3 | GREEN | у `app` нет кредов мигратора | passed |
| N13 | — | гонка первого расчёта (скрипт, не vitest) | см. ниже: как есть 15/15 → 500 (N2); с обходом N2 — 0/30 гонок |
| N5 | GREEN | tenant-isolation на живой БД | до: FAIL; после: 2/2 прогона exit=0 (см. ниже) |
Сверх таблицы TASK-GROK-2 §2 (по тексту AUDIT.md): K1/SYNC-I (анонимный доступ без токенов на
`/sync`), K1/PILOT-1 (подстановки без `:?` названы в K1), K2/PILOT-2 (development в пилоте — суть K2).
Предполагаемые контракты для OWN-01..11 (C1 роли точки/бухгалтера/директора, C2 пакет
зарплаты и согласование, C3 согласие на биометрию) описаны в `NOTES-FOR-EXECUTORS.md` §1.
## Приёмка веток исполнителей (TASK-GROK-2 §4)
### Механизм для красных сценариев (храповик)
Способ: `git worktree add --detach <dir> origin/<ветка>`, поверх — `tests/e2e/` и `scripts/test/`
из этой ветки (в ветки исполнителей ничего не коммитилось), затем
`E2E_MIGRATIONS=roundtrip E2E_DATABASE_NAME=krona_staff_acc node scripts/test/run-e2e.mjs`.
«Было» — основная ветка `f5ac179` с тем же стендом (45 red / 9 green, храповик OK). Полные таблицы —
`tests/e2e/report-evidence/acceptance-*.txt`. Ни одна ветка не влита в основную
(`git merge-base --is-ancestor` → нет), поэтому `known-defects.json` не сокращён.
Выбран список `tests/e2e/known-defects.json` и одна задача `e2e`, а не отдельная
задача «allowed to fail». Причины: задача с `continue-on-error` зеленеет при любом
сбое, включая сломанный стенд, а храповик различает три случая: (1) стенд сломан
(`[HARNESS]`/`[CTRL]` красные или тест без ID) → exit 1; (2) новый красный ID не из
списка (регрессия) → exit 1; (3) ID из списка стал зелёным → exit 1 с просьбой
вычеркнуть его (исправление фиксируется, откат снова станет красным). Строгий режим
`--no-known-defects` показывает полную картину.
### `codex/fix-live-database` @ ea68e12, перепроверено на b289dd6
## N5: tenant-isolation до/после
До (база 778ba2d, `DATABASE_TEST_URL` = роль приложения), [`evidence/n5-before.txt`](evidence/n5-before.txt):
```text
== roundtrip OK: rolledBack=11 reapplied=11
Tests 41 failed | 13 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K3/N2 | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K4/N1 | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
FAIL tests/integration/tenant-isolation.test.ts > PostgreSQL tenant isolation
error: permission denied for table staff_employees
❯ tests/integration/tenant-isolation.test.ts:40:7
Test Files 1 failed (1)
Tests 1 passed (1)
exit=1
```
| ID | Было | Стало | Доказательство |
| ---------- | ---- | ----- | ------------------------------------------------------------------------------------------------------------ |
| K3/N2 | RED | GREEN | было: подтверждение смены `500 23502 occurred_at`; стало: passed (8 ч × 123,00 ₽ = 98400 в ledger) |
| K4/N1 | RED | GREEN | было: `500 42P08`; стало: passed (201, сотрудник в БД) |
| K13/SYNC-A | RED | GREEN | было: `upsert_work_session → applied`; стало: passed (см. находку по fd1ec3d) |
| K13/SYNC-B | RED | GREEN | было: `upsert_timesheet_entry → applied`; стало: passed |
| K5/N4 | RED | RED | было: блокирован K3; стало: `смена должна быть начислена ровно один раз: expected 196800n to be 98400n` |
| K6/D5 | RED | RED | было: блокирован K3; стало: `после отклонения оплаченной смены должно быть сторно: expected 98400n to be 0n` |
| K8/D1 | RED | RED | было: блокирован K3; стало: `C4 verify: HTTP 404 Route GET .../payroll/runs/:id/verify not found` |
| A4 | RED | RED | было: 2 утечки; стало: 1 — `POST /payroll/calculate month=2026-13` → `code=22008` |
| F14 | RED | GREEN | `prettier --check .` → `All matched files use Prettier code style!` (без оверлея evidence) |
Ветку обновили force-push во время приёмки (`ea68e12` → `b289dd6`, изменён только
`tests/integration/live-postgres-remediation.test.ts`); повторный прогон на `b289dd6` дал те же
41 red / 13 green и ту же таблицу.
Вердикт: K3 и K4 исправлены (подтверждено на живой PostgreSQL 17, миграции roundtrip). После влития
убрать `K3/N2`, `K4/N1` из `known-defects.json`. Цепочка расчёта теперь доходит до денежных дефектов:
K5 и K6 подтверждены по существу.
### `codex/fix-format-baseline` @ fd1ec3d
После (очистка соединением мигратора `DATABASE_TEST_MIGRATION_URL`, с
`app.tenant_id` из-за FORCE RLS, до и после теста), [`evidence/n5-after.txt`](evidence/n5-after.txt):
```text
Tests 43 failed | 11 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
$ node node_modules/prettier/bin/prettier.cjs --check .
All matched files use Prettier code style!
== run 1 ... Test Files 1 passed (1) Tests 1 passed (1) exit=0
== run 2 ... Test Files 1 passed (1) Tests 1 passed (1) exit=0
```
| ID | Было | Стало | Доказательство |
| ---------- | -------------- | ----- | ------------------------------------------------- |
| F14 | RED (23 файла) | GREEN | `All matched files use Prettier code style!` |
| K13/SYNC-A | RED | GREEN | было: `applied`; стало: passed |
| K13/SYNC-B | RED | GREEN | было: `applied`; стало: passed |
| остальные | без изменений | — | compare по `e2e-results.json`: других отличий нет |
**Находка:** «style»-коммит `fd1ec3d` содержит функциональное исправление Antigravity.
После нормализации prettier `src/domain/sync/service.ts` отличается от `331e490` на 255 строк diff
и совпадает с `antigravity/fix-reject-device-shifts` (0 строк); `tests/unit/sync.test.ts` — 139 и 0.
Изменение поведения скрыто в коммите форматирования — смешение тем (AGENTS.md).
### `antigravity/fix-reject-device-shifts` @ 795bba0, перепроверено на 1df2019
```text
Tests 43 failed | 11 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
```
| ID | Было | Стало | Доказательство |
| ---------- | ---- | ----- | ------------------------------------------------------- |
| K13/SYNC-A | RED | GREEN | было: `upsert_work_session → applied`; стало: passed |
| K13/SYNC-B | RED | GREEN | было: `upsert_timesheet_entry → applied`; стало: passed |
| остальные | — | — | других отличий нет |
Ветку перебазировали на `f5ac179` во время приёмки (`795bba0` → `1df2019`); повторный прогон
на `1df2019`: те же 43 red / 11 green, отличия только K13/SYNC-A/B.
Вердикт: K13 исправлен. Убрать `K13/SYNC-A`,
`K13/SYNC-B` отдельным коммитом после влития (и после исправления очистки в
`sync-rejection.test.ts`, TASK-GROK-2 §4.1).
## Windows
- Запуск стенда переписан без `npx` и `node_modules/.bin` (раньше `spawn('npx')` и
`spawn('.../.bin/tsx')` падали на Windows с `ENOENT`). Проверка на Linux:
`tests/e2e/harness/node-commands.test.ts` — 8 тестов: команды начинаются с `process.execPath`,
без `.cmd`/`.bin`/`npx`, файлы существуют; под `win32` дочерний процесс получает
`SystemRoot`/`TEMP`, секреты родителя не наследуются.
- **Реальный запуск на Windows 11 — не проверено**: Windows-раннера у git.ochenstarik.ru нет.
В CI добавлена задача `windows` (`runs-on: windows`), включаемая переменной
`KRONA_WINDOWS_RUNNER=true`; для полного e2e нужен секрет `WINDOWS_E2E_PG_ADMIN_URL`.
- `scripts/test/ci-local.sh` — bash, на Windows не предназначен (под Windows запускать
`node scripts/test/run-e2e.mjs`).
## Evidence вне git
```text
$ E2E_MIGRATIONS=roundtrip node scripts/test/run-e2e.mjs # (повторный прогон)
[run-e2e] OK: стенд работает, все красные сценарии — известные открытые дефекты
$ git status --porcelain
# (пусто)
```
## N5 (tenant-isolation)
До (`778ba2d`, очистка ролью приложения) — [`report-evidence/n5-before.txt`](report-evidence/n5-before.txt):
`error: permission denied for table staff_employees`, `exit=1`. После (очистка ролью мигратора с
`app.tenant_id`) — [`report-evidence/n5-after.txt`](report-evidence/n5-after.txt): 2 прогона, `exit=0`.
На `f5ac179`: `npm run check` с тестовой БД — `Test Files 20 passed (20)`, `Tests 196 passed (196)`.
Полный `npm run check` с тестовой БД (задача verify в `ci-local.sh`):
`Test Files 19 passed (19)`, `Tests 188 passed (188)`.
## CI (`.forgejo/workflows/ci.yml`)
- `verify`: `postgres:17-alpine@sha256:…`, роли как в pilot (мигратор NOSUPERUSER, app NOBYPASSRLS),
миграции `up → откат всех 11 → up → up`, `npm run check` с тестовой БД, `npm audit`.
- `format`: отдельно (F14 красный до влития `codex/fix-format-baseline`).
- `e2e`: PostgreSQL 17, `E2E_MIGRATIONS=roundtrip`, храповик; evidence — артефакт `e2e-evidence`
(`actions/upload-artifact@ea165f8… # v4.6.2`, Forgejo 9.0.3).
- `windows`: выключена без раннера (см. выше). `docker-build`: метка `docker-host`, `needs: verify`, только push.
- Все actions закреплены SHA (F13), SHA совпадают на github.com и code.forgejo.org.
- `verify`: сервис `postgres:17-alpine@sha256:18cfe3ef…` (bootstrap-пользователь только
для provision), роли как в pilot (мигратор без SUPERUSER, app без BYPASSRLS),
миграции `up → откат всех 11 → up → up (no-op)`, `npm run check` с
`DATABASE_TEST_URL`/`DATABASE_TEST_MIGRATION_URL` (tenant-isolation реально
выполняется), `npm audit --audit-level=high`.
- `format`: отдельно, чтобы F14 (23 файла вне моих путей) не маскировал остальное.
- `e2e`: тот же сервис PostgreSQL 17, `E2E_MIGRATIONS=roundtrip`, храповик.
- `docker-build`: отдельная задача на метке `docker-host`, `needs: verify`, только push.
- Все actions закреплены SHA (F13): `actions/checkout@11d5960a… # v4.4.0`,
`actions/setup-node@49933ea5… # v4.4.0` (SHA получены `git ls-remote`, совпадают на
github.com и code.forgejo.org).
Механизм красных сценариев — храповик `known-defects.json`, а не «allowed to fail»: сломанный стенд,
новый красный ID или исправленный, но не вычеркнутый ID делают задачу `e2e` красной.
Валидация: `actionlint -config-file actionlint.yaml .forgejo/workflows/ci.yml` (1.7.12, метки
`docker`, `docker-host`, `windows`) → 0 замечаний. Локально `./scripts/test/ci-local.sh`:
Валидация: `actionlint -config-file actionlint.yaml .forgejo/workflows/ci.yml` (1.7.12,
метки `docker`, `docker-host`) → 0 замечаний, exit 0. Локальный эквивалент
`./scripts/test/ci-local.sh` ([`evidence/ci-local.txt`](evidence/ci-local.txt)):
```text
::: [migrate-roundtrip] OK (== roundtrip OK: rolledBack=11 reapplied=11)
::: [check] OK (Test Files 20 passed (20), Tests 196 passed (196))
::: [audit] OK (found 0 vulnerabilities)
::: [format-check] FAIL (Code style issues found in 23 files — F14)
::: [e2e] OK (Tests 45 failed | 9 passed (54), храповик OK)
::: [migrate-roundtrip] OK (== roundtrip OK: rolledBack=11 reapplied=11)
::: [check] OK (Test Files 19 passed, Tests 188 passed)
::: [audit] OK (found 0 vulnerabilities)
::: [format-check] FAIL exit=1 (Code style issues found in 23 files — F14)
::: [e2e] OK (храповик: все красные — известные дефекты)
=== итог: status=1 (только из-за format)
```
## N13 (гонка первого расчёта)
## Проверка pilot compose (PILOT-1..3)
`node scripts/test/n13-race.mjs` (10/25/50 параллельных первых расчётов × 5 попыток) —
[`report-evidence/n13-race.txt`](report-evidence/n13-race.txt): как есть 15/15 → 500 (K3); с обходом K3
в одноразовой БД — 0 некорректных из 30 (с подтверждённой сменой и без). Не воспроизведено, как и у
владельца; вероятная причина (гипотеза по коду) — upsert `ensureDefaultPayRules` сериализует расчёты
тенанта. Прогон до перебазирования, на `778ba2d`.
`tests/e2e/40-compose-pilot.e2e.ts` читает `deploy/pilot/compose.yaml` (только чтение).
Положен в `tests/e2e/`, а не рядом с существующим тестом корневого compose
(`tests/unit/deployment.test.ts`), потому что `tests/unit/` вне разрешённых путей.
Результат: PILOT-1 RED (14 подстановок без `:?`), PILOT-2 RED (`NODE_ENV: development` в
`app`; конфликт с запретом standalone в production в `config.ts` описан в заметках),
PILOT-3 GREEN.
## N13: гонка первого расчёта
`node scripts/test/n13-race.mjs` — 10/25/50 параллельных первых `POST /payroll/calculate`,
5 попыток на размер, каждая попытка на новой точке. Вывод: [`evidence/n13-race.txt`](evidence/n13-race.txt).
```text
[n13] ИТОГ mode=as-is sessions=false: попыток 15, некорректных 15 (все 500: N2, occurred_at)
[n13] ИТОГ mode=n2-bypass sessions=false: попыток 15, некорректных 0 (200×N, 1 run_id, 1 расчёт)
[n13] ИТОГ mode=n2-bypass sessions=true: попыток 15, некорректных 0 (с подтверждённой сменой, db_lines=1)
```
`n2-bypass` — диагностика: в одноразовой БД скрипта мигратор ставит
`DEFAULT now()` для `staff_outbox.occurred_at`; продукт и миграции не меняются.
Вердикт: **гонка не воспроизведена (0 из 30 попыток при 10/25/50)**, совпадает с
«N13 not reproduced» владельца. Вероятная причина (из кода, отдельно не проверено):
upsert `ensureDefaultPayRules` в начале расчёта случайно сериализует расчёты одного
тенанта. Окно в коде остаётся — рекомендация в заметках §5.
## Не проверено
- Реальный Forgejo-раннер (workflow выполнялся только локальным эквивалентом), `docker build`.
- Запуск на Windows 11 (раннера нет); Windows-only: DPAPI, ACL каталога данных, установщик, WinUI,
named pipe — см. тесты Codex в `apps/KronaStaffTerminal.Tests`.
- OWN-01..11, K8 (C4) и K9 (C5) проверяют предполагаемые контракты из NOTES.
- K5/N4, K6/D5, K8/D1 на основной ветке блокированы K3; по существу проверены только на
`codex/fix-live-database`.
- S9 проверен удалением SQL-запросом мигратора (публичного API удаления точки нет).
- Реальный Forgejo-раннер: workflow не запускался на сервере (нет API-токена, задачи
выполнены локально эквивалентным скриптом). Раннера с меткой `docker-host` может не быть.
- `docker build` не запускался (на этой машине нет Docker).
- Windows-only: DPAPI, ACL каталога данных, установщик, WinUI, реальный named pipe —
не проверено; см. тесты Codex в `apps/KronaStaffTerminal.Tests`.
- Сопоставление с ID владельца K1/K3/K4/K5/K6/K10/K11/K12, S1/S2/S9, A4 и сверка с его
`live-audit.mjs`/`live-sync.mjs` — файлов нет.
- N4 и SYNC-C по существу: блокированы N2 и SYNC-C0 соответственно.
- OWN-01..11 проверяют предполагаемый контракт; реальный контракт Codex может отличаться.
- Причина невоспроизводимости N13 — гипотеза по коду.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,669 @@
{
"numTotalTestSuites": 10,
"numPassedTestSuites": 2,
"numFailedTestSuites": 8,
"numPendingTestSuites": 0,
"numTotalTests": 47,
"numPassedTests": 9,
"numFailedTests": 38,
"numPendingTests": 0,
"numTodoTests": 0,
"snapshot": {
"added": 0,
"failure": false,
"filesAdded": 0,
"filesRemoved": 0,
"filesRemovedList": [],
"filesUnmatched": 0,
"filesUpdated": 0,
"matched": 0,
"total": 0,
"unchecked": 0,
"uncheckedKeysByFile": [],
"unmatched": 0,
"updated": 0,
"didUpdate": false
},
"startTime": 1790408012144,
"success": false,
"testResults": [
{
"assertionResults": [
{
"ancestorTitles": ["HARNESS: реальный сервер + PostgreSQL 17"],
"fullName": "HARNESS: реальный сервер + PostgreSQL 17 [HARNESS] сервер отвечает live/ready (ready проверяет БД)",
"status": "passed",
"title": "[HARNESS] сервер отвечает live/ready (ready проверяет БД)",
"duration": 32.192098,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["HARNESS: реальный сервер + PostgreSQL 17"],
"fullName": "HARNESS: реальный сервер + PostgreSQL 17 [HARNESS] БД: PostgreSQL 17, приложение под ролью без SUPERUSER/BYPASSRLS, мигратор без SUPERUSER",
"status": "passed",
"title": "[HARNESS] БД: PostgreSQL 17, приложение под ролью без SUPERUSER/BYPASSRLS, мигратор без SUPERUSER",
"duration": 14.342552000000012,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["HARNESS: реальный сервер + PostgreSQL 17"],
"fullName": "HARNESS: реальный сервер + PostgreSQL 17 [HARNESS] миграции применены мигратором, app-роль не видит schema_migrations",
"status": "passed",
"title": "[HARNESS] миграции применены мигратором, app-роль не видит schema_migrations",
"duration": 14.26604900000001,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["HARNESS: реальный сервер + PostgreSQL 17"],
"fullName": "HARNESS: реальный сервер + PostgreSQL 17 [HARNESS] токены: без токена 401, случайный токен 401, manager-токен 200",
"status": "passed",
"title": "[HARNESS] токены: без токена 401, случайный токен 401, manager-токен 200",
"duration": 13.863121000000007,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["HARNESS: реальный сервер + PostgreSQL 17"],
"fullName": "HARNESS: реальный сервер + PostgreSQL 17 [HARNESS] терминал: отметка сотрудника из импорта принимается (201)",
"status": "passed",
"title": "[HARNESS] терминал: отметка сотрудника из импорта принимается (201)",
"duration": 24.62379200000001,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["HARNESS: реальный сервер + PostgreSQL 17"],
"fullName": "HARNESS: реальный сервер + PostgreSQL 17 [CTRL] RBAC: терминал не видит портал и не создаёт сотрудников; сотрудник видит только себя",
"status": "passed",
"title": "[CTRL] RBAC: терминал не видит портал и не создаёт сотрудников; сотрудник видит только себя",
"duration": 23.691180000000003,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["HARNESS: реальный сервер + PostgreSQL 17"],
"fullName": "HARNESS: реальный сервер + PostgreSQL 17 [CTRL] уволенный сотрудник теряет доступ (401)",
"status": "passed",
"title": "[CTRL] уволенный сотрудник теряет доступ (401)",
"duration": 23.254977999999994,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
}
],
"startTime": 1790408019083,
"endTime": 1790408019229.255,
"status": "passed",
"message": "",
"name": "/workspace/krona-staff/tests/e2e/00-harness.e2e.ts"
},
{
"assertionResults": [
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [N1] менеджер создаёт сотрудника через POST /employees → 201",
"status": "failed",
"title": "[N1] менеджер создаёт сотрудника через POST /employees → 201",
"duration": 38.316193,
"failureMessages": [
"AssertionError: HTTP 500 {\"statusCode\":500,\"code\":\"42P08\",\"error\":\"Internal Server Error\",\"message\":\"inconsistent types deduced for parameter $2\"}: expected 500 to be 201 // Object.is equality\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:55:57\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [N2] подтверждение смены, расчёт и утверждение зарплаты проходят (200) и начисляют 8 ч × ставка",
"status": "failed",
"title": "[N2] подтверждение смены, расчёт и утверждение зарплаты проходят (200) и начисляют 8 ч × ставка",
"duration": 110.697531,
"failureMessages": [
"AssertionError: подтверждение смены: HTTP 500 {\"statusCode\":500,\"code\":\"23502\",\"error\":\"Internal Server Error\",\"message\":\"null value in column \\\"occurred_at\\\" of relation \\\"staff_outbox\\\" violates not-null constraint\"}: expected 500 to be 200 // Object.is equality\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:73:81\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [N4] пересекающиеся расчёты не начисляют одну смену дважды",
"status": "failed",
"title": "[N4] пересекающиеся расчёты не начисляют одну смену дважды",
"duration": 66.33918700000004,
"failureMessages": [
"AssertionError: подтверждение смены (предусловие, см. N2): HTTP 500 {\"statusCode\":500,\"code\":\"23502\",\"error\":\"Internal Server Error\",\"message\":\"null value in column \\\"occurred_at\\\" of relation \\\"staff_outbox\\\" violates not-null constraint\"}: expected 500 to be 200 // Object.is equality\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:104:7\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [N3] push-подписка на внутренний адрес отклоняется, сервер не подключается к 127.0.0.1",
"status": "failed",
"title": "[N3] push-подписка на внутренний адрес отклоняется, сервер не подключается к 127.0.0.1",
"duration": 2544.330582,
"failureMessages": [
"AssertionError: подписка: HTTP 201 {\"id\":\"01M3EA4FH3FG4Q3YEKXYQ8Y4Q5\",\"endpoint\":\"https://127.0.0.1:36027/e2e-internal-admin\"}: expected { status: 201, connections: 1 } to deeply equal { status: toSatisfy{…}, …(1) }\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:161:9\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [N9] чужой push-endpoint нельзя перепривязать к другому сотруднику",
"status": "failed",
"title": "[N9] чужой push-endpoint нельзя перепривязать к другому сотруднику",
"duration": 44.48753099999976,
"failureMessages": [
"AssertionError: HTTP 201 {\"id\":\"01M3EA4J0JSPFRDF22J6E2CEY1\",\"endpoint\":\"https://fcm.googleapis.com/fcm/send/e2e-d464594734e6ddf8569ec571f5832dbf\"}: expected { status: 201, …(1) } to deeply equal { status: toSatisfy{…}, …(1) }\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:191:7\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [N12] PUT pay-assignment отвергает лишние поля и нереальные суммы (400)",
"status": "failed",
"title": "[N12] PUT pay-assignment отвергает лишние поля и нереальные суммы (400)",
"duration": 31.35817700000007,
"failureMessages": [
"AssertionError: HTTP 200 {\"id\":\"01M3EA4J1PHXWHFMAMYYVRMK3E\",\"employee_id\":\"01M3EA4J151B1H9D5AKAR29AN9\",\"org_unit_id\":null,\"pay_rule_id\":\"01M3EA4FCDRQSS6V8H5Q6XS615\",\"pay_rule_code\":\"hourly\",\"pay_rule_name\":\"Почасовая (стажёр, дополнительный сотрудник)\",\"rate_minor\":12345,\"percent_bp\":0,\"guarantee_minor\":0,\"pool_weight_bp\":0… | HTTP 200 {\"id\":\"01M3EA4J1PHXWHFMAMYYVRMK3E\",\"employee_id\":\"01M3EA4J151B1H9D5AKAR29AN9\",\"org_unit_id\":null,\"pay_rule_id\":\"01M3EA4FCDRQSS6V8H5Q6XS615\",\"pay_rule_code\":\"hourly\",\"pay_rule_name\":\"Почасовая (стажёр, дополнительный сотрудник)\",\"rate_minor\":9007199254740991,\"percent_bp\":0,\"guarantee_minor\":900719925…: expected { extra: 200, huge: 200 } to deeply equal { extra: 400, huge: 400 }\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:215:7\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [N10] терминальный токен не читает справочники профессий и точек (403)",
"status": "failed",
"title": "[N10] терминальный токен не читает справочники профессий и точек (403)",
"duration": 4.364047000000028,
"failureMessages": [
"AssertionError: expected { professions: 200, units: 200 } to deeply equal { professions: 403, units: 403 }\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:224:70\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [F2] standalone без токенов не выдаёт права менеджера анонимному запросу (401)",
"status": "failed",
"title": "[F2] standalone без токенов не выдаёт права менеджера анонимному запросу (401)",
"duration": 19.630533999999898,
"failureMessages": [
"AssertionError: expected { portal: 200, payroll: 200, …(1) } to deeply equal { portal: 401, payroll: 401, …(1) }\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:237:85\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [F3] cookie сессии не содержит сырой токен и отзывается при выходе",
"status": "failed",
"title": "[F3] cookie сессии не содержит сырой токен и отзывается при выходе",
"duration": 8.088321000000178,
"failureMessages": [
"AssertionError: expected { rawTokenInCookie: true, …(1) } to deeply equal { rawTokenInCookie: false, …(1) }\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:255:91\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [F10] мутация по cookie без Origin отклоняется (CSRF, 403)",
"status": "failed",
"title": "[F10] мутация по cookie без Origin отклоняется (CSRF, 403)",
"duration": 5.457843000000139,
"failureMessages": [
"AssertionError: HTTP 201 {\"id\":\"01M3EA4J31CEM99Y9708PNVE90\",\"code\":\"profession-01m3ea4j31cem99y9708pnve90\",\"name\":\"E2E-CSRF-профессия-c30803\",\"status\":\"active\"}: expected 201 to be 403 // Object.is equality\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:269:57\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [F7] повтор Idempotency-Key с другим телом не создаёт второе событие",
"status": "failed",
"title": "[F7] повтор Idempotency-Key с другим телом не создаёт второе событие",
"duration": 31.478251999999884,
"failureMessages": [
"AssertionError: expected { first: 201, secondCreated: true } to deeply equal { first: 201, secondCreated: false }\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:288:75\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [N11] импорт с неверным kind начисления → 400, а не 500",
"status": "failed",
"title": "[N11] импорт с неверным kind начисления → 400, а не 500",
"duration": 24.907294000000093,
"failureMessages": [
"AssertionError: HTTP 500 {\"statusCode\":500,\"code\":\"23514\",\"error\":\"Internal Server Error\",\"message\":\"new row for relation \\\"staff_payroll_ledger\\\" violates check constraint \\\"staff_payroll_ledger_kind_check\\\"\"}: expected 500 to be 400 // Object.is equality\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:311:57\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Основной API на реальной PostgreSQL"],
"fullName": "Основной API на реальной PostgreSQL [F4] перебор ключей входа ограничивается (429 не позже 30 неверных попыток)",
"status": "failed",
"title": "[F4] перебор ключей входа ограничивается (429 не позже 30 неверных попыток)",
"duration": 75.38818200000014,
"failureMessages": [
"AssertionError: статусы: 401: expected false to be true // Object.is equality\n at /workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts:324:84\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
}
],
"startTime": 1790408015147,
"endTime": 1790408018151.3882,
"status": "failed",
"message": "",
"name": "/workspace/krona-staff/tests/e2e/10-core-defects.e2e.ts"
},
{
"assertionResults": [
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-A] устройство не может само подтвердить смену (status=confirmed отклоняется)",
"status": "failed",
"title": "[SYNC-A] устройство не может само подтвердить смену (status=confirmed отклоняется)",
"duration": 86.95440500000001,
"failureMessages": [
"AssertionError: HTTP 200 {\"results\":[{\"idempotency_key\":\"e2e-01M3EA4JPXC3E39GZMHFH33H92\",\"command_type\":\"upsert_work_session\",\"status\":\"applied\",\"result\":{\"id\":\"01M3EA4JPXQPVQDPGEA3YVFPXV\",\"revision\":1,\"status\":\"applied\"}}]}: expected { http: 200, result: 'applied', …(1) } to deeply equal { http: 200, result: 'rejected', …(1) }\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:86:7\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-B] устройство не может утвердить табель (status=approved отклоняется)",
"status": "failed",
"title": "[SYNC-B] устройство не может утвердить табель (status=approved отклоняется)",
"duration": 32.361658000000006,
"failureMessages": [
"AssertionError: HTTP 200 {\"results\":[{\"idempotency_key\":\"e2e-01M3EA4JR4CST4PE643FC043K9\",\"command_type\":\"upsert_timesheet_entry\",\"status\":\"applied\",\"result\":{\"id\":\"01M3EA4JR43V65BMVJVX5DHSV0\",\"revision\":1,\"status\":\"applied\"}}]}: expected { result: 'applied', …(1) } to deeply equal { result: 'rejected', stored: null }\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:109:7\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-C0] начальная загрузка (pull без курсора) работает на реальной БД (200)",
"status": "failed",
"title": "[SYNC-C0] начальная загрузка (pull без курсора) работает на реальной БД (200)",
"duration": 39.13565999999997,
"failureMessages": [
"AssertionError: HTTP 500 {\"statusCode\":500,\"code\":\"42703\",\"error\":\"Internal Server Error\",\"message\":\"column \\\"status\\\" does not exist\"}: expected 500 to be 200 // Object.is equality\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:120:57\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-C] начальная загрузка >100 сущностей отдаёт все сущности постранично",
"status": "failed",
"title": "[SYNC-C] начальная загрузка >100 сущностей отдаёт все сущности постранично",
"duration": 54.852048000000025,
"failureMessages": [
"AssertionError: HTTP 500 {\"statusCode\":500,\"code\":\"42703\",\"error\":\"Internal Server Error\",\"message\":\"column \\\"status\\\" does not exist\"}: expected 500 to be 200 // Object.is equality\n at pullAll (/workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:51:57)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:130:25\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-D] изменения, сделанные через портал, попадают в инкрементальный pull",
"status": "failed",
"title": "[SYNC-D] изменения, сделанные через портал, попадают в инкрементальный pull",
"duration": 40.97763200000003,
"failureMessages": [
"AssertionError: expected false to be true // Object.is equality\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:151:95\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-E] отметка уволенного сотрудника через sync отклоняется",
"status": "failed",
"title": "[SYNC-E] отметка уволенного сотрудника через sync отклоняется",
"duration": 23.937388999999996,
"failureMessages": [
"AssertionError: HTTP 200 {\"results\":[{\"idempotency_key\":\"e2e-01M3EA4JXB10Y1W7WAT3QXPJXR\",\"command_type\":\"attendance_event\",\"status\":\"applied\",\"result\":{\"event_id\":\"01M3EA4JXD7TMSBAMMAK6HMXK2\",\"status\":\"accepted\"}}]}: expected 'applied' to be 'rejected' // Object.is equality\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:171:77\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-F] отметка через sync сохраняет точку устройства; чужая точка в payload отклоняется",
"status": "failed",
"title": "[SYNC-F] отметка через sync сохраняет точку устройства; чужая точка в payload отклоняется",
"duration": 42.41749800000002,
"failureMessages": [
"AssertionError: HTTP 200 {\"results\":[{\"idempotency_key\":\"e2e-01M3EA4JYFDZ0AAZYVEF6G72T2\",\"command_type\":\"attendance_event\",\"status\":\"applied\",\"result\":{\"event_id\":\"01M3EA4JYH12S10KQ4NWN232FM\",\"status\":\"accepted\"}},{\"idempotency_key\":\"e2e-01M3EA4JYFDXJXPH923SG1E832\",\"command_type\":\"attendance_event\",\"status\":\"applied\",\"resul…: expected { Object (ownOrgUnit, foreign) } to deeply equal { …(2) }\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:202:7\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-G] битая команда в пакете отклоняется по отдельности, остальные применяются (не 500)",
"status": "failed",
"title": "[SYNC-G] битая команда в пакете отклоняется по отдельности, остальные применяются (не 500)",
"duration": 20.59652299999999,
"failureMessages": [
"AssertionError: HTTP 500 {\"statusCode\":500,\"code\":\"22007\",\"error\":\"Internal Server Error\",\"message\":\"invalid input syntax for type timestamp with time zone: \\\"e2e-not-a-timestamp\\\"\"}: expected { http: 500, statuses: [] } to deeply equal { http: 200, statuses: [ …(2) ] }\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:225:7\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-H] регистрация устройства по cookie с чужим Origin отклоняется (CSRF, 403)",
"status": "failed",
"title": "[SYNC-H] регистрация устройства по cookie с чужим Origin отклоняется (CSRF, 403)",
"duration": 9.081312000000025,
"failureMessages": [
"AssertionError: HTTP 201 {\"device\":{\"id\":\"01M3EA4JZKVD04KCMNCGGW1EAH\",\"tenant_id\":\"01M3EA4DJNEY3HRCYSBSX43XW0\",\"device_code\":\"E2E-5J7EDPFQV6\",\"name\":\"E2E-CSRF-терминал-34e01a\",\"token_hint\":\"kstaff_dev_01M3E\",\"status\":\"active\",\"allowed_scopes\":[\"attendance:sync\"],\"registered_at\":\"2026-09-26T07:33:38.935Z\",\"created_by\":\"01M3E…: expected 201 to be 403 // Object.is equality\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:236:57\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-I] без настроенных токенов анонимный запрос не регистрирует устройство (401)",
"status": "failed",
"title": "[SYNC-I] без настроенных токенов анонимный запрос не регистрирует устройство (401)",
"duration": 6.548922000000005,
"failureMessages": [
"AssertionError: HTTP 201 {\"device\":{\"id\":\"01M3EA4JZWQF4S3SXWCX77J9ST\",\"tenant_id\":\"01M3EA4DJNEY3HRCYSBSX43XW0\",\"device_code\":\"E2E-KS5GF18F83\",\"name\":\"E2E-Анонимный терминал-75d36d\",\"token_hint\":\"kstaff_dev_01M3E\",\"status\":\"active\",\"allowed_scopes\":[\"attendance:sync\"],\"registered_at\":\"2026-09-26T07:33:38.940Z\",\"created_by\":\"…: expected 201 to be 401 // Object.is equality\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:247:57\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-J] отметка через sync вне окна времени (2001 год) отклоняется, как в POST /attendance/events",
"status": "failed",
"title": "[SYNC-J] отметка через sync вне окна времени (2001 год) отклоняется, как в POST /attendance/events",
"duration": 23.565251999999987,
"failureMessages": [
"AssertionError: HTTP 200 {\"results\":[{\"idempotency_key\":\"e2e-01M3EA4K0JQNMDJTDAM1PZ1J8K\",\"command_type\":\"attendance_event\",\"status\":\"applied\",\"result\":{\"event_id\":\"01M3EA4K0NB5RS8GACHWC7N2C2\",\"status\":\"accepted\"}}]}: expected 'applied' to be 'rejected' // Object.is equality\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:260:77\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-K] ack курсора из будущего (больше выданного сервером) отклоняется (400)",
"status": "failed",
"title": "[SYNC-K] ack курсора из будущего (больше выданного сервером) отклоняется (400)",
"duration": 6.953785000000039,
"failureMessages": [
"AssertionError: HTTP 200 {\"acknowledged\":true,\"cursor\":\"cur_999999999_fd163ccb01a6\",\"acknowledged_at\":\"2026-09-26T07:33:38.972Z\"}: expected 200 to be 400 // Object.is equality\n at /workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts:275:57\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Офлайн-синхронизация на реальной PostgreSQL"],
"fullName": "Офлайн-синхронизация на реальной PostgreSQL [SYNC-L] отозванное устройство не может синхронизироваться (403) — позитивный контроль",
"status": "passed",
"title": "[SYNC-L] отозванное устройство не может синхронизироваться (403) — позитивный контроль",
"duration": 8.451247999999964,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
}
],
"startTime": 1790408018587,
"endTime": 1790408018982.4512,
"status": "failed",
"message": "",
"name": "/workspace/krona-staff/tests/e2e/20-sync-defects.e2e.ts"
},
{
"assertionResults": [
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-01] менеджер точки A запускает расчёт для точки B → 403",
"status": "failed",
"title": "[OWN-01] менеджер точки A запускает расчёт для точки B → 403",
"duration": 109.84663699999999,
"failureMessages": [
"AssertionError: C1 POST /access-grants (point_manager): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:94:22\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-02] менеджер точки отправляет пакет на согласование → 403",
"status": "failed",
"title": "[OWN-02] менеджер точки отправляет пакет на согласование → 403",
"duration": 64.021771,
"failureMessages": [
"AssertionError: C1 POST /access-grants (point_manager): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:105:22\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-03] бухгалтер отправляет пакет → успех, каждый директор получает ровно одно уведомление",
"status": "failed",
"title": "[OWN-03] бухгалтер отправляет пакет → успех, каждый директор получает ровно одно уведомление",
"duration": 1.5183850000000234,
"failureMessages": [
"AssertionError: C1 POST /access-grants (accountant): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:118:24\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-04] бухгалтер пытается подписать пакет → 403",
"status": "failed",
"title": "[OWN-04] бухгалтер пытается подписать пакет → 403",
"duration": 1.8508840000000077,
"failureMessages": [
"AssertionError: C1 POST /access-grants (accountant): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:133:24\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-05] до подписи директора в ledger нет начислений и выплат",
"status": "failed",
"title": "[OWN-05] до подписи директора в ledger нет начислений и выплат",
"duration": 1.9114280000000008,
"failureMessages": [
"AssertionError: C1 POST /access-grants (accountant): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:141:24\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-06] подпись директора → начисления и выплаты в ledger, пакет и смены неизменяемы",
"status": "failed",
"title": "[OWN-06] подпись директора → начисления и выплаты в ledger, пакет и смены неизменяемы",
"duration": 1.5373430000000212,
"failureMessages": [
"AssertionError: C1 POST /access-grants (accountant): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:148:24\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-07] смена изменена после отправки → подписать нельзя (409), пакет возвращён бухгалтеру",
"status": "failed",
"title": "[OWN-07] смена изменена после отправки → подписать нельзя (409), пакет возвращён бухгалтеру",
"duration": 1.4993349999999737,
"failureMessages": [
"AssertionError: C1 POST /access-grants (accountant): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:173:24\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-08] возврат с комментарием → пакет у бухгалтера, комментарий сохранён",
"status": "failed",
"title": "[OWN-08] возврат с комментарием → пакет у бухгалтера, комментарий сохранён",
"duration": 2.188139000000035,
"failureMessages": [
"AssertionError: C1 POST /access-grants (accountant): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:195:24\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-09] сотрудник точки A отработал смену в точке B → смена попадает в зарплату точки B",
"status": "failed",
"title": "[OWN-09] сотрудник точки A отработал смену в точке B → смена попадает в зарплату точки B",
"duration": 2.2691649999999868,
"failureMessages": [
"AssertionError: C1 POST /access-grants (accountant): HTTP 404 {\"message\":\"Route POST:/api/v1/staff/access-grants not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 201 // Object.is equality\n at grant (/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:28:94)\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:213:24\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-10] сотрудник без согласия на биометрию → сервер сообщает терминалу «регистрация запрещена»",
"status": "failed",
"title": "[OWN-10] сотрудник без согласия на биометрию → сервер сообщает терминалу «регистрация запрещена»",
"duration": 15.068132999999989,
"failureMessages": [
"AssertionError: C3: HTTP 404 {\"message\":\"Route GET:/api/v1/staff/terminal/employees/01M3EA4JGPPB7M0G78QQBQBJ1M/enrollment not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 200 // Object.is equality\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:241:66\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["Решения владельца: роли, пакеты зарплаты, согласие на биометрию"],
"fullName": "Решения владельца: роли, пакеты зарплаты, согласие на биометрию [OWN-11] согласие отозвано → статус для терминала меняется",
"status": "failed",
"title": "[OWN-11] согласие отозвано → статус для терминала меняется",
"duration": 14.774637000000041,
"failureMessages": [
"AssertionError: C3 PUT biometric-consent: HTTP 404 {\"message\":\"Route PUT:/api/v1/staff/employees/01M3EA4JH57XZ361XBC2Z7SA6J/biometric-consent not found\",\"error\":\"Not Found\",\"statusCode\":404}: expected 404 to be 200 // Object.is equality\n at /workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts:255:86\n at processTicksAndRejections (node:internal/process/task_queues:105:5)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:20"
],
"meta": {},
"tags": [],
"benchmarks": []
}
],
"startTime": 1790408018262,
"endTime": 1790408018478.7747,
"status": "failed",
"message": "",
"name": "/workspace/krona-staff/tests/e2e/30-owner-decisions.e2e.ts"
},
{
"assertionResults": [
{
"ancestorTitles": ["deploy/pilot/compose.yaml"],
"fullName": "deploy/pilot/compose.yaml [PILOT-1] все подставляемые переменные обязательны: ${VAR:?сообщение}",
"status": "failed",
"title": "[PILOT-1] все подставляемые переменные обязательны: ${VAR:?сообщение}",
"duration": 5.8893739999999895,
"failureMessages": [
"AssertionError: переменные без :? — пустое значение молча попадёт в контейнер: expected [ 'STANDALONE_MANAGER_TOKEN', …(13) ] to deeply equal []\n at /workspace/krona-staff/tests/e2e/40-compose-pilot.e2e.ts:34:87\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:1628:35\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:26\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3319:20\n at new Promise (<anonymous>)\n at runWithCancel (file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3314:10)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3299:20\n at new Promise (<anonymous>)\n at runWithTimeout (file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3257:10)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3876:64"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["deploy/pilot/compose.yaml"],
"fullName": "deploy/pilot/compose.yaml [PILOT-2] ни один сервис не запускается с NODE_ENV=development",
"status": "failed",
"title": "[PILOT-2] ни один сервис не запускается с NODE_ENV=development",
"duration": 1.0336859999999888,
"failureMessages": [
"AssertionError: expected [ 'app' ] to deeply equal []\n at /workspace/krona-staff/tests/e2e/40-compose-pilot.e2e.ts:41:23\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:1628:35\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:2783:26\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3319:20\n at new Promise (<anonymous>)\n at runWithCancel (file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3314:10)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3299:20\n at new Promise (<anonymous>)\n at runWithTimeout (file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3257:10)\n at file:///workspace/krona-staff/node_modules/vitest/dist/chunks/run.C5UmxDPh.js:3876:64"
],
"meta": {},
"tags": [],
"benchmarks": []
},
{
"ancestorTitles": ["deploy/pilot/compose.yaml"],
"fullName": "deploy/pilot/compose.yaml [PILOT-3] у сервиса app нет учётных данных мигратора",
"status": "passed",
"title": "[PILOT-3] у сервиса app нет учётных данных мигратора",
"duration": 0.5442440000000062,
"failureMessages": [],
"meta": {},
"tags": [],
"benchmarks": []
}
],
"startTime": 1790408019346,
"endTime": 1790408019353.5442,
"status": "failed",
"message": "",
"name": "/workspace/krona-staff/tests/e2e/40-compose-pilot.e2e.ts"
}
]
}

View file

@ -0,0 +1,941 @@
$ npx vitest run --config tests/e2e/vitest.e2e.config.ts --reporter=verbose --reporter=json --outputFile.json=/workspace/krona-staff/tests/e2e/evidence/e2e-results.json
RUN v5.0.1 /workspace/krona-staff
[e2e] provision:
provisioned database=krona_staff_e2e server_version=17.11
role=krona_migrator super=false createrole=false createdb=false bypassrls=false
role=krona_staff_app super=false createrole=false createdb=false bypassrls=false
[e2e] migrations (roundtrip) as krona_migrator:
== migrate up (1)
applied 0001_infrastructure.up.sql
applied 0002_security_hardening.up.sql
applied 0003_app_role_privileges.up.sql
applied 0004_revoke_broad_default_privileges.up.sql
applied 0005_attendance_portal.up.sql
applied 0006_payroll_foundation.up.sql
applied 0007_work_session_trace.up.sql
applied 0008_employee_access.up.sql
applied 0009_professions.up.sql
applied 0010_employee_push_notifications.up.sql
applied 0011_offline_sync_backend.up.sql
== rollback all (applied now: 11)
rolled back 0011_offline_sync_backend.down.sql
rolled back 0010_employee_push_notifications.down.sql
rolled back 0009_professions.down.sql
rolled back 0008_employee_access.down.sql
rolled back 0007_work_session_trace.down.sql
rolled back 0006_payroll_foundation.down.sql
rolled back 0005_attendance_portal.down.sql
rolled back 0004_revoke_broad_default_privileges.down.sql
rolled back 0003_app_role_privileges.down.sql
rolled back 0002_security_hardening.down.sql
rolled back 0001_infrastructure.down.sql
no migration to roll back
== rolled back 11 migrations
== migrate up (2)
applied 0001_infrastructure.up.sql
applied 0002_security_hardening.up.sql
applied 0003_app_role_privileges.up.sql
applied 0004_revoke_broad_default_privileges.up.sql
applied 0005_attendance_portal.up.sql
applied 0006_payroll_foundation.up.sql
applied 0007_work_session_trace.up.sql
applied 0008_employee_access.up.sql
applied 0009_professions.up.sql
applied 0010_employee_push_notifications.up.sql
applied 0011_offline_sync_backend.up.sql
== migrate up (3, must be no-op)
== roundtrip OK: rolledBack=11 reapplied=11
[e2e] server secured ready at http://127.0.0.1:35389 (log: tests/e2e/evidence/server-secured.txt)
[e2e] server no-tokens ready at http://127.0.0.1:33821 (log: tests/e2e/evidence/server-no-tokens.txt)
[e2e] server rate-limit ready at http://127.0.0.1:36299 (log: tests/e2e/evidence/server-rate-limit.txt)
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N1] менеджер создаёт сотрудника через POST /employees → 201 38ms
→ HTTP 500 {"statusCode":500,"code":"42P08","error":"Internal Server Error","message":"inconsistent types deduced for parameter $2"}: expected 500 to be 201 // Object.is equality
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N2] подтверждение смены, расчёт и утверждение зарплаты проходят (200) и начисляют 8 ч × ставка 111ms
→ подтверждение смены: HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}: expected 500 to be 200 // Object.is equality
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N4] пересекающиеся расчёты не начисляют одну смену дважды 66ms
→ подтверждение смены (предусловие, см. N2): HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}: expected 500 to be 200 // Object.is equality
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N3] push-подписка на внутренний адрес отклоняется, сервер не подключается к 127.0.0.1 2544ms
→ подписка: HTTP 201 {"id":"01M3EA4FH3FG4Q3YEKXYQ8Y4Q5","endpoint":"https://127.0.0.1:36027/e2e-internal-admin"}: expected { status: 201, connections: 1 } to deeply equal { status: toSatisfy{…}, …(1) }
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N9] чужой push-endpoint нельзя перепривязать к другому сотруднику 44ms
→ HTTP 201 {"id":"01M3EA4J0JSPFRDF22J6E2CEY1","endpoint":"https://fcm.googleapis.com/fcm/send/e2e-d464594734e6ddf8569ec571f5832dbf"}: expected { status: 201, …(1) } to deeply equal { status: toSatisfy{…}, …(1) }
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N12] PUT pay-assignment отвергает лишние поля и нереальные суммы (400) 31ms
→ HTTP 200 {"id":"01M3EA4J1PHXWHFMAMYYVRMK3E","employee_id":"01M3EA4J151B1H9D5AKAR29AN9","org_unit_id":null,"pay_rule_id":"01M3EA4FCDRQSS6V8H5Q6XS615","pay_rule_code":"hourly","pay_rule_name":"Почасовая (стажёр, дополнительный сотрудник)","rate_minor":12345,"percent_bp":0,"guarantee_minor":0,"pool_weight_bp":0… | HTTP 200 {"id":"01M3EA4J1PHXWHFMAMYYVRMK3E","employee_id":"01M3EA4J151B1H9D5AKAR29AN9","org_unit_id":null,"pay_rule_id":"01M3EA4FCDRQSS6V8H5Q6XS615","pay_rule_code":"hourly","pay_rule_name":"Почасовая (стажёр, дополнительный сотрудник)","rate_minor":9007199254740991,"percent_bp":0,"guarantee_minor":900719925…: expected { extra: 200, huge: 200 } to deeply equal { extra: 400, huge: 400 }
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N10] терминальный токен не читает справочники профессий и точек (403) 4ms
→ expected { professions: 200, units: 200 } to deeply equal { professions: 403, units: 403 }
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F2] standalone без токенов не выдаёт права менеджера анонимному запросу (401) 20ms
→ expected { portal: 200, payroll: 200, …(1) } to deeply equal { portal: 401, payroll: 401, …(1) }
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F3] cookie сессии не содержит сырой токен и отзывается при выходе 8ms
→ expected { rawTokenInCookie: true, …(1) } to deeply equal { rawTokenInCookie: false, …(1) }
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F10] мутация по cookie без Origin отклоняется (CSRF, 403) 5ms
→ HTTP 201 {"id":"01M3EA4J31CEM99Y9708PNVE90","code":"profession-01m3ea4j31cem99y9708pnve90","name":"E2E-CSRF-профессия-c30803","status":"active"}: expected 201 to be 403 // Object.is equality
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F7] повтор Idempotency-Key с другим телом не создаёт второе событие 31ms
→ expected { first: 201, secondCreated: true } to deeply equal { first: 201, secondCreated: false }
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N11] импорт с неверным kind начисления → 400, а не 500 25ms
→ HTTP 500 {"statusCode":500,"code":"23514","error":"Internal Server Error","message":"new row for relation \"staff_payroll_ledger\" violates check constraint \"staff_payroll_ledger_kind_check\""}: expected 500 to be 400 // Object.is equality
× tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F4] перебор ключей входа ограничивается (429 не позже 30 неверных попыток) 75ms
→ статусы: 401: expected false to be true // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-01] менеджер точки A запускает расчёт для точки B → 403 110ms
→ C1 POST /access-grants (point_manager): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-02] менеджер точки отправляет пакет на согласование → 403 64ms
→ C1 POST /access-grants (point_manager): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-03] бухгалтер отправляет пакет → успех, каждый директор получает ровно одно уведомление 2ms
→ C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-04] бухгалтер пытается подписать пакет → 403 2ms
→ C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-05] до подписи директора в ledger нет начислений и выплат 2ms
→ C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-06] подпись директора → начисления и выплаты в ledger, пакет и смены неизменяемы 2ms
→ C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-07] смена изменена после отправки → подписать нельзя (409), пакет возвращён бухгалтеру 1ms
→ C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-08] возврат с комментарием → пакет у бухгалтера, комментарий сохранён 2ms
→ C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-09] сотрудник точки A отработал смену в точке B → смена попадает в зарплату точки B 2ms
→ C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-10] сотрудник без согласия на биометрию → сервер сообщает терминалу «регистрация запрещена» 15ms
→ C3: HTTP 404 {"message":"Route GET:/api/v1/staff/terminal/employees/01M3EA4JGPPB7M0G78QQBQBJ1M/enrollment not found","error":"Not Found","statusCode":404}: expected 404 to be 200 // Object.is equality
× tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-11] согласие отозвано → статус для терминала меняется 15ms
→ C3 PUT biometric-consent: HTTP 404 {"message":"Route PUT:/api/v1/staff/employees/01M3EA4JH57XZ361XBC2Z7SA6J/biometric-consent not found","error":"Not Found","statusCode":404}: expected 404 to be 200 // Object.is equality
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-A] устройство не может само подтвердить смену (status=confirmed отклоняется) 87ms
→ HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4JPXC3E39GZMHFH33H92","command_type":"upsert_work_session","status":"applied","result":{"id":"01M3EA4JPXQPVQDPGEA3YVFPXV","revision":1,"status":"applied"}}]}: expected { http: 200, result: 'applied', …(1) } to deeply equal { http: 200, result: 'rejected', …(1) }
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-B] устройство не может утвердить табель (status=approved отклоняется) 32ms
→ HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4JR4CST4PE643FC043K9","command_type":"upsert_timesheet_entry","status":"applied","result":{"id":"01M3EA4JR43V65BMVJVX5DHSV0","revision":1,"status":"applied"}}]}: expected { result: 'applied', …(1) } to deeply equal { result: 'rejected', stored: null }
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-C0] начальная загрузка (pull без курсора) работает на реальной БД (200) 39ms
→ HTTP 500 {"statusCode":500,"code":"42703","error":"Internal Server Error","message":"column \"status\" does not exist"}: expected 500 to be 200 // Object.is equality
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-C] начальная загрузка >100 сущностей отдаёт все сущности постранично 55ms
→ HTTP 500 {"statusCode":500,"code":"42703","error":"Internal Server Error","message":"column \"status\" does not exist"}: expected 500 to be 200 // Object.is equality
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-D] изменения, сделанные через портал, попадают в инкрементальный pull 41ms
→ expected false to be true // Object.is equality
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-E] отметка уволенного сотрудника через sync отклоняется 24ms
→ HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4JXB10Y1W7WAT3QXPJXR","command_type":"attendance_event","status":"applied","result":{"event_id":"01M3EA4JXD7TMSBAMMAK6HMXK2","status":"accepted"}}]}: expected 'applied' to be 'rejected' // Object.is equality
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-F] отметка через sync сохраняет точку устройства; чужая точка в payload отклоняется 42ms
→ HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4JYFDZ0AAZYVEF6G72T2","command_type":"attendance_event","status":"applied","result":{"event_id":"01M3EA4JYH12S10KQ4NWN232FM","status":"accepted"}},{"idempotency_key":"e2e-01M3EA4JYFDXJXPH923SG1E832","command_type":"attendance_event","status":"applied","resul…: expected { Object (ownOrgUnit, foreign) } to deeply equal { …(2) }
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-G] битая команда в пакете отклоняется по отдельности, остальные применяются (не 500) 21ms
→ HTTP 500 {"statusCode":500,"code":"22007","error":"Internal Server Error","message":"invalid input syntax for type timestamp with time zone: \"e2e-not-a-timestamp\""}: expected { http: 500, statuses: [] } to deeply equal { http: 200, statuses: [ …(2) ] }
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-H] регистрация устройства по cookie с чужим Origin отклоняется (CSRF, 403) 9ms
→ HTTP 201 {"device":{"id":"01M3EA4JZKVD04KCMNCGGW1EAH","tenant_id":"01M3EA4DJNEY3HRCYSBSX43XW0","device_code":"E2E-5J7EDPFQV6","name":"E2E-CSRF-терминал-34e01a","token_hint":"kstaff_dev_01M3E","status":"active","allowed_scopes":["attendance:sync"],"registered_at":"2026-09-26T07:33:38.935Z","created_by":"01M3E…: expected 201 to be 403 // Object.is equality
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-I] без настроенных токенов анонимный запрос не регистрирует устройство (401) 7ms
→ HTTP 201 {"device":{"id":"01M3EA4JZWQF4S3SXWCX77J9ST","tenant_id":"01M3EA4DJNEY3HRCYSBSX43XW0","device_code":"E2E-KS5GF18F83","name":"E2E-Анонимный терминал-75d36d","token_hint":"kstaff_dev_01M3E","status":"active","allowed_scopes":["attendance:sync"],"registered_at":"2026-09-26T07:33:38.940Z","created_by":"…: expected 201 to be 401 // Object.is equality
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-J] отметка через sync вне окна времени (2001 год) отклоняется, как в POST /attendance/events 24ms
→ HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4K0JQNMDJTDAM1PZ1J8K","command_type":"attendance_event","status":"applied","result":{"event_id":"01M3EA4K0NB5RS8GACHWC7N2C2","status":"accepted"}}]}: expected 'applied' to be 'rejected' // Object.is equality
× tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-K] ack курсора из будущего (больше выданного сервером) отклоняется (400) 7ms
→ HTTP 200 {"acknowledged":true,"cursor":"cur_999999999_fd163ccb01a6","acknowledged_at":"2026-09-26T07:33:38.972Z"}: expected 200 to be 400 // Object.is equality
✓ tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-L] отозванное устройство не может синхронизироваться (403) — позитивный контроль 8ms
✓ tests/e2e/00-harness.e2e.ts > HARNESS: реальный сервер + PostgreSQL 17 > [HARNESS] сервер отвечает live/ready (ready проверяет БД) 32ms
✓ tests/e2e/00-harness.e2e.ts > HARNESS: реальный сервер + PostgreSQL 17 > [HARNESS] БД: PostgreSQL 17, приложение под ролью без SUPERUSER/BYPASSRLS, мигратор без SUPERUSER 14ms
✓ tests/e2e/00-harness.e2e.ts > HARNESS: реальный сервер + PostgreSQL 17 > [HARNESS] миграции применены мигратором, app-роль не видит schema_migrations 14ms
✓ tests/e2e/00-harness.e2e.ts > HARNESS: реальный сервер + PostgreSQL 17 > [HARNESS] токены: без токена 401, случайный токен 401, manager-токен 200 14ms
✓ tests/e2e/00-harness.e2e.ts > HARNESS: реальный сервер + PostgreSQL 17 > [HARNESS] терминал: отметка сотрудника из импорта принимается (201) 25ms
✓ tests/e2e/00-harness.e2e.ts > HARNESS: реальный сервер + PostgreSQL 17 > [CTRL] RBAC: терминал не видит портал и не создаёт сотрудников; сотрудник видит только себя 24ms
✓ tests/e2e/00-harness.e2e.ts > HARNESS: реальный сервер + PostgreSQL 17 > [CTRL] уволенный сотрудник теряет доступ (401) 23ms
× tests/e2e/40-compose-pilot.e2e.ts > deploy/pilot/compose.yaml > [PILOT-1] все подставляемые переменные обязательны: ${VAR:?сообщение} 6ms
→ переменные без :? — пустое значение молча попадёт в контейнер: expected [ 'STANDALONE_MANAGER_TOKEN', …(13) ] to deeply equal []
× tests/e2e/40-compose-pilot.e2e.ts > deploy/pilot/compose.yaml > [PILOT-2] ни один сервис не запускается с NODE_ENV=development 1ms
→ expected [ 'app' ] to deeply equal []
✓ tests/e2e/40-compose-pilot.e2e.ts > deploy/pilot/compose.yaml > [PILOT-3] у сервиса app нет учётных данных мигратора 1ms
⎯⎯⎯⎯⎯⎯ Failed Tests 38 ⎯⎯⎯⎯⎯⎯⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N1] менеджер создаёт сотрудника через POST /employees → 201
AssertionError: HTTP 500 {"statusCode":500,"code":"42P08","error":"Internal Server Error","message":"inconsistent types deduced for parameter $2"}: expected 500 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 500
❯ tests/e2e/10-core-defects.e2e.ts:55:57
53| },
54| });
55| expect(response.status, describeResponse(response)).toBe(201);
| ^
56| const rows = await dbQuery('SELECT id FROM staff_employees WHERE p…
57| number,
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N2] подтверждение смены, расчёт и утверждение зарплаты проходят (200) и начисляют 8 ч × ставка
AssertionError: подтверждение смены: HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}: expected 500 to be 200 // Object.is equality
- Expected
+ Received
- 200
+ 500
❯ tests/e2e/10-core-defects.e2e.ts:73:81
71| body: { status: 'confirmed' },
72| });
73| expect(confirm.status, `подтверждение смены: ${describeResponse(co…
| ^
74|
75| const calculate = await api('POST', '/payroll/calculate', {
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N4] пересекающиеся расчёты не начисляют одну смену дважды
AssertionError: подтверждение смены (предусловие, см. N2): HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}: expected 500 to be 200 // Object.is equality
- Expected
+ Received
- 200
+ 500
❯ tests/e2e/10-core-defects.e2e.ts:104:7
102| confirm.status,
103| `подтверждение смены (предусловие, см. N2): ${describeResponse(c…
104| ).toBe(200);
| ^
105|
106| const month = monthOf(day);
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N3] push-подписка на внутренний адрес отклоняется, сервер не подключается к 127.0.0.1
AssertionError: подписка: HTTP 201 {"id":"01M3EA4FH3FG4Q3YEKXYQ8Y4Q5","endpoint":"https://127.0.0.1:36027/e2e-internal-admin"}: expected { status: 201, connections: 1 } to deeply equal { status: toSatisfy{…}, …(1) }
- Expected
+ Received
{
- "connections": 0,
- "status": toSatisfy<[Function anonymous]>,
+ "connections": 1,
+ "status": 201,
}
❯ tests/e2e/10-core-defects.e2e.ts:161:9
159| { status: subscribe.status, connections },
160| `подписка: ${describeResponse(subscribe)}`,
161| ).toEqual({
| ^
162| status: expect.toSatisfy((s: number) => s === 400 || s === 422…
163| connections: 0,
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N9] чужой push-endpoint нельзя перепривязать к другому сотруднику
AssertionError: HTTP 201 {"id":"01M3EA4J0JSPFRDF22J6E2CEY1","endpoint":"https://fcm.googleapis.com/fcm/send/e2e-d464594734e6ddf8569ec571f5832dbf"}: expected { status: 201, …(1) } to deeply equal { status: toSatisfy{…}, …(1) }
- Expected
+ Received
{
"owner": [
- "01M3EA4HZSY982GYTPDAVP0Z0Q",
+ "01M3EA4HZTSZ12MKP3SV134FKS",
],
- "status": toSatisfy<[Function anonymous]>,
+ "status": 201,
}
❯ tests/e2e/10-core-defects.e2e.ts:191:7
189| { status: second.status, owner: owner.map((row) => row.employee_…
190| describeResponse(second),
191| ).toEqual({
| ^
192| status: expect.toSatisfy((s: number) => s === 409 || s === 403),
193| owner: [employeeA!.id],
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N12] PUT pay-assignment отвергает лишние поля и нереальные суммы (400)
AssertionError: HTTP 200 {"id":"01M3EA4J1PHXWHFMAMYYVRMK3E","employee_id":"01M3EA4J151B1H9D5AKAR29AN9","org_unit_id":null,"pay_rule_id":"01M3EA4FCDRQSS6V8H5Q6XS615","pay_rule_code":"hourly","pay_rule_name":"Почасовая (стажёр, дополнительный сотрудник)","rate_minor":12345,"percent_bp":0,"guarantee_minor":0,"pool_weight_bp":0… | HTTP 200 {"id":"01M3EA4J1PHXWHFMAMYYVRMK3E","employee_id":"01M3EA4J151B1H9D5AKAR29AN9","org_unit_id":null,"pay_rule_id":"01M3EA4FCDRQSS6V8H5Q6XS615","pay_rule_code":"hourly","pay_rule_name":"Почасовая (стажёр, дополнительный сотрудник)","rate_minor":9007199254740991,"percent_bp":0,"guarantee_minor":900719925…: expected { extra: 200, huge: 200 } to deeply equal { extra: 400, huge: 400 }
- Expected
+ Received
{
- "extra": 400,
- "huge": 400,
+ "extra": 200,
+ "huge": 200,
}
❯ tests/e2e/10-core-defects.e2e.ts:215:7
213| { extra: extra.status, huge: huge.status },
214| `${describeResponse(extra)} | ${describeResponse(huge)}`,
215| ).toEqual({
| ^
216| extra: 400,
217| huge: 400,
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N10] терминальный токен не читает справочники профессий и точек (403)
AssertionError: expected { professions: 200, units: 200 } to deeply equal { professions: 403, units: 403 }
- Expected
+ Received
{
- "professions": 403,
- "units": 403,
+ "professions": 200,
+ "units": 200,
}
❯ tests/e2e/10-core-defects.e2e.ts:224:70
222| const professions = await api('GET', '/professions', { token: ctx(…
223| const units = await api('GET', '/org-units', { token: ctx().termin…
224| expect({ professions: professions.status, units: units.status }).t…
| ^
225| professions: 403,
226| units: 403,
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F2] standalone без токенов не выдаёт права менеджера анонимному запросу (401)
AssertionError: expected { portal: 200, payroll: 200, …(1) } to deeply equal { portal: 401, payroll: 401, …(1) }
- Expected
+ Received
{
- "payroll": 401,
- "portal": 401,
- "write": 401,
+ "payroll": 200,
+ "portal": 200,
+ "write": 201,
}
❯ tests/e2e/10-core-defects.e2e.ts:237:85
235| body: { name: synthetic('Профессия') },
236| });
237| expect({ portal: portal.status, payroll: payroll.status, write: wr…
| ^
238| portal: 401,
239| payroll: 401,
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F3] cookie сессии не содержит сырой токен и отзывается при выходе
AssertionError: expected { rawTokenInCookie: true, …(1) } to deeply equal { rawTokenInCookie: false, …(1) }
- Expected
+ Received
{
- "afterLogout": 401,
- "rawTokenInCookie": false,
+ "afterLogout": 200,
+ "rawTokenInCookie": true,
}
❯ tests/e2e/10-core-defects.e2e.ts:255:91
253| expect(logout.status).toBe(204);
254| const reuse = await api('GET', '/portal', { headers: { cookie } });
255| expect({ rawTokenInCookie: value === ctx().managerToken, afterLogo…
| ^
256| rawTokenInCookie: false,
257| afterLogout: 401,
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F10] мутация по cookie без Origin отклоняется (CSRF, 403)
AssertionError: HTTP 201 {"id":"01M3EA4J31CEM99Y9708PNVE90","code":"profession-01m3ea4j31cem99y9708pnve90","name":"E2E-CSRF-профессия-c30803","status":"active"}: expected 201 to be 403 // Object.is equality
- Expected
+ Received
- 403
+ 201
❯ tests/e2e/10-core-defects.e2e.ts:269:57
267| body: { name: synthetic('CSRF-профессия') },
268| });
269| expect(response.status, describeResponse(response)).toBe(403);
| ^
270| });
271|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[10/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F7] повтор Idempotency-Key с другим телом не создаёт второе событие
AssertionError: expected { first: 201, secondCreated: true } to deeply equal { first: 201, secondCreated: false }
- Expected
+ Received
{
"first": 201,
- "secondCreated": false,
+ "secondCreated": true,
}
❯ tests/e2e/10-core-defects.e2e.ts:288:75
286| const first = await send(`e2e-${randomUlid()}`);
287| const second = await send(`e2e-${randomUlid()}`);
288| expect({ first: first.status, secondCreated: second.status === 201…
| ^
289| first: 201,
290| secondCreated: false,
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[11/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [N11] импорт с неверным kind начисления → 400, а не 500
AssertionError: HTTP 500 {"statusCode":500,"code":"23514","error":"Internal Server Error","message":"new row for relation \"staff_payroll_ledger\" violates check constraint \"staff_payroll_ledger_kind_check\""}: expected 500 to be 400 // Object.is equality
- Expected
+ Received
- 400
+ 500
❯ tests/e2e/10-core-defects.e2e.ts:311:57
309| },
310| });
311| expect(response.status, describeResponse(response)).toBe(400);
| ^
312| });
313|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[12/38]⎯
FAIL tests/e2e/10-core-defects.e2e.ts > Основной API на реальной PostgreSQL > [F4] перебор ключей входа ограничивается (429 не позже 30 неверных попыток)
AssertionError: статусы: 401: expected false to be true // Object.is equality
- Expected
+ Received
- true
+ false
❯ tests/e2e/10-core-defects.e2e.ts:324:84
322| if (response.status === 429) break;
323| }
324| expect(statuses.includes(429), `статусы: ${[...new Set(statuses)].…
| ^
325| });
326| });
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[13/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-A] устройство не может само подтвердить смену (status=confirmed отклоняется)
AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4JPXC3E39GZMHFH33H92","command_type":"upsert_work_session","status":"applied","result":{"id":"01M3EA4JPXQPVQDPGEA3YVFPXV","revision":1,"status":"applied"}}]}: expected { http: 200, result: 'applied', …(1) } to deeply equal { http: 200, result: 'rejected', …(1) }
- Expected
+ Received
{
"http": 200,
- "result": "rejected",
- "stored": null,
+ "result": "applied",
+ "stored": "confirmed",
}
❯ tests/e2e/20-sync-defects.e2e.ts:86:7
84| },
85| describeResponse(response),
86| ).toEqual({ http: 200, result: 'rejected', stored: null });
| ^
87| });
88|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[14/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-B] устройство не может утвердить табель (status=approved отклоняется)
AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4JR4CST4PE643FC043K9","command_type":"upsert_timesheet_entry","status":"applied","result":{"id":"01M3EA4JR43V65BMVJVX5DHSV0","revision":1,"status":"applied"}}]}: expected { result: 'applied', …(1) } to deeply equal { result: 'rejected', stored: null }
- Expected
+ Received
{
- "result": "rejected",
- "stored": null,
+ "result": "applied",
+ "stored": "approved",
}
❯ tests/e2e/20-sync-defects.e2e.ts:109:7
107| { result: response.body?.results?.[0]?.status, stored: stored[0]…
108| describeResponse(response),
109| ).toEqual({ result: 'rejected', stored: null });
| ^
110| });
111|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[15/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-C0] начальная загрузка (pull без курсора) работает на реальной БД (200)
AssertionError: HTTP 500 {"statusCode":500,"code":"42703","error":"Internal Server Error","message":"column \"status\" does not exist"}: expected 500 to be 200 // Object.is equality
- Expected
+ Received
- 200
+ 500
❯ tests/e2e/20-sync-defects.e2e.ts:120:57
118| body: { cursor: null },
119| });
120| expect(response.status, describeResponse(response)).toBe(200);
| ^
121| const types = new Set(
122| (response.body.changes as Array<{ entity_type: string }>).map((c…
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[16/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-C] начальная загрузка >100 сущностей отдаёт все сущности постранично
AssertionError: HTTP 500 {"statusCode":500,"code":"42703","error":"Internal Server Error","message":"column \"status\" does not exist"}: expected 500 to be 200 // Object.is equality
- Expected
+ Received
- 200
+ 500
❯ pullAll tests/e2e/20-sync-defects.e2e.ts:51:57
49| body: { cursor: next, limit: 100 },
50| });
51| expect(response.status, describeResponse(response)).toBe(200);
| ^
52| changes.push(...(response.body.changes as Array<{ entity_type: str…
53| next = response.body.next_cursor as string;
❯ tests/e2e/20-sync-defects.e2e.ts:130:25
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[17/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-D] изменения, сделанные через портал, попадают в инкрементальный pull
AssertionError: expected false to be true // Object.is equality
- Expected
+ Received
- true
+ false
❯ tests/e2e/20-sync-defects.e2e.ts:151:95
149| expect(patch.status, describeResponse(patch)).toBe(200);
150| const { changes } = await pullAll(device, cursor);
151| expect(changes.some((c) => c.entity_type === 'employee' && c.entit…
| ^
152| true,
153| );
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[18/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-E] отметка уволенного сотрудника через sync отклоняется
AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4JXB10Y1W7WAT3QXPJXR","command_type":"attendance_event","status":"applied","result":{"event_id":"01M3EA4JXD7TMSBAMMAK6HMXK2","status":"accepted"}}]}: expected 'applied' to be 'rejected' // Object.is equality
Expected: "rejected"
Received: "applied"
❯ tests/e2e/20-sync-defects.e2e.ts:171:77
169| }),
170| ]);
171| expect(response.body?.results?.[0]?.status, describeResponse(respo…
| ^
172| });
173|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[19/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-F] отметка через sync сохраняет точку устройства; чужая точка в payload отклоняется
AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4JYFDZ0AAZYVEF6G72T2","command_type":"attendance_event","status":"applied","result":{"event_id":"01M3EA4JYH12S10KQ4NWN232FM","status":"accepted"}},{"idempotency_key":"e2e-01M3EA4JYFDXJXPH923SG1E832","command_type":"attendance_event","status":"applied","resul…: expected { Object (ownOrgUnit, foreign) } to deeply equal { …(2) }
- Expected
+ Received
{
- "foreign": "rejected",
- "ownOrgUnit": "01M3EA4JXPPT6RXP11RKV1VY20",
+ "foreign": "applied",
+ "ownOrgUnit": null,
}
❯ tests/e2e/20-sync-defects.e2e.ts:202:7
200| },
201| describeResponse(response),
202| ).toEqual({ ownOrgUnit: unitA!.id, foreign: 'rejected' });
| ^
203| });
204|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[20/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-G] битая команда в пакете отклоняется по отдельности, остальные применяются (не 500)
AssertionError: HTTP 500 {"statusCode":500,"code":"22007","error":"Internal Server Error","message":"invalid input syntax for type timestamp with time zone: \"e2e-not-a-timestamp\""}: expected { http: 500, statuses: [] } to deeply equal { http: 200, statuses: [ …(2) ] }
- Expected
+ Received
{
- "http": 200,
- "statuses": [
- "applied",
- "rejected",
- ],
+ "http": 500,
+ "statuses": [],
}
❯ tests/e2e/20-sync-defects.e2e.ts:225:7
223| },
224| describeResponse(response),
225| ).toEqual({ http: 200, statuses: ['applied', 'rejected'] });
| ^
226| });
227|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[21/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-H] регистрация устройства по cookie с чужим Origin отклоняется (CSRF, 403)
AssertionError: HTTP 201 {"device":{"id":"01M3EA4JZKVD04KCMNCGGW1EAH","tenant_id":"01M3EA4DJNEY3HRCYSBSX43XW0","device_code":"E2E-5J7EDPFQV6","name":"E2E-CSRF-терминал-34e01a","token_hint":"kstaff_dev_01M3E","status":"active","allowed_scopes":["attendance:sync"],"registered_at":"2026-09-26T07:33:38.935Z","created_by":"01M3E…: expected 201 to be 403 // Object.is equality
- Expected
+ Received
- 403
+ 201
❯ tests/e2e/20-sync-defects.e2e.ts:236:57
234| body: { device_code: `E2E-${randomUlid().slice(-10)}`, name: syn…
235| });
236| expect(response.status, describeResponse(response)).toBe(403);
| ^
237| });
238|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[22/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-I] без настроенных токенов анонимный запрос не регистрирует устройство (401)
AssertionError: HTTP 201 {"device":{"id":"01M3EA4JZWQF4S3SXWCX77J9ST","tenant_id":"01M3EA4DJNEY3HRCYSBSX43XW0","device_code":"E2E-KS5GF18F83","name":"E2E-Анонимный терминал-75d36d","token_hint":"kstaff_dev_01M3E","status":"active","allowed_scopes":["attendance:sync"],"registered_at":"2026-09-26T07:33:38.940Z","created_by":"…: expected 201 to be 401 // Object.is equality
- Expected
+ Received
- 401
+ 201
❯ tests/e2e/20-sync-defects.e2e.ts:247:57
245| },
246| });
247| expect(response.status, describeResponse(response)).toBe(401);
| ^
248| });
249|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[23/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-J] отметка через sync вне окна времени (2001 год) отклоняется, как в POST /attendance/events
AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-01M3EA4K0JQNMDJTDAM1PZ1J8K","command_type":"attendance_event","status":"applied","result":{"event_id":"01M3EA4K0NB5RS8GACHWC7N2C2","status":"accepted"}}]}: expected 'applied' to be 'rejected' // Object.is equality
Expected: "rejected"
Received: "applied"
❯ tests/e2e/20-sync-defects.e2e.ts:260:77
258| }),
259| ]);
260| expect(response.body?.results?.[0]?.status, describeResponse(respo…
| ^
261| });
262|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[24/38]⎯
FAIL tests/e2e/20-sync-defects.e2e.ts > Офлайн-синхронизация на реальной PostgreSQL > [SYNC-K] ack курсора из будущего (больше выданного сервером) отклоняется (400)
AssertionError: HTTP 200 {"acknowledged":true,"cursor":"cur_999999999_fd163ccb01a6","acknowledged_at":"2026-09-26T07:33:38.972Z"}: expected 200 to be 400 // Object.is equality
- Expected
+ Received
- 400
+ 200
❯ tests/e2e/20-sync-defects.e2e.ts:275:57
273| body: { cursor: `cur_${seq}_${hash}` },
274| });
275| expect(response.status, describeResponse(response)).toBe(400);
| ^
276| });
277|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[25/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-01] менеджер точки A запускает расчёт для точки B → 403
AssertionError: C1 POST /access-grants (point_manager): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:94:22
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[26/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-02] менеджер точки отправляет пакет на согласование → 403
AssertionError: C1 POST /access-grants (point_manager): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:105:22
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[27/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-03] бухгалтер отправляет пакет → успех, каждый директор получает ровно одно уведомление
AssertionError: C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:118:24
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[28/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-04] бухгалтер пытается подписать пакет → 403
AssertionError: C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:133:24
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[29/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-05] до подписи директора в ledger нет начислений и выплат
AssertionError: C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:141:24
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[30/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-06] подпись директора → начисления и выплаты в ledger, пакет и смены неизменяемы
AssertionError: C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:148:24
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[31/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-07] смена изменена после отправки → подписать нельзя (409), пакет возвращён бухгалтеру
AssertionError: C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:173:24
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[32/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-08] возврат с комментарием → пакет у бухгалтера, комментарий сохранён
AssertionError: C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:195:24
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[33/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-09] сотрудник точки A отработал смену в точке B → смена попадает в зарплату точки B
AssertionError: C1 POST /access-grants (accountant): HTTP 404 {"message":"Route POST:/api/v1/staff/access-grants not found","error":"Not Found","statusCode":404}: expected 404 to be 201 // Object.is equality
- Expected
+ Received
- 201
+ 404
❯ grant tests/e2e/30-owner-decisions.e2e.ts:28:94
26| body: { role, org_unit_ids: orgUnitIds, display_name: synthetic(ro…
27| });
28| expect(response.status, `C1 POST /access-grants (${role}): ${describ…
| ^
29| 201,
30| );
❯ tests/e2e/30-owner-decisions.e2e.ts:213:24
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[34/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-10] сотрудник без согласия на биометрию → сервер сообщает терминалу «регистрация запрещена»
AssertionError: C3: HTTP 404 {"message":"Route GET:/api/v1/staff/terminal/employees/01M3EA4JGPPB7M0G78QQBQBJ1M/enrollment not found","error":"Not Found","statusCode":404}: expected 404 to be 200 // Object.is equality
- Expected
+ Received
- 200
+ 404
❯ tests/e2e/30-owner-decisions.e2e.ts:241:66
239| token: ctx().terminalToken,
240| });
241| expect(response.status, `C3: ${describeResponse(response)}`).toBe(…
| ^
242| expect(response.body).toMatchObject({ registration_allowed: false,…
243| });
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[35/38]⎯
FAIL tests/e2e/30-owner-decisions.e2e.ts > Решения владельца: роли, пакеты зарплаты, согласие на биометрию > [OWN-11] согласие отозвано → статус для терминала меняется
AssertionError: C3 PUT biometric-consent: HTTP 404 {"message":"Route PUT:/api/v1/staff/employees/01M3EA4JH57XZ361XBC2Z7SA6J/biometric-consent not found","error":"Not Found","statusCode":404}: expected 404 to be 200 // Object.is equality
- Expected
+ Received
- 200
+ 404
❯ tests/e2e/30-owner-decisions.e2e.ts:255:86
253| api('GET', `/terminal/employees/${employee!.id}/enrollment`, { t…
254| const granted = await setConsent('granted');
255| expect(granted.status, `C3 PUT biometric-consent: ${describeRespon…
| ^
256| const before = await enrollment();
257| const revoked = await setConsent('revoked');
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[36/38]⎯
FAIL tests/e2e/40-compose-pilot.e2e.ts > deploy/pilot/compose.yaml > [PILOT-1] все подставляемые переменные обязательны: ${VAR:?сообщение}
AssertionError: переменные без :? — пустое значение молча попадёт в контейнер: expected [ 'STANDALONE_MANAGER_TOKEN', …(13) ] to deeply equal []
- Expected
+ Received
- []
+ [
+ "STANDALONE_MANAGER_TOKEN",
+ "STANDALONE_TERMINAL_TOKEN",
+ "STANDALONE_TENANT_ID",
+ "STANDALONE_ACTOR_ID",
+ "STANDALONE_TERMINAL_ACTOR_ID",
+ "VAPID_PUBLIC_KEY",
+ "VAPID_PRIVATE_KEY",
+ "VAPID_SUBJECT",
+ "POSTGRES_APP_PASSWORD",
+ "HTTPS_PFX_PASSPHRASE",
+ "POSTGRES_MIGRATION_PASSWORD",
+ "POSTGRES_APP_PASSWORD",
+ "POSTGRES_MIGRATION_PASSWORD",
+ "POSTGRES_MIGRATION_PASSWORD",
+ ]
❯ tests/e2e/40-compose-pilot.e2e.ts:34:87
32| expect(interpolations.length).toBeGreaterThan(0);
33| const optional = interpolations.filter((inner) => !/^[A-Z0-9_]+:\?…
34| expect(optional, 'переменные без :? — пустое значение молча попадё…
| ^
35| });
36|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[37/38]⎯
FAIL tests/e2e/40-compose-pilot.e2e.ts > deploy/pilot/compose.yaml > [PILOT-2] ни один сервис не запускается с NODE_ENV=development
AssertionError: expected [ 'app' ] to deeply equal []
- Expected
+ Received
- []
+ [
+ "app",
+ ]
❯ tests/e2e/40-compose-pilot.e2e.ts:41:23
39| (service) => environmentOf(service).NODE_ENV === 'development',
40| );
41| expect(offenders).toEqual([]);
| ^
42| });
43|
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[38/38]⎯
Test Files 4 failed | 1 passed (5)
Tests 38 failed | 9 passed (47)
Start at 14:33:32
Duration 7.22s (tests 95%, import 3%, transform 2%)
JSON report written to /workspace/krona-staff/tests/e2e/evidence/e2e-results.json

View file

@ -0,0 +1,44 @@
| ID | Цвет | Зелёных/всего | Вердикт |
| ------- | ----- | ------------- | ----------------------------- |
| CTRL | GREEN | 2/2 | зелёный |
| F10 | RED | 0/1 | красный (известный дефект) |
| F2 | RED | 0/1 | красный (известный дефект) |
| F3 | RED | 0/1 | красный (известный дефект) |
| F4 | RED | 0/1 | красный (известный дефект) |
| F7 | RED | 0/1 | красный (известный дефект) |
| HARNESS | GREEN | 5/5 | зелёный (позитивный контроль) |
| N1 | RED | 0/1 | красный (известный дефект) |
| N10 | RED | 0/1 | красный (известный дефект) |
| N11 | RED | 0/1 | красный (известный дефект) |
| N12 | RED | 0/1 | красный (известный дефект) |
| N2 | RED | 0/1 | красный (известный дефект) |
| N3 | RED | 0/1 | красный (известный дефект) |
| N4 | RED | 0/1 | красный (известный дефект) |
| N9 | RED | 0/1 | красный (известный дефект) |
| OWN-01 | RED | 0/1 | красный (известный дефект) |
| OWN-02 | RED | 0/1 | красный (известный дефект) |
| OWN-03 | RED | 0/1 | красный (известный дефект) |
| OWN-04 | RED | 0/1 | красный (известный дефект) |
| OWN-05 | RED | 0/1 | красный (известный дефект) |
| OWN-06 | RED | 0/1 | красный (известный дефект) |
| OWN-07 | RED | 0/1 | красный (известный дефект) |
| OWN-08 | RED | 0/1 | красный (известный дефект) |
| OWN-09 | RED | 0/1 | красный (известный дефект) |
| OWN-10 | RED | 0/1 | красный (известный дефект) |
| OWN-11 | RED | 0/1 | красный (известный дефект) |
| PILOT-1 | RED | 0/1 | красный (известный дефект) |
| PILOT-2 | RED | 0/1 | красный (известный дефект) |
| PILOT-3 | GREEN | 1/1 | зелёный |
| SYNC-A | RED | 0/1 | красный (известный дефект) |
| SYNC-B | RED | 0/1 | красный (известный дефект) |
| SYNC-C | RED | 0/1 | красный (известный дефект) |
| SYNC-C0 | RED | 0/1 | красный (известный дефект) |
| SYNC-D | RED | 0/1 | красный (известный дефект) |
| SYNC-E | RED | 0/1 | красный (известный дефект) |
| SYNC-F | RED | 0/1 | красный (известный дефект) |
| SYNC-G | RED | 0/1 | красный (известный дефект) |
| SYNC-H | RED | 0/1 | красный (известный дефект) |
| SYNC-I | RED | 0/1 | красный (известный дефект) |
| SYNC-J | RED | 0/1 | красный (известный дефект) |
| SYNC-K | RED | 0/1 | красный (известный дефект) |
| SYNC-L | GREEN | 1/1 | зелёный |

View file

@ -0,0 +1,425 @@
{"level":50,"time":1790407963311,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WMRD8CMNHSB5ASJMFBS","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963325,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WMWG288RAXX5MB0GAME","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963331,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WMSF3VNWBQZ79WKKNNG","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963338,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WMXA0R6KVNMAZ62PAP6","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963345,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WN61YD42TVX52CPV29Y","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963352,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WN0ZPN48QJQF30N7F84","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963359,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WMZEPFZW4MD43ACVP7A","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963367,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WN2AXFW9XX343GSAYSW","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963374,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WN4MZ157N86APJGC2W5","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963381,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WMV8PP6Y9KPJTRXMV3B","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963412,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR5S56NK6Z7EHTXF0AX","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963420,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR9TTXP41YVMF089FDK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963426,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR6BTDQAYWCVJ544482","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963432,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR93N9FS6NJY47Z5K8T","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963441,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR6VE5SZ9XVT27NETH8","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963446,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR7ZW2HA8GW7X04F070","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963452,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR7H2A888DND2A80V6D","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963458,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR8E3C5SSTS1EZ28S0S","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963464,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR8NK7NJQFVBXZT7NR3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963470,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WR5QXAPDRTA7CT5WMDG","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963500,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WTW3GAAN5JX70CNESXB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963506,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WV0FZFTXVMET1EBJZRY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963513,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WTXJJZPWPTVB1R6CCMT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963520,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WV0PNJ2MF2VVDHCGW3C","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963532,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WTZJPMY0BR5888AQP04","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963537,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WTZWYG3FW751JS6A98B","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963543,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WTY0WE4H6HATS4ZXQS7","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963549,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WTXTTXH6FDW0K9FHXNN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963554,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WTY6460861YTBDC8JEJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963562,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WTWVZVQK74PWS4YEYSA","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963592,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXTQ1MQGD6ZGT6Z6NEN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963600,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXWTA8NVDQMKDZNC4JB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963606,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXV4877JVGAKE8QEMH9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963613,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXVEJG0SDHWEA8JRHQQ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963620,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXYC8F53J2JYPW9GYEN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963625,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXY5QK5STGXYV8A5N72","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963632,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXWEXYB2JJRB97TS6V6","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963638,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXX4RZG8AT10ZR3949K","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963643,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXXW5QCG2EN36ZABAWF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963649,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2WXW5386STRFC2ZSVTFB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963674,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0DR50W08E0TW1CJDP3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963680,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0ETN4VJ6E5S1XMJSRM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963686,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0F7CNQDM7KCBYWW10Q","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963691,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0FT5MZ86G8XCBYGVT0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963696,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0ES5PFCH22EDNXSRVA","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963701,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0G5JEFCJWAZ1672ZB2","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963708,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0F93X9X184JZ0DTAPM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963715,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0HG5RBXRHGAWM9YEKE","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963721,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0HYAKNA5F7N1TM31GR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963726,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X0G79BPG9S4WS477MEE","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963789,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X2XBGTKEMYHTVFRFT1Y","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963797,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X306DVB68DF24PN3AXY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963803,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X2YKSQR2EQPRAY1185F","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963809,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X2X8HCENQG9T653YZ7H","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963815,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X34BVPQDV95ZRJTEG8C","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963821,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X2ZY9M3A1EG0PM5M1YM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963828,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X2YARTZ4F6WVQKG8JTT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963834,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X33NXYG4RXTQVYM7B7M","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963841,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X3074X883NVBKAEPBH7","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963847,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X2ZBS9GGH585FQHC600","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963855,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X35PRRSCHX485RYE00R","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963861,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X36TW0RQ6GCT38D0RGA","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963869,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X30RSHEHPT6TKT4RA0A","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963876,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X35GSGZSGZ2QB53EZE9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963882,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X37GYFQ44242WDJ925M","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963888,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X47XAAP290ZPSD1B2MY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963893,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X310PWZXZM12NDZJ05X","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963899,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X46M8YRPTZGA8W30TAK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963907,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X48EW7RG3Q5P1PFGCDV","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963913,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X38E3GA8N20AABDZVD5","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963919,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X3EQT9RSV7QYR4ZRWGF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963925,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X3F3M3N6VJN4XGE3Y8A","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963932,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X49R4AWV6GZFZB9SDAJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963938,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X32DFS3V6T25XBS1JCH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963945,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X37AMJ23S5QXZTS3WPN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963978,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9TE8DMMHGT71KQTWVE","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963984,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9Y9EJQTH6B7482Q943","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963990,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9WGREC82MJZ9MP87X2","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407963996,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9X6KVXK4P7QGAHGZ3B","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964001,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9W1QH7Q0HHNHE596PK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964007,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9YRT3B6CJVGC8XBH8A","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964014,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9Z5G7KWKJWKYFRYGW3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964025,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9X87S66PMVGPNT11B1","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964031,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA0VEPEMTCAQXWAY20C","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964037,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA0S7Z7GSVN27FK0RRF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964043,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA0QVVZFPZNRMESZDMW","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964050,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9VDX2TF8XD2B0RV2JZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964057,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9VB432D0EN7PY9F1KB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964062,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA0ZD9KQHRZJ57YYG09","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964068,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA0ZNA8N42MS6Q8VAM0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964074,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA014GN6FM8F9EVNHFC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964079,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA08CJPQ4PF92ZZE8ZC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964085,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9Z4KDSDAW5VTJ5493V","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964091,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA0PJEE6F4YVYAHKQVP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964097,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9Z1XN8TG716AZE7EWJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964102,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA124E0FG1PFD1K6YVY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964107,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA1VKFBCRDYMP91AZF3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964112,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2X9Z3M0CW5407VQTF7ED","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964117,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA1EMVC43JRJ8BPK3Q1","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964124,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XA1K9ZY3FB1Q2618QY4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964156,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFCB9SC9W9T63A1ZQ5B","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964164,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFE2FA7V3NSD66BX231","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964170,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFFMWQ79R656KA6K3E1","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964175,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFD1F3VSSC4Z4WN0N6Z","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964181,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFF61E76M61MEJ1VP02","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964187,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFERN16DRFNQGE1G33S","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964193,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFG8VZSY2YJZZC6DSSY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964198,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFD0XTA0YHQQCY5C49A","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964205,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFHVPRN3C754PSQJQZ7","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964210,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFH5057G981ES6EPYCZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964216,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFJR26DNEYQ8ZGCNQCF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964222,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFJQQ05FYYQT4XNDFVZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964228,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFFJ6PKRNTQ0DWNB3RX","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964233,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFJ6RZPSD7RAAVK9SZ4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964239,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFJ5PHMG859R0C9SB1F","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964244,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFGBZADJY58BPVKXE29","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964249,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFHNM49XG13DKEKW0NH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964255,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFK75NJ8KA408MT2D56","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964265,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFJTAZWFKVJG5B71M63","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964271,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFKDC5FQ3M1GQVNFNDR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964276,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFHJ4CK5H9DW9P1XGXA","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964281,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFKYCE0GHBHP5ZCMYPT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964287,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFHW9D8GKFZ9Y3J4S8V","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964292,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFJRVBQT6YZA8NA146A","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964297,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XFKX8CPRJ5VA8C185RT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964328,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMRN73PCR6ATE3H1PVC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964335,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMTCCQBRNQ0T67Y6HGX","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964341,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMVMVYAT2SJNK43ECSF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964348,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMV3JJWYSX7GC1FFW2E","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964354,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMSZAHD6SBFGKJJKA8X","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964360,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMREK8AD51VMJDQF4KT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964366,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMVADWS7XGPX2B8CDQC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964372,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMWDCPQFT4PNJ0G4ZXP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964377,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMTXCH6GJVT8060GJAP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964384,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMX7WQP1JKA12FHD7R8","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964390,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMX9NSEYD5PJHQWAGTP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964395,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMS8NZVBMKQTCPEHAFP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964401,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMWCNAJ3MGDNPG76951","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964407,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMYXAWTSH7TBPT2JDGT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964412,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMXH1VP5ZTG3S1XXZZ4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964418,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMXEQWXR2NKENBZ5BQM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964423,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMXR374KPSXPF4B6QJG","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964429,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMYKTMWJ3EH8GPN92M0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964435,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMXJN79QTBAJT3TV9ES","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964440,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMXFDPGG6QZZ4EPAMHC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964445,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMX4Q7BNE2TCVGSSB3J","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964451,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMY0M84WZKHJT2HKSV3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964457,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMS76BPHAXCSCCKY5P2","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964462,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMWEKXMJHX51CMRA10F","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964467,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XMY50VMYKXWGDXR46TV","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964500,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT24NB574XWFWN98SR8","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964506,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT4JXC06KKSZX77M0PZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964513,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT30G1V2198SRDW0K8C","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964520,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT4EP2GNZDRE640NBS1","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964526,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT5SVJBGQ569N278Y90","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964531,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT6Q8JKVKKPX13K68YJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964536,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT2V7TW2N9SFGNZJZG4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964543,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT6W7MXW2P1A0V4P9D6","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964550,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT43JQA5ZSJ04J6DTY9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964555,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT2D0WVR5QFAYPVN9MH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964562,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT5T50RW8M7KAM0GNVQ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964569,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT3ZEXZPBCXNEX6C4CF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964575,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT7MA1HN042QAAHPFVD","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964581,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT6YGPWV3TRSDZGYFMM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964587,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT7R2CZ98J7QYCQ2XZ3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964593,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT61N79MRYCW30M2B7S","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964599,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT7JQCTPF8JT72JW5RY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964605,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT78QB837WH5WDZJW50","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964610,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT7H54YZ1B3DXS9M8FB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964615,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT62KADS90EG49V9CEZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964621,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT6G2FBNE7KCYVD8WTS","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964627,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT70P57ECHSJVCNGFWZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964633,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT76C11XPFH99V7HK2S","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964639,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT7938D4BK129G6Y00D","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964647,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XT7TXS05R23GAT1QTCK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964680,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZRYDQ1RFA9J9ASAS2N","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964685,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZW50956C67KTT2DH41","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964699,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZVQN75QWJ1S2GNM24R","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964706,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZSBD9WTJ2PRTRY54BS","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964711,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZT8AK3CVEQMKV55DDW","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964717,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZV5CTRB1PZTAM3FW9Z","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964723,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZTYTSWG20Q5KAE44E5","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964728,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZXHQC3BAEAG3MGDQMY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964734,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZSXY7HT6BHVS3EES82","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964740,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZX9GTC764YTCMWGXBG","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964747,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZVE55P7BR7M1Z07H7E","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964754,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZXTE7D1QEDW8XF8H7R","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964759,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZW4WSK4XGS1R4TFRJN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964764,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZXYZSQJAWM9W564ACQ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964771,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZXTPQWVM1YET03ZQJP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964777,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZX9X1EF4AXG4GM2KX0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964783,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZYE18WNB3Y3NYF4QVF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964789,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZZ0THT610YYWWJMWES","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964794,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZYBB8W0KX81ZWY3A5R","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964800,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0KWTYH51GYGY8RTQ7E","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43906},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964807,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZXDMGP4AQPM597JHRV","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964812,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0KQWYY6WRGMXRQ21D0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43894},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964818,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZY5G9X4RQNA006SNW7","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964824,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZYMW881NSMWDX6EBSH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964830,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0MQZ86WVEJBX4EG2A2","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43928},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964837,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0M4WRW53H1BKJGHJ5Y","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43944},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964842,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0MHNPHR49YZ2TV788K","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43918},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964848,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0KVTE5TKV6CXYC6QDC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43916},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964854,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0MJG1GT81JW3YHPPTF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43962},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964860,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0MTTPWRDMNXRPD8HHP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43992},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964865,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0KZSVSCQHYJES12M7Z","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43892},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964871,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZY1S5ESWG25P982Q57","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964877,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZY2JS5D989YRNRXA67","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964883,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2XZZB80CSCCHNK1GNCE5","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964889,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0NGVGYA7HPR5VTFPPF","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44014},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964895,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0NZZ5H29M3NDBP95AZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44022},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964901,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0NX2W04XPC2AZW8E2T","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44034},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964908,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0MW9QD684TRVF69NZ2","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43978},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964914,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0N70Q70HT5DC9AVCRE","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44032},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964921,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0NFH191EAHW8N5KTKE","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44042},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964926,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0PD8CR9M02RK2ATYDE","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44090},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964931,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0MWCWGC4GKYRGZGJZJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43948},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964936,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0PZCC413TQ6MP0TRQP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44080},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964941,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0NQNSEWMBR0486JNWC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44054},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964947,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0NSX46DV7P73B3TRC8","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44008},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964954,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0PDBEBK3HRPSAXN7VK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44120},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964959,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0N6HNP1C8BRD0W42C0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44070},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964965,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0PK43FJ929JGG54YQN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44128},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964970,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0P7DA2KYH6JNJ2PDA5","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44112},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407964976,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Y0PF7R7DFRVSW8T5FS3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44102},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965016,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA36BF3P24RJ9SKX34B","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965022,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA39KYMA48Z3TPB7NAK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965028,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA6H6JQG2Q1E1RMXV6R","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965034,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA7CF5MCMDY4KDR39QP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965039,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA8CQ0RSW12TSMDAFF4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965045,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA4CJR8K7R1M3M82TWR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965052,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA4TQX8RF6TV0RSQ1ZY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965057,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA5VXDVTAT12PEQBQSC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965063,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA92667DT1DH6R4R01P","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965068,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA658K4GZEPZSVWW7QX","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965074,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA7306DGWX7K1PCE5T4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965080,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA9TMM1QFMJD91YQPTB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965086,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA8FRY47X3P22M5D1WE","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965092,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA8TZFG6Q5CK8G54D92","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965098,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA8SGGAD06FT56WY073","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965103,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA9JHF39K08JB7XWCZE","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965109,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA92D1CFHEF6M838NHD","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965116,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA9SB4ESYZTSJW4X3Q9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965122,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAA9SDTX0MX796MCRZN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965127,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAAZS5377NVG34RXACC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43906},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965133,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA9PDT48B3Q203S4Z2D","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965139,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAAHYZADFD8JTGF3SN2","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965144,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA963VJ505CRYSF95ME","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965150,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA8V97B41TV9RKCC3Z0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965156,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YABVSDB8N0X3XK28Y2N","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43928},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965161,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YABW4PJ30ZBP8DBB4QM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43918},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965168,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAA4YWNQSGSSG8RYE7M","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43916},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965173,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA56JJYYK1FE7ZY3AZK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965178,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAACHJVKGK5WJPQPRKN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43894},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965184,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YABWE5RVMA0V67YY7FX","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43944},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965190,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YABKQP0TA9C5E4E204X","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43948},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965196,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YABTBEY78C36RB8X6FZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43978},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965201,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YA911BQMZPGY9XW6N7F","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965212,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAA4FKWGCWBWFY56T0G","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43892},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965217,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YACT1NJ7DWZWM4PS80Y","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44022},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965222,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAB3MNS49K6K991YMWH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44014},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965227,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAB66GP4FE1Y8HAX0YH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43992},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965233,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YABHD4GQP7WPG5CRNGT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43962},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965238,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YACMR0RPCXY9XKF29B1","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44032},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965244,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YACRBTBTZ6KYS2BEWA3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44034},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965250,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAC0Z83WPN3KK1KZ2G2","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44042},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965255,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YADH3FCP66EKN1XA0RR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44102},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965260,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YADETCSN2DP6FYK619W","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44112},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965267,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAB3D9P3RQ54E5QXFG6","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44008},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965273,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YACSSAWH4ERMM10WZHW","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44080},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965279,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YADRPT6D69QPQ9HZWQV","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44128},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965284,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAC6RKR8DN5HPMEMWST","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44070},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965289,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YADC8XHDDZB7TK5EW1Y","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44090},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965293,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YADRQN6ABZ07BKN25ZB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44120},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965299,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YAC9PRJ21A4R4HSKXQM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44054},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965332,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM3VZYNCDHRJ08BZ28F","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965339,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM40WYDVMMMWEGF4VSD","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965344,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM74YTH1R30R204S0P3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965351,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM7Y4NEM06JZG6H35HY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965356,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM5S6C3846JGCYM5HYA","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965362,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM6T4MCTCZ9MNGHQFNA","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965369,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM5XMP4GN9VB69XSVHB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965375,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM6ZE3NNVGG4Z6A8R8Q","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965381,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM891SXA4N2QNNK6R35","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965388,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM5J46VAB4K9E73RM5P","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965393,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM3NS8JH2NWPZPS7PZ9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965398,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM8JFPSGEDXNC05RMKC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965405,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM8GX0V7Q1NEQ7YK578","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965413,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM8WQJZJSXSN389JHC5","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965418,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM7XYZKDFAGVS68ZCBY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965424,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM893G0FFHQZ9X6MXS4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965429,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM7PEFVY2D2AYT8M7P4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965435,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM97EGNADPKJE3FR0ME","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965444,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM4K8Z8HK0X02B8J655","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965452,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM89ZK5BV2MW0CAE22X","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965458,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM87054EXYKYXE97R2Y","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965463,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM96PDVFN59EEVCPQ4T","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43892},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965469,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM91NZKEGSZXN27XS84","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43906},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965475,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM91TEDCZDKWYPBH0JQ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43918},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965480,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM8AFRQCKHSD0CJDNH5","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965486,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM9N3CR0TJ46B21PQSC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965491,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM9KZFZDCQDCR3J2A7G","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965497,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMA3XRG2ASSZF2BV7KH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43928},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965502,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMATNGRG9XT01VDMCCK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43948},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965507,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMAFHHD3SASE6YBGNKK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43992},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965512,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMA3TJFJGYWYNNYE5H6","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43944},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965518,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM9Z758WF96P9N779RY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43916},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965524,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM9N3A0FT5NVX8JRXKR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965529,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMB5MQMFJ00Y7RJWD81","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44034},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965535,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMB4BPY4P0PHY108ZNR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44032},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965541,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMAPXXA6PJRJ7EJ3M74","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43962},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965547,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMBT3ETTERG26CMV8XJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44022},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965553,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMAXFZT6X42PM7MC8TB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44014},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965558,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMB0YBKZ6DHKCW3KVFJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44080},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965565,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMAPMFTVDSD87TBB91F","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44008},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965570,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMBDEBD7ZND56AH840S","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44054},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965575,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMBM779ZE2DBH05NSE7","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44112},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965581,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMBNZD3PT75A3BRFV26","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44070},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965587,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YM9BW06B1N3A3R2EHP9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43894},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965592,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMBWCFPNNC7RK170JGS","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44090},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965597,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMA3Z5S0ZZGAMFM7WJ2","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43978},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965602,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMCKW5GH6X625Q9P45X","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44120},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965608,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMCN8K7AJPPVZXSF6CT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44128},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965613,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMB93JCRFF379W6DQBH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44102},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965618,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YMB603133XQGGPJ09HN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44042},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965654,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY42AZZHP2CSM5QD51H","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965659,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY6705R9KDCPDYVDEYN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965665,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY5S8RAFHE0M86NQDZ4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965670,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY671H84ETCJJHV69K7","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965681,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY7WTHBKGDDMQZBN4GB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965686,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY8585N9VH1J3JAB2CP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965691,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY6EGZSAXYDSFXDT16J","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965698,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY7D8FJRNS3Y4VQNFAA","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965704,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY8RNBEJTP1K5EXSKX0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965710,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY7K36Y1Y37JX8QT5VM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965716,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY9MXW9KK63JP34P5X9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965722,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY9YZZ1Z4X86SC2F23N","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965727,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY9Q01D5WDCJGCSGX7M","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965732,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY8Z5P3ED5PER21T0CZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965737,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY94NDXTWXCP20SV5A1","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965744,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY98Z1E61C98CWDH9YQ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965750,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY9ZM69E4EPBT6KWD4Z","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965756,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY8NNQS3740ZFJVQSCW","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965762,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY8ADPJD91SS7WN1CZR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965767,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY9ZC9KFDW94X09XG0M","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965772,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYAVWKDQ9RSHVHRYAPG","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43892},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965778,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY9BCZCEG858SEYZWPJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965783,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY4MGKKB4E8GWZ8X1C4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965790,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYARPAGF7XA9FC72QV6","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965795,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYA7FB841BF8109WC2V","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43906},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965801,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YY5M47QR5JPYYMGKJYK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965805,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYBZJHPY029DF3975G0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43944},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965812,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYBAWPS1WP6W8W99PWS","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43978},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965817,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYAB65BX5WE894WBV9X","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43918},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965823,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYBV62PPKJ5C57GY4E9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43962},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965829,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYBTZP7ZYDSKRBXC0Q1","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44014},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965835,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYBBKA6ZYBE5X3ARFBX","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43948},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965840,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYAF600TEZ7EWNBW0HR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965845,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYANH6A95DXQKQW3E4J","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43928},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965853,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYA890DXAQ252EGN38A","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43894},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965860,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYC6PMCBC8HX7HCRQ7A","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44054},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965866,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYCCES2JMHHGEM2PPAN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44042},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965872,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYB24AMATY82EAEJ1FK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44032},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965877,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYCNK1T6GVG2Y81SEW8","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44070},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965883,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYAFR6S5V4TDR9M01Z4","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43916},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965889,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYBY6G844P4EZBK70F8","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44022},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965893,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYCN7X755NRRWH7Q0VC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44090},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965899,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYBTVRDTM1XKPR1FH61","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44034},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965903,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYB759SZTK1707Y6CVM","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43992},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965909,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYBY443NXAGQ0TQ7KVX","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44008},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965915,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYCC0ECBBQT0FKPMPD3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44112},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965921,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYCCTRMMZJ6X8SVGTZ0","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44102},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965927,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYC981T139JP60STH3D","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44128},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965934,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYCT20MN11WTC7TXND3","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44120},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965940,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2YYC8SKBX1ACPZ0X3ANT","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44080},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965979,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z82PF421QGEA433F0J5","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43656},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965984,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z853ZC384RKZ3GRCPBK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43740},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965990,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z84SZDS35KT0F0TFEXY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43726},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407965995,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z878Y4W6AXHC44H4M48","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43774},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966001,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z85449RSNZNCCXBA5SR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43728},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966007,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z84VST39574Z9TTNSAW","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43696},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966012,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z86RSGEJB76S19ZJYTH","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43748},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966018,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z87YAM0E2W3WRXH4A2T","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966024,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z87MBW2KWDGAE4MAAAC","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43792},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966030,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z839DCTZQCDDF2G1TQP","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43668},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966036,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z866R1TF6A0V8SW5SXR","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43760},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966043,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z86VJE6A4R6HR1MZ1QN","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43768},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966049,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z87BN3E8614Q3NZZME8","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43812},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966054,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z87GPC9G8MAGDK8DHJV","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43788},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966060,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z889N4HRHA1N8HJ5DQG","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43848},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966068,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z87GCARD3FJ10KXR424","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43828},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966075,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z883G5TQ5CJGZTCK5D9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43834},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966080,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z83J7K3GC393YWPSN0X","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43684},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966088,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z84SDHESVNJ58ZYYF1B","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43710},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966093,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8852W9KKHP616R5G2N","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43872},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966099,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z88NJ8SCF82A7YMHKHD","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43844},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966106,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z88C6A6J21GZTC139JD","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43850},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966112,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z893ZQDZDQ85VXRY5VK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43886},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966119,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z89R8297RXNR7QRGKEZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43892},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966126,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8AS1QPV0M8860CCP91","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43944},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966131,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z89SHYVET82FT28W07F","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43882},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966136,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8AA65NVS2PQ1GAXG98","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43918},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966142,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z88KYARSKGTTPR5A99N","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43862},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966152,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z89AK2EGF0THM2QR8H9","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43916},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966158,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8BA9NNV6THDDTGCCMK","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44014},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966163,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z89S9V69EEQBAMEED5N","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43906},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966168,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8ANH9J60334K44XNPJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43962},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966174,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8AQKJF1XN2NDDS864X","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43928},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966179,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8BDSMZMSPDB566DDBZ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44022},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966185,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8ASEVQMQ1R6GX92NND","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43978},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966190,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8B9ERJNWRZRS6419CQ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44032},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966195,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8B0QQD0RRQQTSN8P63","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44034},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966200,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8BVZ6YGQ3ZT67BXB04","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44042},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966206,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z89TKFEQ4H2SKGCQRGD","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43894},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966210,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8C3PPTDCAXG4FW46DY","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44090},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966215,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8B6WA84WC71GWYP20G","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44008},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966225,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8A319FY032CNA3VPTB","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43992},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966230,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8CV5X8CCSJNWK9ACXS","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44120},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966235,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8C07SAMHFQXX12J01F","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44102},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966240,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8CR9E6TXJ4S0V0CJNA","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44128},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966245,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8A08N2PFP6K7CC94Y6","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":43948},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966251,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8BMXA4GBCV9DTRSN93","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44070},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966260,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8C2Q0D58VJCBEQDQ46","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44080},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966265,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8CAPNAAFC9Z5H5D6BJ","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44112},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":50,"time":1790407966271,"pid":1686260,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA2Z8B7J6KW3JPGG1NMT0S","req":{"method":"POST","url":"/api/v1/staff/payroll/calculate","host":"127.0.0.1:42341","remoteAddress":"127.0.0.1","remotePort":44054},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async calculatePayrollPeriod (/workspace/krona-staff/src/domain/payroll/service.ts:770:3)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:687:24)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}

View file

@ -0,0 +1,11 @@
{"level":30,"time":1790408014423,"pid":1688835,"hostname":"grok-bot-vm-420973429","msg":"Server listening at http://127.0.0.1:33821"}
{"level":30,"time":1790408014470,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4EM59MB3QYQ7QG56R4Q6","req":{"method":"GET","url":"/api/v1/staff/ready","host":"127.0.0.1:33821","remoteAddress":"127.0.0.1","remotePort":43800},"msg":"incoming request"}
{"level":30,"time":1790408014485,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4EM59MB3QYQ7QG56R4Q6","res":{"statusCode":200},"responseTime":15.399766999999997,"msg":"request completed"}
{"level":30,"time":1790408017988,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J24H0CNE1DPZ87J7PY6","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:33821","remoteAddress":"127.0.0.1","remotePort":41914},"msg":"incoming request"}
{"level":30,"time":1790408017995,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J24H0CNE1DPZ87J7PY6","res":{"statusCode":200},"responseTime":7.126036999999997,"msg":"request completed"}
{"level":30,"time":1790408017997,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2CSDE96DCZ4X0TSJ1E","req":{"method":"GET","url":"/api/v1/staff/payroll","host":"127.0.0.1:33821","remoteAddress":"127.0.0.1","remotePort":41916},"msg":"incoming request"}
{"level":30,"time":1790408018000,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2CSDE96DCZ4X0TSJ1E","res":{"statusCode":200},"responseTime":3.394659000000047,"msg":"request completed"}
{"level":30,"time":1790408018001,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2HH1VC67KYM9CGFM3R","req":{"method":"POST","url":"/api/v1/staff/professions","host":"127.0.0.1:33821","remoteAddress":"127.0.0.1","remotePort":41914},"msg":"incoming request"}
{"level":30,"time":1790408018006,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2HH1VC67KYM9CGFM3R","res":{"statusCode":201},"responseTime":4.0853070000002845,"msg":"request completed"}
{"level":30,"time":1790408018939,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZTH0S49N5WD7NP5DXV","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:33821","remoteAddress":"127.0.0.1","remotePort":41926},"msg":"incoming request"}
{"level":30,"time":1790408018943,"pid":1688835,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZTH0S49N5WD7NP5DXV","res":{"statusCode":201},"responseTime":4.126679999999396,"msg":"request completed"}

View file

@ -0,0 +1,93 @@
{"level":30,"time":1790408014985,"pid":1688859,"hostname":"grok-bot-vm-420973429","msg":"Server listening at http://127.0.0.1:36299"}
{"level":30,"time":1790408014994,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4F4HH3VG14PERD1YSY9Y","req":{"method":"GET","url":"/api/v1/staff/ready","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":38380},"msg":"incoming request"}
{"level":30,"time":1790408015008,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4F4HH3VG14PERD1YSY9Y","res":{"statusCode":200},"responseTime":13.205045999999982,"msg":"request completed"}
{"level":30,"time":1790408018078,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J4YV0JF6R2376AEHJPT","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018085,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J4YV0JF6R2376AEHJPT","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018088,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J4YV0JF6R2376AEHJPT","res":{"statusCode":401},"responseTime":10.026388999999654,"msg":"request completed"}
{"level":30,"time":1790408018090,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5AY86FT8CXCVMZBCVE","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018092,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5AY86FT8CXCVMZBCVE","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018093,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5AY86FT8CXCVMZBCVE","res":{"statusCode":401},"responseTime":3.1223180000001776,"msg":"request completed"}
{"level":30,"time":1790408018094,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5EVV7MG8NSJEN3BEHE","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018095,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5EVV7MG8NSJEN3BEHE","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018095,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5EVV7MG8NSJEN3BEHE","res":{"statusCode":401},"responseTime":1.5804190000003473,"msg":"request completed"}
{"level":30,"time":1790408018096,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5GS3DNBZVF696K10GB","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018097,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5GS3DNBZVF696K10GB","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018098,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5GS3DNBZVF696K10GB","res":{"statusCode":401},"responseTime":1.4676269999999931,"msg":"request completed"}
{"level":30,"time":1790408018099,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5J8T6KXH5TFHHSCHVF","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018100,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5J8T6KXH5TFHHSCHVF","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018100,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5J8T6KXH5TFHHSCHVF","res":{"statusCode":401},"responseTime":1.386855000000196,"msg":"request completed"}
{"level":30,"time":1790408018101,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5NP6FY0C583X92CP43","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018102,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5NP6FY0C583X92CP43","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018102,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5NP6FY0C583X92CP43","res":{"statusCode":401},"responseTime":1.2076160000001437,"msg":"request completed"}
{"level":30,"time":1790408018103,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5Q5TRCA85QYA3H0VYQ","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018104,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5Q5TRCA85QYA3H0VYQ","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018104,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5Q5TRCA85QYA3H0VYQ","res":{"statusCode":401},"responseTime":1.1122859999995853,"msg":"request completed"}
{"level":30,"time":1790408018105,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5SA4BPNWS2DED9PXYB","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018107,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5SA4BPNWS2DED9PXYB","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018107,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5SA4BPNWS2DED9PXYB","res":{"statusCode":401},"responseTime":1.8221369999996568,"msg":"request completed"}
{"level":30,"time":1790408018108,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5WVAX2TGTKMNXF5TMG","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018110,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5WVAX2TGTKMNXF5TMG","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018110,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5WVAX2TGTKMNXF5TMG","res":{"statusCode":401},"responseTime":1.6929129999998622,"msg":"request completed"}
{"level":30,"time":1790408018111,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5ZJ0TBAM6HCKDG31ST","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018112,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5ZJ0TBAM6HCKDG31ST","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018112,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J5ZJ0TBAM6HCKDG31ST","res":{"statusCode":401},"responseTime":1.3584950000004028,"msg":"request completed"}
{"level":30,"time":1790408018113,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J61SAXX1SBMMF6K7MW7","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018114,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J61SAXX1SBMMF6K7MW7","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018115,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J61SAXX1SBMMF6K7MW7","res":{"statusCode":401},"responseTime":1.17779500000006,"msg":"request completed"}
{"level":30,"time":1790408018116,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J64PXWG5P4DSGFA9VDQ","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018117,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J64PXWG5P4DSGFA9VDQ","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018117,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J64PXWG5P4DSGFA9VDQ","res":{"statusCode":401},"responseTime":1.2440259999998489,"msg":"request completed"}
{"level":30,"time":1790408018118,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J665CYSPZZM1V2R18JN","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018119,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J665CYSPZZM1V2R18JN","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018120,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J665CYSPZZM1V2R18JN","res":{"statusCode":401},"responseTime":1.6543000000001484,"msg":"request completed"}
{"level":30,"time":1790408018120,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J681X6JYH17BSE6KS7T","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018121,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J681X6JYH17BSE6KS7T","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018121,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J681X6JYH17BSE6KS7T","res":{"statusCode":401},"responseTime":0.9558520000000499,"msg":"request completed"}
{"level":30,"time":1790408018122,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6AZB9EF2ZWRM58K33X","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018124,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6AZB9EF2ZWRM58K33X","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018124,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6AZB9EF2ZWRM58K33X","res":{"statusCode":401},"responseTime":1.3041690000000017,"msg":"request completed"}
{"level":30,"time":1790408018125,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6DANVFJ43ANCSWN2AD","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018126,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6DANVFJ43ANCSWN2AD","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018126,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6DANVFJ43ANCSWN2AD","res":{"statusCode":401},"responseTime":1.0975260000000162,"msg":"request completed"}
{"level":30,"time":1790408018127,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6FB5G9XGHEX6J2DQD9","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018128,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6FB5G9XGHEX6J2DQD9","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018128,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6FB5G9XGHEX6J2DQD9","res":{"statusCode":401},"responseTime":0.9584480000003168,"msg":"request completed"}
{"level":30,"time":1790408018129,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6HN1B0FT6JSM29WA43","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018129,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6HN1B0FT6JSM29WA43","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018130,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6HN1B0FT6JSM29WA43","res":{"statusCode":401},"responseTime":0.8860890000000836,"msg":"request completed"}
{"level":30,"time":1790408018130,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6JYZVQY0HTDDS7J417","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018131,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6JYZVQY0HTDDS7J417","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018131,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6JYZVQY0HTDDS7J417","res":{"statusCode":401},"responseTime":1.0295750000000226,"msg":"request completed"}
{"level":30,"time":1790408018132,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6MATZ7QY0BR7V8AW72","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018133,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6MATZ7QY0BR7V8AW72","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018133,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6MATZ7QY0BR7V8AW72","res":{"statusCode":401},"responseTime":0.9096939999999449,"msg":"request completed"}
{"level":30,"time":1790408018134,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6PDK66S783WHQ51ASV","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018135,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6PDK66S783WHQ51ASV","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018135,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6PDK66S783WHQ51ASV","res":{"statusCode":401},"responseTime":0.9012949999996636,"msg":"request completed"}
{"level":30,"time":1790408018136,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6R8EVAMEACB5RG5PMT","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018137,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6R8EVAMEACB5RG5PMT","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018137,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6R8EVAMEACB5RG5PMT","res":{"statusCode":401},"responseTime":0.97691500000019,"msg":"request completed"}
{"level":30,"time":1790408018137,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6S4NWEJWJSHW2QW0H1","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018138,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6S4NWEJWJSHW2QW0H1","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018139,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6S4NWEJWJSHW2QW0H1","res":{"statusCode":401},"responseTime":1.0356249999999818,"msg":"request completed"}
{"level":30,"time":1790408018139,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6V5MVSWERJFSE4H8S1","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018140,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6V5MVSWERJFSE4H8S1","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018140,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6V5MVSWERJFSE4H8S1","res":{"statusCode":401},"responseTime":0.9596630000000914,"msg":"request completed"}
{"level":30,"time":1790408018141,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6X3SS6P42S0J20JY43","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018142,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6X3SS6P42S0J20JY43","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018142,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6X3SS6P42S0J20JY43","res":{"statusCode":401},"responseTime":0.8438820000001215,"msg":"request completed"}
{"level":30,"time":1790408018143,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6ZGJ3J8AZ6CADNGANJ","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018144,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6ZGJ3J8AZ6CADNGANJ","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018144,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J6ZGJ3J8AZ6CADNGANJ","res":{"statusCode":401},"responseTime":1.0216669999999795,"msg":"request completed"}
{"level":30,"time":1790408018145,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J70HW4EQGVGGWZBSN09","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018146,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J70HW4EQGVGGWZBSN09","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018146,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J70HW4EQGVGGWZBSN09","res":{"statusCode":401},"responseTime":1.648689000000104,"msg":"request completed"}
{"level":30,"time":1790408018147,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J73XM8Q0YNRJ914G8W1","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018148,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J73XM8Q0YNRJ914G8W1","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018148,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J73XM8Q0YNRJ914G8W1","res":{"statusCode":401},"responseTime":0.967511000000286,"msg":"request completed"}
{"level":30,"time":1790408018149,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J74SQB99XZJCVDXJNMT","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34810},"msg":"incoming request"}
{"level":30,"time":1790408018149,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J74SQB99XZJCVDXJNMT","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018149,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J74SQB99XZJCVDXJNMT","res":{"statusCode":401},"responseTime":0.8698090000002594,"msg":"request completed"}
{"level":30,"time":1790408018150,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J76XMMPD5PD7AKCYR2N","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:36299","remoteAddress":"127.0.0.1","remotePort":34822},"msg":"incoming request"}
{"level":30,"time":1790408018151,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J76XMMPD5PD7AKCYR2N","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:253:23)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408018151,"pid":1688859,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J76XMMPD5PD7AKCYR2N","res":{"statusCode":401},"responseTime":1.0111910000000535,"msg":"request completed"}

View file

@ -0,0 +1,279 @@
{"level":30,"time":1790408013912,"pid":1688811,"hostname":"grok-bot-vm-420973429","msg":"Server listening at http://127.0.0.1:35389"}
{"level":30,"time":1790408013941,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4E3M5MJKAGV50FFXN9SZ","req":{"method":"GET","url":"/api/v1/staff/ready","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41352},"msg":"incoming request"}
{"level":30,"time":1790408013957,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4E3M5MJKAGV50FFXN9SZ","res":{"statusCode":200},"responseTime":16.484744000000035,"msg":"request completed"}
{"level":30,"time":1790408015166,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4F9X4201XC0AAD6DNBP5","req":{"method":"POST","url":"/api/v1/staff/employees","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":50,"time":1790408015172,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4F9X4201XC0AAD6DNBP5","req":{"method":"POST","url":"/api/v1/staff/employees","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"inconsistent types deduced for parameter $2","stack":"error: inconsistent types deduced for parameter $2\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async <anonymous> (/workspace/krona-staff/src/portal.ts:465:25)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:461:24)","length":155,"name":"error","severity":"ERROR","code":"42P08","detail":"text versus character varying","position":"150","file":"parse_param.c","line":"219","routine":"variable_coerce_param_hook"},"msg":"inconsistent types deduced for parameter $2"}
{"level":30,"time":1790408015177,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4F9X4201XC0AAD6DNBP5","res":{"statusCode":500},"responseTime":11.21852100000001,"msg":"request completed"}
{"level":30,"time":1790408015188,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FAMNJX2833KF1T4TTXN","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408015205,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FAMNJX2833KF1T4TTXN","res":{"statusCode":202},"responseTime":17.02252499999986,"msg":"request completed"}
{"level":30,"time":1790408015223,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FBQJSK6DGCRM59J8R5P","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015232,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FBQJSK6DGCRM59J8R5P","res":{"statusCode":202},"responseTime":9.666789000000108,"msg":"request completed"}
{"level":30,"time":1790408015242,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FCAV488NV3PYX6F3FJA","req":{"method":"GET","url":"/api/v1/staff/pay-rules","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015247,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FCAV488NV3PYX6F3FJA","res":{"statusCode":200},"responseTime":4.858270000000175,"msg":"request completed"}
{"level":30,"time":1790408015249,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FCGJF6Z76CTR188VGCN","req":{"method":"PUT","url":"/api/v1/staff/employees/01M3EA4FBZ4PJA3W2WDRQSRQSA/pay-assignment","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408015257,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FCGJF6Z76CTR188VGCN","res":{"statusCode":200},"responseTime":8.3228059999999,"msg":"request completed"}
{"level":30,"time":1790408015259,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FCVQ0FHFZTP5RX5VGFS","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015262,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FCVQ0FHFZTP5RX5VGFS","res":{"statusCode":201},"responseTime":3.2303699999999935,"msg":"request completed"}
{"level":30,"time":1790408015264,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FCZJ2ZQZ454GQVQ000V","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408015272,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FCZJ2ZQZ454GQVQ000V","res":{"statusCode":201},"responseTime":8.185108000000128,"msg":"request completed"}
{"level":30,"time":1790408015273,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FD9GB296ZS3YK71ZE6D","req":{"method":"POST","url":"/api/v1/staff/work-sessions/reconcile","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015279,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FD9GB296ZS3YK71ZE6D","res":{"statusCode":200},"responseTime":6.122667999999976,"msg":"request completed"}
{"level":30,"time":1790408015289,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FDSCE1FXX9KMABVM5TM","req":{"method":"PATCH","url":"/api/v1/staff/work-sessions/01M3EA4FDDGG7NT2PNT26E1QKB","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":50,"time":1790408015293,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FDSCE1FXX9KMABVM5TM","req":{"method":"PATCH","url":"/api/v1/staff/work-sessions/01M3EA4FDDGG7NT2PNT26E1QKB","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async <anonymous> (/workspace/krona-staff/src/portal.ts:1145:13)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:1053:23)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":30,"time":1790408015294,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FDSCE1FXX9KMABVM5TM","res":{"statusCode":500},"responseTime":4.745336999999836,"msg":"request completed"}
{"level":30,"time":1790408015297,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FE18FJJN9394Y3N6BJ5","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408015304,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FE18FJJN9394Y3N6BJ5","res":{"statusCode":202},"responseTime":6.942637999999988,"msg":"request completed"}
{"level":30,"time":1790408015313,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FEH4RF0G7FDCFWZYRG2","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015320,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FEH4RF0G7FDCFWZYRG2","res":{"statusCode":202},"responseTime":6.775562000000036,"msg":"request completed"}
{"level":30,"time":1790408015329,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FF1VZ350VV5QWXTG0CR","req":{"method":"GET","url":"/api/v1/staff/pay-rules","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015333,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FF1VZ350VV5QWXTG0CR","res":{"statusCode":200},"responseTime":3.717247000000043,"msg":"request completed"}
{"level":30,"time":1790408015334,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FF6VREYSW25ACQZKRG3","req":{"method":"PUT","url":"/api/v1/staff/employees/01M3EA4FEQWG7KW934X22C56ZR/pay-assignment","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408015340,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FF6VREYSW25ACQZKRG3","res":{"statusCode":200},"responseTime":6.012408999999934,"msg":"request completed"}
{"level":30,"time":1790408015341,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFDF0DKJ2W7ZPPDR4DV","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015344,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFDF0DKJ2W7ZPPDR4DV","res":{"statusCode":201},"responseTime":2.4532470000001467,"msg":"request completed"}
{"level":30,"time":1790408015345,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFHKWR6VMNF2WQKGBWZ","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408015346,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFHKWR6VMNF2WQKGBWZ","res":{"statusCode":201},"responseTime":1.5671030000000883,"msg":"request completed"}
{"level":30,"time":1790408015347,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFKMGVXC8YMD6PFV6W2","req":{"method":"POST","url":"/api/v1/staff/work-sessions/reconcile","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015350,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFKMGVXC8YMD6PFV6W2","res":{"statusCode":200},"responseTime":3.180074999999988,"msg":"request completed"}
{"level":30,"time":1790408015358,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFYESE8NJFN70MAFRPV","req":{"method":"PATCH","url":"/api/v1/staff/work-sessions/01M3EA4FFN6TXZWFAV7AD8W931","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":50,"time":1790408015361,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFYESE8NJFN70MAFRPV","req":{"method":"PATCH","url":"/api/v1/staff/work-sessions/01M3EA4FFN6TXZWFAV7AD8W931","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint","stack":"error: null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async <anonymous> (/workspace/krona-staff/src/portal.ts:1145:13)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:1053:23)","length":188,"name":"error","severity":"ERROR","code":"23502","schema":"public","table":"staff_outbox","column":"occurred_at","file":"execMain.c","line":"2022","routine":"ExecConstraints"},"msg":"null value in column \"occurred_at\" of relation \"staff_outbox\" violates not-null constraint"}
{"level":30,"time":1790408015361,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FFYESE8NJFN70MAFRPV","res":{"statusCode":500},"responseTime":2.768146999999999,"msg":"request completed"}
{"level":30,"time":1790408015363,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FG37GZKF5QXE421K1NS","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408015374,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FG37GZKF5QXE421K1NS","res":{"statusCode":202},"responseTime":10.611540999999988,"msg":"request completed"}
{"level":30,"time":1790408015383,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FGQ28S5QBWAQDRD3ENC","req":{"method":"POST","url":"/api/v1/staff/employees/01M3EA4FGC5Y20677SW81GPFB2/access-token","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015387,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FGQ28S5QBWAQDRD3ENC","res":{"statusCode":200},"responseTime":4.416566000000103,"msg":"request completed"}
{"level":30,"time":1790408015392,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FH06VNHJY4EBW5EE2XX","req":{"method":"POST","url":"/api/v1/staff/push/subscriptions","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408015397,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FH06VNHJY4EBW5EE2XX","res":{"statusCode":201},"responseTime":4.635773999999856,"msg":"request completed"}
{"level":30,"time":1790408015398,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FH57Y74WHQVGP02939Q","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408015401,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4FH57Y74WHQVGP02939Q","res":{"statusCode":201},"responseTime":2.8056480000000192,"msg":"request completed"}
{"level":30,"time":1790408017908,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4HZMM5H00GW47QM8H57P","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408017915,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4HZMM5H00GW47QM8H57P","res":{"statusCode":202},"responseTime":6.821124000000054,"msg":"request completed"}
{"level":30,"time":1790408017927,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J070MWKRVC3R9SEXHZZ","req":{"method":"POST","url":"/api/v1/staff/employees/01M3EA4HZSY982GYTPDAVP0Z0Q/access-token","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408017932,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J070MWKRVC3R9SEXHZZ","res":{"statusCode":200},"responseTime":4.815638999999464,"msg":"request completed"}
{"level":30,"time":1790408017933,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J0D6X5ZRVMAHE2KHFP0","req":{"method":"POST","url":"/api/v1/staff/employees/01M3EA4HZTSZ12MKP3SV134FKS/access-token","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408017935,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J0D6X5ZRVMAHE2KHFP0","res":{"statusCode":200},"responseTime":2.3987600000000384,"msg":"request completed"}
{"level":30,"time":1790408017936,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J0GAPK6MYZKS6CEP69P","req":{"method":"POST","url":"/api/v1/staff/push/subscriptions","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408017938,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J0GAPK6MYZKS6CEP69P","res":{"statusCode":201},"responseTime":1.9624579999999696,"msg":"request completed"}
{"level":30,"time":1790408017939,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J0K1RMKPTCT5QNAGV7A","req":{"method":"POST","url":"/api/v1/staff/push/subscriptions","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408017941,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J0K1RMKPTCT5QNAGV7A","res":{"statusCode":201},"responseTime":2.340323000000353,"msg":"request completed"}
{"level":30,"time":1790408017952,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J10VK1XV0ZMVF812CYW","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408017958,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J10VK1XV0ZMVF812CYW","res":{"statusCode":202},"responseTime":5.686529999999948,"msg":"request completed"}
{"level":30,"time":1790408017965,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J1DG7KEQN92H5D256PE","req":{"method":"GET","url":"/api/v1/staff/pay-rules","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408017970,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J1DG7KEQN92H5D256PE","res":{"statusCode":200},"responseTime":4.494719000000259,"msg":"request completed"}
{"level":30,"time":1790408017971,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J1KMHYPJ01JH6Z2WEQK","req":{"method":"PUT","url":"/api/v1/staff/employees/01M3EA4J151B1H9D5AKAR29AN9/pay-assignment","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408017976,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J1KMHYPJ01JH6Z2WEQK","res":{"statusCode":200},"responseTime":5.194629999999961,"msg":"request completed"}
{"level":30,"time":1790408017977,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J1S0SNJZ8H7X0K9F7T1","req":{"method":"PUT","url":"/api/v1/staff/employees/01M3EA4J151B1H9D5AKAR29AN9/pay-assignment","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408017981,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J1S0SNJZ8H7X0K9F7T1","res":{"statusCode":200},"responseTime":4.459873999999218,"msg":"request completed"}
{"level":30,"time":1790408017983,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J1ZDTDW66WF28KDYB4W","req":{"method":"GET","url":"/api/v1/staff/professions","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408017984,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J1ZDTDW66WF28KDYB4W","res":{"statusCode":200},"responseTime":1.0135330000002796,"msg":"request completed"}
{"level":30,"time":1790408017985,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J208WKMDXHJERS4H6MT","req":{"method":"GET","url":"/api/v1/staff/org-units","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408017986,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J208WKMDXHJERS4H6MT","res":{"statusCode":200},"responseTime":1.3112160000000586,"msg":"request completed"}
{"level":30,"time":1790408018007,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2Q3T2JSPF95TG96N6P","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408018008,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2Q3T2JSPF95TG96N6P","res":{"statusCode":200},"responseTime":0.6348109999998996,"msg":"request completed"}
{"level":30,"time":1790408018009,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2SK303DG80T5VC5DDC","req":{"method":"DELETE","url":"/api/v1/staff/session","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408018009,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2SK303DG80T5VC5DDC","res":{"statusCode":204},"responseTime":0.33697699999993347,"msg":"request completed"}
{"level":30,"time":1790408018010,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2S1XNED469T2N44WFY","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408018013,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2S1XNED469T2N44WFY","res":{"statusCode":200},"responseTime":3.6036009999997987,"msg":"request completed"}
{"level":30,"time":1790408018015,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2Z7TW54HTHRM9B7PFS","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408018016,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J2Z7TW54HTHRM9B7PFS","res":{"statusCode":200},"responseTime":0.40848600000026636,"msg":"request completed"}
{"level":30,"time":1790408018017,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J31AWQFE866QK3R19T8","req":{"method":"POST","url":"/api/v1/staff/professions","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408018019,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J31AWQFE866QK3R19T8","res":{"statusCode":201},"responseTime":2.3794800000005125,"msg":"request completed"}
{"level":30,"time":1790408018021,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J35B5NNN9AVW7EH7XVR","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408018027,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J35B5NNN9AVW7EH7XVR","res":{"statusCode":202},"responseTime":6.364180999999917,"msg":"request completed"}
{"level":30,"time":1790408018037,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J3NFJ32S6B487DGQF3F","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408018040,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J3NFJ32S6B487DGQF3F","res":{"statusCode":201},"responseTime":3.285291999999572,"msg":"request completed"}
{"level":30,"time":1790408018041,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J3S918GM99F9BXZKYHD","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41370},"msg":"incoming request"}
{"level":30,"time":1790408018051,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J3S918GM99F9BXZKYHD","res":{"statusCode":201},"responseTime":9.325840999999855,"msg":"request completed"}
{"level":30,"time":1790408018052,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J44HBZG5R6A7238SHNC","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":30,"time":1790408018059,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J44HBZG5R6A7238SHNC","res":{"statusCode":202},"responseTime":6.6378679999997985,"msg":"request completed"}
{"level":30,"time":1790408018068,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J4MJ6D7YHY7NJP8XW6B","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"msg":"incoming request"}
{"level":50,"time":1790408018073,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J4MJ6D7YHY7NJP8XW6B","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":41366},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"new row for relation \"staff_payroll_ledger\" violates check constraint \"staff_payroll_ledger_kind_check\"","stack":"error: new row for relation \"staff_payroll_ledger\" violates check constraint \"staff_payroll_ledger_kind_check\"\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async <anonymous> (/workspace/krona-staff/src/operations.ts:1033:13)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/operations.ts:813:22)","length":229,"name":"error","severity":"ERROR","code":"23514","schema":"public","table":"staff_payroll_ledger","constraint":"staff_payroll_ledger_kind_check","file":"execMain.c","line":"2074","routine":"ExecConstraints"},"msg":"new row for relation \"staff_payroll_ledger\" violates check constraint \"staff_payroll_ledger_kind_check\""}
{"level":30,"time":1790408018076,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4J4MJ6D7YHY7NJP8XW6B","res":{"statusCode":500},"responseTime":7.259319999999207,"msg":"request completed"}
{"level":30,"time":1790408018281,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JB912NAAC419Y02QPGD","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018289,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JB912NAAC419Y02QPGD","res":{"statusCode":202},"responseTime":7.542034999999487,"msg":"request completed"}
{"level":30,"time":1790408018310,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JC6JJ5PE5S4M8MJAPYQ","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018323,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JC6JJ5PE5S4M8MJAPYQ","res":{"statusCode":202},"responseTime":12.457030999999915,"msg":"request completed"}
{"level":30,"time":1790408018333,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JCXCHJFD211C4GCEFKB","req":{"method":"GET","url":"/api/v1/staff/pay-rules","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018338,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JCXCHJFD211C4GCEFKB","res":{"statusCode":200},"responseTime":4.526701000000685,"msg":"request completed"}
{"level":30,"time":1790408018340,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JD4NWCFKZRS9ENNQ1RR","req":{"method":"PUT","url":"/api/v1/staff/employees/01M3EA4JCJZDWYMA296ZFPY4DF/pay-assignment","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018346,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JD4NWCFKZRS9ENNQ1RR","res":{"statusCode":200},"responseTime":5.515754999999444,"msg":"request completed"}
{"level":30,"time":1790408018348,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDC28B95P2KDW019QM5","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018350,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDC28B95P2KDW019QM5","res":{"statusCode":201},"responseTime":1.652274000000034,"msg":"request completed"}
{"level":30,"time":1790408018351,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDFHP41V6MX75HC8BA2","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018353,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDFHP41V6MX75HC8BA2","res":{"statusCode":201},"responseTime":1.7120279999999184,"msg":"request completed"}
{"level":30,"time":1790408018354,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDJP8QC0RWYNJG3BAWE","req":{"method":"POST","url":"/api/v1/staff/work-sessions/reconcile","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018357,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDJP8QC0RWYNJG3BAWE","res":{"statusCode":200},"responseTime":3.009777999999642,"msg":"request completed"}
{"level":30,"time":1790408018366,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDY7YVS8NFMK6B159M9","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018367,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDY7YVS8NFMK6B159M9","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018367,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JDY7YVS8NFMK6B159M9","res":{"statusCode":404},"responseTime":0.45273399999950925,"msg":"request completed"}
{"level":30,"time":1790408018373,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JE5C72SJMQT011VRYK0","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018380,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JE5C72SJMQT011VRYK0","res":{"statusCode":202},"responseTime":6.309143000000404,"msg":"request completed"}
{"level":30,"time":1790408018391,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JEQ53Q7Q75D8JNWM330","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018395,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JEQ53Q7Q75D8JNWM330","res":{"statusCode":202},"responseTime":4.627241999999569,"msg":"request completed"}
{"level":30,"time":1790408018403,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JF35G4F1KTESX0J64QY","req":{"method":"GET","url":"/api/v1/staff/pay-rules","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018406,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JF35G4F1KTESX0J64QY","res":{"statusCode":200},"responseTime":2.5201289999995424,"msg":"request completed"}
{"level":30,"time":1790408018407,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JF75GCM7BPRQ93RQXGY","req":{"method":"PUT","url":"/api/v1/staff/employees/01M3EA4JETWGVJMHFN7Q38N6ZH/pay-assignment","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018410,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JF75GCM7BPRQ93RQXGY","res":{"statusCode":200},"responseTime":3.6298900000001595,"msg":"request completed"}
{"level":30,"time":1790408018412,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JFB7RG1HJWMFPP628P1","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018413,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JFB7RG1HJWMFPP628P1","res":{"statusCode":201},"responseTime":1.662560000000667,"msg":"request completed"}
{"level":30,"time":1790408018414,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JFEEZ33FSBQR5V8S3XG","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018422,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JFEEZ33FSBQR5V8S3XG","res":{"statusCode":201},"responseTime":7.868167999999969,"msg":"request completed"}
{"level":30,"time":1790408018423,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JFQ185WPASH3T84B2KY","req":{"method":"POST","url":"/api/v1/staff/work-sessions/reconcile","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018427,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JFQ185WPASH3T84B2KY","res":{"statusCode":200},"responseTime":3.232307000000219,"msg":"request completed"}
{"level":30,"time":1790408018435,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG3C73K6MDYG5QKZBX4","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018435,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG3C73K6MDYG5QKZBX4","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018435,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG3C73K6MDYG5QKZBX4","res":{"statusCode":404},"responseTime":0.33230400000047666,"msg":"request completed"}
{"level":30,"time":1790408018437,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG57J9AN9YWDETCP3FJ","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018437,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG57J9AN9YWDETCP3FJ","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018437,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG57J9AN9YWDETCP3FJ","res":{"statusCode":404},"responseTime":0.2454699999998411,"msg":"request completed"}
{"level":30,"time":1790408018438,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG6X163QEGB6N85AM9P","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018439,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG6X163QEGB6N85AM9P","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018439,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG6X163QEGB6N85AM9P","res":{"statusCode":404},"responseTime":0.2565549999999348,"msg":"request completed"}
{"level":30,"time":1790408018440,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG8B5RZ5V4K0GB12G8X","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018441,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG8B5RZ5V4K0GB12G8X","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018441,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JG8B5RZ5V4K0GB12G8X","res":{"statusCode":404},"responseTime":0.28928499999983615,"msg":"request completed"}
{"level":30,"time":1790408018442,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGAE9ZP2T630SJGVMDD","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018442,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGAE9ZP2T630SJGVMDD","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018443,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGAE9ZP2T630SJGVMDD","res":{"statusCode":404},"responseTime":0.2572410000002492,"msg":"request completed"}
{"level":30,"time":1790408018444,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGCQ53FE88AQGRDBRZG","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018444,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGCQ53FE88AQGRDBRZG","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018444,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGCQ53FE88AQGRDBRZG","res":{"statusCode":404},"responseTime":0.2509200000004057,"msg":"request completed"}
{"level":30,"time":1790408018445,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGDK389KPYPC2PXWXYA","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018446,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGDK389KPYPC2PXWXYA","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018446,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGDK389KPYPC2PXWXYA","res":{"statusCode":404},"responseTime":0.2959399999999732,"msg":"request completed"}
{"level":30,"time":1790408018448,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGGYYTDWN5DQXM5JY5P","req":{"method":"POST","url":"/api/v1/staff/access-grants","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018448,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGGYYTDWN5DQXM5JY5P","msg":"Route POST:/api/v1/staff/access-grants not found"}
{"level":30,"time":1790408018448,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGGYYTDWN5DQXM5JY5P","res":{"statusCode":404},"responseTime":0.39974900000015623,"msg":"request completed"}
{"level":30,"time":1790408018450,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGJS6D7CH512HB9HZTM","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018455,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGJS6D7CH512HB9HZTM","res":{"statusCode":202},"responseTime":4.826310999999805,"msg":"request completed"}
{"level":30,"time":1790408018463,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGZ01CBTK1YMAHJRB18","req":{"method":"GET","url":"/api/v1/staff/terminal/employees/01M3EA4JGPPB7M0G78QQBQBJ1M/enrollment","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018463,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGZ01CBTK1YMAHJRB18","msg":"Route GET:/api/v1/staff/terminal/employees/01M3EA4JGPPB7M0G78QQBQBJ1M/enrollment not found"}
{"level":30,"time":1790408018463,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JGZ01CBTK1YMAHJRB18","res":{"statusCode":404},"responseTime":0.3378870000005918,"msg":"request completed"}
{"level":30,"time":1790408018465,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JH1A0MMMC9Y5FHG5JR3","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35782},"msg":"incoming request"}
{"level":30,"time":1790408018470,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JH1A0MMMC9Y5FHG5JR3","res":{"statusCode":202},"responseTime":5.273951000000125,"msg":"request completed"}
{"level":30,"time":1790408018478,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JHE1Z7JVRT7FTV70AXY","req":{"method":"PUT","url":"/api/v1/staff/employees/01M3EA4JH57XZ361XBC2Z7SA6J/biometric-consent","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35778},"msg":"incoming request"}
{"level":30,"time":1790408018478,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JHE1Z7JVRT7FTV70AXY","msg":"Route PUT:/api/v1/staff/employees/01M3EA4JH57XZ361XBC2Z7SA6J/biometric-consent not found"}
{"level":30,"time":1790408018478,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JHE1Z7JVRT7FTV70AXY","res":{"statusCode":404},"responseTime":0.304058000000623,"msg":"request completed"}
{"level":30,"time":1790408018606,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JNE3G43KVT3QY8K1AEW","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018612,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JNE3G43KVT3QY8K1AEW","res":{"statusCode":202},"responseTime":6.345726999999897,"msg":"request completed"}
{"level":30,"time":1790408018632,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JP8Q2M2Y2BDPFWA68K7","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018637,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JP8Q2M2Y2BDPFWA68K7","res":{"statusCode":202},"responseTime":4.942963999999847,"msg":"request completed"}
{"level":30,"time":1790408018647,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JPQHAWFX6VEZQRJADJ4","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018650,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JPQHAWFX6VEZQRJADJ4","res":{"statusCode":201},"responseTime":2.9649260000005597,"msg":"request completed"}
{"level":30,"time":1790408018654,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JPYKMHN8AV2XRK1ZT9C","req":{"method":"POST","url":"/api/v1/staff/sync/push","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018660,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JPYKMHN8AV2XRK1ZT9C","res":{"statusCode":200},"responseTime":5.449781000000257,"msg":"request completed"}
{"level":30,"time":1790408018675,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JQKCR13BT1AW47A8GYY","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018681,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JQKCR13BT1AW47A8GYY","res":{"statusCode":202},"responseTime":5.823410999999396,"msg":"request completed"}
{"level":30,"time":1790408018690,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JR2M60V60HT7JY4DVYZ","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018691,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JR2M60V60HT7JY4DVYZ","res":{"statusCode":201},"responseTime":1.3205479999996896,"msg":"request completed"}
{"level":30,"time":1790408018693,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JR5F9GRXENA9023DH3Q","req":{"method":"POST","url":"/api/v1/staff/sync/push","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018697,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JR5F9GRXENA9023DH3Q","res":{"statusCode":200},"responseTime":3.8750069999996413,"msg":"request completed"}
{"level":30,"time":1790408018707,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JRKGVB9KFM4GW8JCCRS","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018712,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JRKGVB9KFM4GW8JCCRS","res":{"statusCode":202},"responseTime":4.9716669999997976,"msg":"request completed"}
{"level":30,"time":1790408018722,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JS290GZAPS7A6Z5YFZZ","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018727,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JS290GZAPS7A6Z5YFZZ","res":{"statusCode":202},"responseTime":5.085656000000199,"msg":"request completed"}
{"level":30,"time":1790408018736,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JSG89R09EJQ2CDW87CW","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018738,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JSG89R09EJQ2CDW87CW","res":{"statusCode":201},"responseTime":1.3734510000003866,"msg":"request completed"}
{"level":30,"time":1790408018739,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JSKMK02GDMP23FZ2DZR","req":{"method":"POST","url":"/api/v1/staff/sync/pull","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":50,"time":1790408018743,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JSKMK02GDMP23FZ2DZR","req":{"method":"POST","url":"/api/v1/staff/sync/pull","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"column \"status\" does not exist","stack":"error: column \"status\" does not exist\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async <anonymous> (/workspace/krona-staff/src/domain/sync/service.ts:389:24)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/sync.ts:306:28)","length":106,"name":"error","severity":"ERROR","code":"42703","position":"24","file":"parse_relation.c","line":"3716","routine":"errorMissingColumn"},"msg":"column \"status\" does not exist"}
{"level":30,"time":1790408018744,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JSKMK02GDMP23FZ2DZR","res":{"statusCode":500},"responseTime":4.648181000000477,"msg":"request completed"}
{"level":30,"time":1790408018747,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JSVD8C9S834XPRJQTD2","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018785,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JSVD8C9S834XPRJQTD2","res":{"statusCode":202},"responseTime":37.420500999999604,"msg":"request completed"}
{"level":30,"time":1790408018793,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JV9WNV36C6MKDW979R6","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018796,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JV9WNV36C6MKDW979R6","res":{"statusCode":201},"responseTime":2.075665000000299,"msg":"request completed"}
{"level":30,"time":1790408018797,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JVDPWZPXAZ8HFFNX7AB","req":{"method":"POST","url":"/api/v1/staff/sync/pull","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":50,"time":1790408018799,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JVDPWZPXAZ8HFFNX7AB","req":{"method":"POST","url":"/api/v1/staff/sync/pull","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"column \"status\" does not exist","stack":"error: column \"status\" does not exist\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async <anonymous> (/workspace/krona-staff/src/domain/sync/service.ts:389:24)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/sync.ts:306:28)","length":106,"name":"error","severity":"ERROR","code":"42703","position":"24","file":"parse_relation.c","line":"3716","routine":"errorMissingColumn"},"msg":"column \"status\" does not exist"}
{"level":30,"time":1790408018799,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JVDPWZPXAZ8HFFNX7AB","res":{"statusCode":500},"responseTime":2.661884999999529,"msg":"request completed"}
{"level":30,"time":1790408018801,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JVHZF6TQCPQ6PWDKPCP","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018813,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JVHZF6TQCPQ6PWDKPCP","res":{"statusCode":201},"responseTime":12.522825000000012,"msg":"request completed"}
{"level":30,"time":1790408018814,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JVYMVC1M9CPBB2A3R39","req":{"method":"GET","url":"/api/v1/staff/sync/status","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018817,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JVYMVC1M9CPBB2A3R39","res":{"statusCode":200},"responseTime":2.794176000000334,"msg":"request completed"}
{"level":30,"time":1790408018818,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JW2EXB5S1H9YVT9GK45","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018823,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JW2EXB5S1H9YVT9GK45","res":{"statusCode":202},"responseTime":4.881444999999985,"msg":"request completed"}
{"level":30,"time":1790408018834,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JWJVPG8V84QAPCEE014","req":{"method":"PATCH","url":"/api/v1/staff/employees/01M3EA4JW60F9X6AEXP33M4MDQ","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018836,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JWJVPG8V84QAPCEE014","res":{"statusCode":200},"responseTime":2.368786999999429,"msg":"request completed"}
{"level":30,"time":1790408018837,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JWNGP1EJHDT3VJRAMN4","req":{"method":"POST","url":"/api/v1/staff/sync/pull","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018840,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JWNGP1EJHDT3VJRAMN4","res":{"statusCode":200},"responseTime":2.5322159999996074,"msg":"request completed"}
{"level":30,"time":1790408018842,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JWTMTYJ05Y0GV6PQS6B","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018846,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JWTMTYJ05Y0GV6PQS6B","res":{"statusCode":202},"responseTime":4.6687080000001515,"msg":"request completed"}
{"level":30,"time":1790408018853,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JX5JMS8NPRX3DHT88ZC","req":{"method":"PATCH","url":"/api/v1/staff/employees/01M3EA4JWYGKJW3S3SQW7QMCF1","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018857,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JX5JMS8NPRX3DHT88ZC","res":{"statusCode":200},"responseTime":3.251942999999301,"msg":"request completed"}
{"level":30,"time":1790408018857,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JX9M65W8D65RMHR6D9Y","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018859,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JX9M65W8D65RMHR6D9Y","res":{"statusCode":201},"responseTime":1.2874750000000859,"msg":"request completed"}
{"level":30,"time":1790408018860,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JXC3004KR4378VKCH5G","req":{"method":"POST","url":"/api/v1/staff/sync/push","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018863,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JXC3004KR4378VKCH5G","res":{"statusCode":200},"responseTime":3.7642430000005334,"msg":"request completed"}
{"level":30,"time":1790408018866,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JXJBJV3807BHBFN5S1J","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018871,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JXJBJV3807BHBFN5S1J","res":{"statusCode":202},"responseTime":5.396490000000085,"msg":"request completed"}
{"level":30,"time":1790408018879,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JXZX0ABKYVBY9ZTNTH9","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018885,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JXZX0ABKYVBY9ZTNTH9","res":{"statusCode":202},"responseTime":5.91953199999989,"msg":"request completed"}
{"level":30,"time":1790408018893,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JYDQA2MT149ZXET8XDC","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018895,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JYDQA2MT149ZXET8XDC","res":{"statusCode":201},"responseTime":1.6295439999994414,"msg":"request completed"}
{"level":30,"time":1790408018896,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JYGEHZECWTJNPV5CJVK","req":{"method":"POST","url":"/api/v1/staff/sync/push","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018899,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JYGEHZECWTJNPV5CJVK","res":{"statusCode":200},"responseTime":3.3800209999999424,"msg":"request completed"}
{"level":30,"time":1790408018908,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JYWF1Z6Y8YFD24BMCNK","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018913,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JYWF1Z6Y8YFD24BMCNK","res":{"statusCode":202},"responseTime":4.775786000000153,"msg":"request completed"}
{"level":30,"time":1790408018920,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZ8P6JQC0MCXERDQG8A","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018922,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZ8P6JQC0MCXERDQG8A","res":{"statusCode":201},"responseTime":1.5908949999993638,"msg":"request completed"}
{"level":30,"time":1790408018923,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZBFX4VJZTS4YKEPZRK","req":{"method":"POST","url":"/api/v1/staff/sync/push","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":50,"time":1790408018926,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZBFX4VJZTS4YKEPZRK","req":{"method":"POST","url":"/api/v1/staff/sync/push","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"res":{"statusCode":500},"err":{"type":"DatabaseError","message":"invalid input syntax for type timestamp with time zone: \"e2e-not-a-timestamp\"","stack":"error: invalid input syntax for type timestamp with time zone: \"e2e-not-a-timestamp\"\n at /workspace/krona-staff/node_modules/pg/lib/client.js:694:17\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async SyncService.executeCommand (/workspace/krona-staff/src/domain/sync/service.ts:755:9)\n at async <anonymous> (/workspace/krona-staff/src/domain/sync/service.ts:701:33)\n at async Database.tenantTransaction (/workspace/krona-staff/src/infrastructure/database.ts:30:22)\n at async Object.<anonymous> (/workspace/krona-staff/src/sync.ts:390:25)","length":180,"name":"error","severity":"ERROR","code":"22007","where":"unnamed portal parameter $6 = '...'","file":"datetime.c","line":"4140","routine":"DateTimeParseError"},"msg":"invalid input syntax for type timestamp with time zone: \"e2e-not-a-timestamp\""}
{"level":30,"time":1790408018927,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZBFX4VJZTS4YKEPZRK","res":{"statusCode":500},"responseTime":3.56025099999988,"msg":"request completed"}
{"level":30,"time":1790408018929,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZHQDMJQN1239C4STY6","req":{"method":"POST","url":"/api/v1/staff/session","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018929,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZHQDMJQN1239C4STY6","res":{"statusCode":200},"responseTime":0.275908999999956,"msg":"request completed"}
{"level":30,"time":1790408018931,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZKAZRYGPJS1C4JH86J","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018936,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4JZKAZRYGPJS1C4JH86J","res":{"statusCode":201},"responseTime":5.502994999999828,"msg":"request completed"}
{"level":30,"time":1790408018944,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K00QZ7RA4HCX365PH9C","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018952,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K00QZ7RA4HCX365PH9C","res":{"statusCode":202},"responseTime":7.422302000000855,"msg":"request completed"}
{"level":30,"time":1790408018960,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0GZZ935P4K7N775AKH","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018961,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0GZZ935P4K7N775AKH","res":{"statusCode":201},"responseTime":1.3733540000002904,"msg":"request completed"}
{"level":30,"time":1790408018962,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0J9ZACFMJQKXWB42BF","req":{"method":"POST","url":"/api/v1/staff/sync/push","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018966,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0J9ZACFMJQKXWB42BF","res":{"statusCode":200},"responseTime":4.033708999999362,"msg":"request completed"}
{"level":30,"time":1790408018968,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0R231R31H7Y82XKEFW","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018969,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0R231R31H7Y82XKEFW","res":{"statusCode":201},"responseTime":1.091668000000027,"msg":"request completed"}
{"level":30,"time":1790408018971,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0VXYZRT371QPNE7KZA","req":{"method":"POST","url":"/api/v1/staff/sync/ack","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018973,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0VXYZRT371QPNE7KZA","res":{"statusCode":200},"responseTime":2.2560160000002725,"msg":"request completed"}
{"level":30,"time":1790408018975,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0ZTN3QWGTMYH903DYA","req":{"method":"POST","url":"/api/v1/staff/sync/devices","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018976,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K0ZTN3QWGTMYH903DYA","res":{"statusCode":201},"responseTime":1.3257619999994859,"msg":"request completed"}
{"level":30,"time":1790408018977,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K111C5QFY8DC05HAMNK","req":{"method":"POST","url":"/api/v1/staff/sync/devices/01M3EA4K0ZYSXA5WW5PZG2TNS5/revoke","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35806},"msg":"incoming request"}
{"level":30,"time":1790408018980,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K111C5QFY8DC05HAMNK","res":{"statusCode":200},"responseTime":2.1610540000001492,"msg":"request completed"}
{"level":30,"time":1790408018981,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K15V20PHSJGB9EQP4WN","req":{"method":"GET","url":"/api/v1/staff/sync/status","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35792},"msg":"incoming request"}
{"level":30,"time":1790408018982,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K15V20PHSJGB9EQP4WN","res":{"statusCode":403},"err":{"type":"ForbiddenError","message":"Устройство отозвано","stack":"ForbiddenError: Устройство отозвано\n at Object.forbidden (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:33:12)\n at handleSyncError (/workspace/krona-staff/src/sync.ts:443:39)\n at Object.<anonymous> (/workspace/krona-staff/src/sync.ts:249:9)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)","status":403,"statusCode":403,"expose":true},"msg":"Устройство отозвано"}
{"level":30,"time":1790408018982,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K15V20PHSJGB9EQP4WN","res":{"statusCode":403},"responseTime":1.4805010000000038,"msg":"request completed"}
{"level":30,"time":1790408019100,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K4VD2Y9VX05D0YVHRPQ","req":{"method":"GET","url":"/api/v1/staff/live","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019100,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K4VD2Y9VX05D0YVHRPQ","res":{"statusCode":200},"responseTime":0.3551319999996849,"msg":"request completed"}
{"level":30,"time":1790408019106,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K52MQKWRNJHJ052QT1C","req":{"method":"GET","url":"/api/v1/staff/ready","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35824},"msg":"incoming request"}
{"level":30,"time":1790408019113,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K52MQKWRNJHJ052QT1C","res":{"statusCode":200},"responseTime":7.321270999999797,"msg":"request completed"}
{"level":30,"time":1790408019144,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K68VG1ZD7J17S2G4TZV","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019145,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K68VG1ZD7J17S2G4TZV","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:280:21)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408019145,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K68VG1ZD7J17S2G4TZV","res":{"statusCode":401},"responseTime":0.6766259999994872,"msg":"request completed"}
{"level":30,"time":1790408019147,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K6BA91KQ3B0K2DV1R8Z","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35824},"msg":"incoming request"}
{"level":30,"time":1790408019149,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K6BA91KQ3B0K2DV1R8Z","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:280:21)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408019149,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K6BA91KQ3B0K2DV1R8Z","res":{"statusCode":401},"responseTime":2.714422000000013,"msg":"request completed"}
{"level":30,"time":1790408019151,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K6FC17V38828NK5AWDH","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019156,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K6FC17V38828NK5AWDH","res":{"statusCode":200},"responseTime":5.406590999999935,"msg":"request completed"}
{"level":30,"time":1790408019161,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K6SBM3C4B20HGWAFBMZ","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35824},"msg":"incoming request"}
{"level":30,"time":1790408019168,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K6SBM3C4B20HGWAFBMZ","res":{"statusCode":202},"responseTime":7.204690999999912,"msg":"request completed"}
{"level":30,"time":1790408019178,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K7AC5R9N6168RDHC6ZK","req":{"method":"POST","url":"/api/v1/staff/attendance/events","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019181,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K7AC5R9N6168RDHC6ZK","res":{"statusCode":201},"responseTime":2.922958000000108,"msg":"request completed"}
{"level":30,"time":1790408019183,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K7FA1GFE2QZ11B20ZRS","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35824},"msg":"incoming request"}
{"level":30,"time":1790408019189,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K7FA1GFE2QZ11B20ZRS","res":{"statusCode":202},"responseTime":5.149693999999727,"msg":"request completed"}
{"level":30,"time":1790408019196,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K7WVTQDXRJXTNYDGR89","req":{"method":"POST","url":"/api/v1/staff/employees/01M3EA4K7MJGQJ2T2YKG46NF7B/access-token","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019199,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K7WVTQDXRJXTNYDGR89","res":{"statusCode":200},"responseTime":2.3117400000001,"msg":"request completed"}
{"level":30,"time":1790408019200,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K80FDTYG9ES87Q9ZQ7W","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35824},"msg":"incoming request"}
{"level":30,"time":1790408019200,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K80FDTYG9ES87Q9ZQ7W","res":{"statusCode":403},"err":{"type":"ForbiddenError","message":"Недостаточно прав для просмотра посещаемости.","stack":"ForbiddenError: Недостаточно прав для просмотра посещаемости.\n at Object.forbidden (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:33:12)\n at _Reply.sensibleForbidden [as forbidden] (/workspace/krona-staff/node_modules/@fastify/sensible/index.js:55:44)\n at Object.<anonymous> (/workspace/krona-staff/src/portal.ts:283:20)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)","status":403,"statusCode":403,"expose":true},"msg":"Недостаточно прав для просмотра посещаемости."}
{"level":30,"time":1790408019201,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K80FDTYG9ES87Q9ZQ7W","res":{"statusCode":403},"responseTime":0.48845000000073924,"msg":"request completed"}
{"level":30,"time":1790408019202,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K810TRXD0SQ27W7YDGR","req":{"method":"POST","url":"/api/v1/staff/employees","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019202,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K810TRXD0SQ27W7YDGR","res":{"statusCode":403},"err":{"type":"ForbiddenError","message":"Недостаточно прав для этой операции.","stack":"ForbiddenError: Недостаточно прав для этой операции.\n at Object.forbidden (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:33:12)\n at requirePermission (/workspace/krona-staff/src/portal.ts:1383:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:454:23)","status":403,"statusCode":403,"expose":true},"msg":"Недостаточно прав для этой операции."}
{"level":30,"time":1790408019202,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K810TRXD0SQ27W7YDGR","res":{"statusCode":403},"responseTime":0.5087550000007468,"msg":"request completed"}
{"level":30,"time":1790408019203,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8324R3A78MXKWG5GN2","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35824},"msg":"incoming request"}
{"level":30,"time":1790408019205,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8324R3A78MXKWG5GN2","res":{"statusCode":200},"responseTime":2.2520119999999224,"msg":"request completed"}
{"level":30,"time":1790408019207,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K87MB5BVVM753W72HHZ","req":{"method":"POST","url":"/api/v1/staff/imports/owner-workbook","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019212,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K87MB5BVVM753W72HHZ","res":{"statusCode":202},"responseTime":5.460973000000195,"msg":"request completed"}
{"level":30,"time":1790408019220,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8M7PQ0714YSD1M4CQP","req":{"method":"POST","url":"/api/v1/staff/employees/01M3EA4K8BXTNNKH3PQYXZJNBE/access-token","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019222,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8M7PQ0714YSD1M4CQP","res":{"statusCode":200},"responseTime":1.5780409999997573,"msg":"request completed"}
{"level":30,"time":1790408019222,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8P75YVNTFTC53C6RE4","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35824},"msg":"incoming request"}
{"level":30,"time":1790408019225,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8P75YVNTFTC53C6RE4","res":{"statusCode":200},"responseTime":2.076332000000548,"msg":"request completed"}
{"level":30,"time":1790408019225,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8S1H145G1H6N733Y63","req":{"method":"PATCH","url":"/api/v1/staff/employees/01M3EA4K8BXTNNKH3PQYXZJNBE","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35820},"msg":"incoming request"}
{"level":30,"time":1790408019227,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8S1H145G1H6N733Y63","res":{"statusCode":200},"responseTime":1.5953489999992598,"msg":"request completed"}
{"level":30,"time":1790408019228,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8WFVAZS9JJ3Y48JK1Z","req":{"method":"GET","url":"/api/v1/staff/portal","host":"127.0.0.1:35389","remoteAddress":"127.0.0.1","remotePort":35824},"msg":"incoming request"}
{"level":30,"time":1790408019228,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8WFVAZS9JJ3Y48JK1Z","res":{"statusCode":401},"err":{"type":"UnauthorizedError","message":"Требуется действующий ключ доступа.","stack":"UnauthorizedError: Требуется действующий ключ доступа.\n at Object.unauthorized (/workspace/krona-staff/node_modules/@fastify/sensible/lib/httpErrors.js:25:12)\n at resolveToken (/workspace/krona-staff/src/portal.ts:1337:37)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async Object.<anonymous> (/workspace/krona-staff/src/portal.ts:280:21)","status":401,"statusCode":401,"expose":true},"msg":"Требуется действующий ключ доступа."}
{"level":30,"time":1790408019229,"pid":1688811,"hostname":"grok-bot-vm-420973429","reqId":"01M3EA4K8WFVAZS9JJ3Y48JK1Z","res":{"statusCode":401},"responseTime":0.9479200000005221,"msg":"request completed"}

View file

@ -138,12 +138,8 @@ export async function hourlyRuleId(): Promise<string> {
return hourly!.id;
}
/**
* Синтетическая ставка 123,00 ₽/ч (заведомо не реальная сумма). Кратна рублю: расчёт
* округляет строку до rounding_unit_minor (по умолчанию 100 коп.), и 8 ч × ставка
* должны совпадать с начислением без учёта округления.
*/
export const SYNTHETIC_RATE_MINOR = 12_300;
/** Синтетическая ставка 123,45 ₽/ч (заведомо не реальная сумма). */
export const SYNTHETIC_RATE_MINOR = 12_345;
export async function assignHourly(employeeId: string, orgUnitId: string | null) {
const response = await api('PUT', `/employees/${employeeId}/pay-assignment`, {

View file

@ -7,7 +7,6 @@ import { createServer } from 'node:net';
import { tmpdir } from 'node:os';
import path from 'node:path';
import type { TestProject } from 'vitest/node';
import { baseEnv, nodeWithTsx } from '../../../scripts/test/node-commands.mjs';
import { randomUlid, type E2EContext } from './context.js';
const repoRoot = path.resolve(import.meta.dirname, '../../..');
@ -64,11 +63,11 @@ async function startServer(name: string, env: Record<string, string>): Promise<S
const port = await freePort();
const logPath = path.join(evidenceDir, `server-${name}.txt`);
const log = createWriteStream(logPath, { flags: 'w' });
const server = nodeWithTsx(['src/server.ts']);
const child = spawn(server.command, server.args, {
const tsx = path.join(repoRoot, 'node_modules/.bin/tsx');
const child = spawn(tsx, ['src/server.ts'], {
cwd: repoRoot,
env: {
...baseEnv(),
PATH: process.env.PATH ?? '',
NODE_ENV: 'test',
HOST: '127.0.0.1',
PORT: String(port),
@ -128,7 +127,7 @@ export default async function setup(project: TestProject) {
const migrationMode = process.env.E2E_MIGRATIONS ?? 'up';
runNode(
['scripts/test/migrate-roundtrip.mjs', migrationMode === 'roundtrip' ? 'roundtrip' : 'up'],
{ ...baseEnv(), DATABASE_MIGRATION_URL: migrationUrl },
{ PATH: process.env.PATH ?? '', DATABASE_MIGRATION_URL: migrationUrl },
`migrations (${migrationMode}) as krona_migrator`,
);

View file

@ -1,51 +0,0 @@
// Проверяемо на Linux: стенд запускает инструменты так, что под Windows не нужен
// .cmd-обёрточный файл (spawn без shell падает на них с ENOENT).
import { existsSync, readFileSync } from 'node:fs';
import path from 'node:path';
import { describe, expect, it } from 'vitest';
import { baseEnv, nodeTool, nodeWithTsx, repoRoot } from '../../../scripts/test/node-commands.mjs';
const forbidden = /\.cmd\b|[\\/]\.bin[\\/]|^npx$|^npm$/i;
describe('[HARNESS-WIN] запуск инструментов без .cmd-обёрток', () => {
it.each(['tsx', 'vitest', 'prettier'] as const)('%s: process.execPath + JS-файл', (tool) => {
const command = nodeTool(tool, ['--version']);
expect(command.command).toBe(process.execPath);
const entry = command.args[0]!;
expect(entry).not.toMatch(forbidden);
expect(entry).toMatch(/\.(mjs|cjs|js)$/);
expect(path.isAbsolute(entry)).toBe(true);
expect(existsSync(entry)).toBe(true);
});
it('сервер: один процесс node с загрузчиком tsx', () => {
const command = nodeWithTsx(['src/server.ts']);
expect(command.command).toBe(process.execPath);
expect(command.args[0]).toBe('--import');
expect(command.args[1]).toMatch(/^file:\/\/.*\.mjs$/);
expect(command.args.join(' ')).not.toMatch(forbidden);
expect(command.args.at(-1)).toBe('src/server.ts');
});
it('под win32 дочерний процесс получает SystemRoot/TEMP, а секреты не наследуются', () => {
const env = baseEnv('win32', {
PATH: 'C:\\Windows',
SystemRoot: 'C:\\Windows',
TEMP: 'C:\\Temp',
DATABASE_URL: 'secret-must-not-leak',
});
expect(env).toMatchObject({ PATH: 'C:\\Windows', SystemRoot: 'C:\\Windows', TEMP: 'C:\\Temp' });
expect(env).not.toHaveProperty('DATABASE_URL');
expect(baseEnv('linux', { PATH: '/bin', SystemRoot: 'x' })).toEqual({ PATH: '/bin' });
});
it.each([
'scripts/test/run-e2e.mjs',
'scripts/test/n13-race.mjs',
'tests/e2e/harness/global-setup.ts',
])('%s не вызывает npx и node_modules/.bin', (file) => {
const source = readFileSync(path.join(repoRoot, file), 'utf8');
expect(source).not.toMatch(/spawn(Sync)?\(\s*['"`]npx/);
expect(source).not.toMatch(/node_modules\/\.bin/);
});
});

View file

@ -1,50 +1,43 @@
{
"comment": "ID сценариев, красный цвет которых сейчас ожидаем (открытые дефекты или ещё не реализованные решения владельца). Когда дефект исправлен и все тесты ID зелёные, scripts/test/run-e2e.mjs падает, пока ID не убран отсюда. Добавлять ID сюда можно только вместе с записью в REPORT.md. Ключи — двойные ID «владелец/мой» (docs/audit/2026-09-26/AUDIT.md и TASK-GROK-2 §2), для сценариев без ID владельца — мой ID.",
"comment": "ID сценариев, красный цвет которых сейчас ожидаем (открытые дефекты или ещё не реализованные решения владельца). Когда дефект исправлен и все тесты ID зелёные, scripts/test/run-e2e.mjs падает, пока ID не убран отсюда. Добавлять ID сюда можно только вместе с записью в REPORT.md.",
"defects": {
"K4/N1": "POST /employees: 42P08 inconsistent types for $2 на реальной PostgreSQL",
"K3/N2": "подтверждение смены / расчёт / утверждение: staff_outbox.occurred_at NULL (23502)",
"K12/N3": "SSRF через push-endpoint на внутренние адреса",
"K5/N4": "двойное начисление при пересекающихся расчётах (сейчас блокирован N2)",
"N1": "POST /employees: 42P08 inconsistent types for $2 на реальной PostgreSQL",
"N2": "подтверждение смены / расчёт / утверждение: staff_outbox.occurred_at NULL (23502)",
"N3": "SSRF через push-endpoint на внутренние адреса",
"N4": "двойное начисление при пересекающихся расчётах (сейчас блокирован N2)",
"N9": "перепривязка чужого push-endpoint",
"N10": "справочники доступны терминалу",
"N11": "импорт с неверным kind → 500",
"N12": "pay-assignment без additionalProperties:false и верхних границ",
"K1/F2": "standalone без токенов даёт права STANDALONE_ACCESS анониму",
"K10/F3": "cookie = сырой токен, logout не отзывает",
"K11/F4": "нет rate limit на вход",
"F2": "standalone без токенов даёт права STANDALONE_ACCESS анониму",
"F3": "cookie = сырой токен, logout не отзывает",
"F4": "нет rate limit на вход",
"F7": "Idempotency-Key не используется",
"F10": "CSRF: мутации по cookie без Origin разрешены",
"K13/SYNC-A": "устройство само подтверждает смену через upsert_work_session",
"K13/SYNC-B": "устройство само утверждает табель через upsert_timesheet_entry",
"SYNC-A": "устройство само подтверждает смену через upsert_work_session",
"SYNC-B": "устройство само утверждает табель через upsert_timesheet_entry",
"SYNC-C0": "начальная загрузка /sync/pull падает 500: column status does not exist (staff_org_units)",
"S5/SYNC-C": "начальная загрузка обрезается на 100 сущностях (сейчас также блокирована SYNC-C0)",
"S5/SYNC-D": "изменения из портала не пишутся в staff_sync_change_log",
"S4/SYNC-E": "отметки уволенных сотрудников принимаются через sync",
"S4/SYNC-F": "sync не сохраняет org_unit_id отметки и принимает чужую точку",
"S3/SYNC-G": "одна битая команда роняет весь пакет (500)",
"S8/SYNC-H": "регистрация устройства по cookie без проверки Origin",
"K1/SYNC-I": "без токенов анонимно регистрируется устройство",
"S2/SYNC-J": "sync принимает отметки вне окна времени",
"SYNC-C": "начальная загрузка обрезается на 100 сущностях (сейчас также блокирована SYNC-C0)",
"SYNC-D": "изменения из портала не пишутся в staff_sync_change_log",
"SYNC-E": "отметки уволенных сотрудников принимаются через sync",
"SYNC-F": "sync не сохраняет org_unit_id отметки и принимает чужую точку",
"SYNC-G": "одна битая команда роняет весь пакет (500)",
"SYNC-H": "регистрация устройства по cookie без проверки Origin",
"SYNC-I": "без токенов анонимно регистрируется устройство",
"SYNC-J": "sync принимает отметки вне окна времени",
"SYNC-K": "ack принимает курсор больше выданного сервером",
"K1/PILOT-1": "deploy/pilot/compose.yaml: 14 подстановок без :? (пустые токены/пароли молча проходят)",
"K2/PILOT-2": "deploy/pilot/compose.yaml: app с NODE_ENV=development",
"D6/OWN-01": "решение владельца: роли точки (этап 4 Codex)",
"D6/OWN-02": "решение владельца: пакет отправляет только бухгалтер",
"PILOT-1": "deploy/pilot/compose.yaml: 14 подстановок без :? (пустые токены/пароли молча проходят)",
"PILOT-2": "deploy/pilot/compose.yaml: app с NODE_ENV=development",
"OWN-01": "решение владельца: роли точки (этап 4 Codex)",
"OWN-02": "решение владельца: пакет отправляет только бухгалтер",
"OWN-03": "решение владельца: уведомления директорам",
"OWN-04": "решение владельца: подписывает только директор",
"OWN-05": "решение владельца: ledger пуст до подписи",
"OWN-06": "решение владельца: подпись → ledger, неизменяемость",
"K19/OWN-07": "решение владельца: изменение смены после отправки возвращает пакет",
"OWN-07": "решение владельца: изменение смены после отправки возвращает пакет",
"OWN-08": "решение владельца: возврат с комментарием",
"OWN-09": "решение владельца: смена в чужой точке идёт в зарплату той точки",
"K17/OWN-10": "решение владельца: нет согласия на биометрию → регистрация запрещена",
"K17/OWN-11": "решение владельца: отзыв согласия меняет статус для терминала",
"K6/D5": "отклонение смены из подписанной ведомости: 200 без сторно (сейчас блокирован K3 на подтверждении)",
"K7/D2": "повторный импорт книги теряет суммы: две точки в один день → 222,00 вместо 333,00 ₽",
"K8/D1": "подписанная ведомость не воспроизводится после смены ставки; контракта verify нет (C4), сейчас блокирован K3",
"K9/D3": "параметры пресета официанта (shift_rate_minor и др.) не сохраняются",
"S9": "удаление точки с устройством: 23502 null value in column tenant_id (ON DELETE SET NULL на составном FK)",
"A4": "ответы 500 содержат SQLSTATE и текст PostgreSQL",
"N12-DATE": "month=2026-13 → 500 (22008) вместо 400"
"OWN-10": "решение владельца: нет согласия на биометрию → регистрация запрещена",
"OWN-11": "решение владельца: отзыв согласия меняет статус для терминала"
}
}

View file

@ -1,27 +0,0 @@
# Приёмка ветки antigravity/fix-reject-device-shifts @ 795bba0ce8eb2621a395c6bd794d075609c1a3eb (2026-09-26, UTC+7)
# Код продукта — ветка исполнителя (git worktree --detach origin/antigravity/fix-reject-device-shifts), поверх — tests/e2e и scripts/test из grok/e2e-harness @ 3475133 (без коммитов в ветку исполнителя).
# PostgreSQL 17.11, мигратор NOSUPERUSER, сервер под krona_staff_app.
$ cd <worktree> && E2E_MIGRATIONS=roundtrip E2E_DATABASE_NAME=krona_staff_acc node scripts/test/run-e2e.mjs
== roundtrip OK: rolledBack=11 reapplied=11
Tests 43 failed | 11 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
exit=1
# Было (основная ветка f5ac179 + тот же стенд): Tests 45 failed | 9 passed (54) ; run-e2e OK
# Отличия по ID (compare по e2e-results.json, ULID/порты замаскированы):
| ID | было | стало | фактический вывод |
| K13/SYNC-A | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_work_session","status":"applied","result":{"id":"<ulid>","revision":1,"status" / стало: passed |
| K13/SYNC-B | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_timesheet_entry","status":"applied","result":{"id":"<ulid>","revision":1,"stat / стало: passed |
# Перепроверка: ветку обновили force-push во время приёмки; новый HEAD 1df2019cb89cad69e2c86608dd3b43e18275e97c (2026-09-26 ~15:40 UTC+7)
$ cd <worktree @ 1df2019> && E2E_MIGRATIONS=roundtrip E2E_DATABASE_NAME=krona_staff_acc node scripts/test/run-e2e.mjs
== roundtrip OK: rolledBack=11 reapplied=11
Tests 43 failed | 11 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
exit=1
| ID | было | стало | фактический вывод |
| K13/SYNC-A | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_work_session","status":"applied","result":{"id":"<ulid>","revision":1,"status" / стало: passed |
| K13/SYNC-B | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_timesheet_entry","status":"applied","result":{"id":"<ulid>","revision":1,"stat / стало: passed |

View file

@ -1,31 +0,0 @@
# Приёмка ветки codex/fix-format-baseline @ fd1ec3d8197c21afe15a8dc8101816c52226ebef (2026-09-26, UTC+7)
# Код продукта — ветка исполнителя (git worktree --detach origin/codex/fix-format-baseline), поверх — tests/e2e и scripts/test из grok/e2e-harness @ 3475133 (без коммитов в ветку исполнителя).
# PostgreSQL 17.11, мигратор NOSUPERUSER, сервер под krona_staff_app.
$ cd <worktree> && E2E_MIGRATIONS=roundtrip E2E_DATABASE_NAME=krona_staff_acc node scripts/test/run-e2e.mjs
== roundtrip OK: rolledBack=11 reapplied=11
Tests 43 failed | 11 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
exit=1
# Было (основная ветка f5ac179 + тот же стенд): Tests 45 failed | 9 passed (54) ; run-e2e OK
# Отличия по ID (compare по e2e-results.json, ULID/порты замаскированы):
| ID | было | стало | фактический вывод |
| K13/SYNC-A | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_work_session","status":"applied","result":{"id":"<ulid>","revision":1,"status" / стало: passed |
| K13/SYNC-B | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_timesheet_entry","status":"applied","result":{"id":"<ulid>","revision":1,"stat / стало: passed |
# F14: форматирование ветки (оверлей tests/e2e/evidence удалён перед проверкой — в ветке исполнителя нет записи .gitignore для него)
$ node node_modules/prettier/bin/prettier.cjs --check .
Checking formatting...
All matched files use Prettier code style!
# Было (основная ветка f5ac179): [warn] Code style issues found in 23 files.
# Находка: коммит fd1ec3d «style: establish repository formatting baseline» содержит не только форматирование.
# Сравнение после нормализации prettier (--config .prettierrc.json), число строк diff:
# src/domain/sync/service.ts 331e490 → fd1ec3d: 255; antigravity/fix-reject-device-shifts → fd1ec3d: 0
# tests/unit/sync.test.ts 331e490 → fd1ec3d: 139; antigravity/fix-reject-device-shifts → fd1ec3d: 0
# src/sync.ts, src/domain/sync/cursor.ts: antigravity → fd1ec3d: 0
# То есть в «style»-коммит вошло функциональное исправление Antigravity (отклонение
# upsert_work_session/upsert_timesheet_entry, COMMAND_NOT_SUPPORTED) — поэтому K13/SYNC-A/B
# зелёные и на этой ветке. Для ревью это смешение тем: изменение поведения скрыто в форматировании.

View file

@ -1,49 +0,0 @@
# Приёмка ветки codex/fix-live-database @ ea68e123506cc29276514f67b1dda7cef77057df (2026-09-26, UTC+7)
# Код продукта — ветка исполнителя (git worktree --detach origin/codex/fix-live-database), поверх — tests/e2e и scripts/test из grok/e2e-harness @ 3475133 (без коммитов в ветку исполнителя).
# PostgreSQL 17.11, мигратор NOSUPERUSER, сервер под krona_staff_app.
$ cd <worktree> && E2E_MIGRATIONS=roundtrip E2E_DATABASE_NAME=krona_staff_acc node scripts/test/run-e2e.mjs
== roundtrip OK: rolledBack=11 reapplied=11
Tests 41 failed | 13 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K3/N2 | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K4/N1 | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
exit=1
# Было (основная ветка f5ac179 + тот же стенд): Tests 45 failed | 9 passed (54) ; run-e2e OK
# Отличия по ID (compare по e2e-results.json, ULID/порты замаскированы):
| ID | было | стало | фактический вывод |
| A4 | RED | RED | было: AssertionError: тела 500 с деталями PostgreSQL: expected [ …(2) ] to deeply equal [] / стало: AssertionError: тела 500 с деталями PostgreSQL: expected [ { …(2) } ] to deeply equal [] |
| K13/SYNC-A | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_work_session","status":"applied","result":{"id":"<ulid>","revision":1,"status" / стало: passed |
| K13/SYNC-B | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_timesheet_entry","status":"applied","result":{"id":"<ulid>","revision":1,"stat / стало: passed |
| K3/N2 | RED | GREEN | было: AssertionError: подтверждение смены: HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occurred_at\" of relation / стало: passed |
| K4/N1 | RED | GREEN | было: AssertionError: HTTP 500 {"statusCode":500,"code":"42P08","error":"Internal Server Error","message":"inconsistent types deduced for parameter $2"}: expected 500 to be 201 / стало: passed |
| K5/N4 | RED | RED | было: AssertionError: подтверждение смены (предусловие, см. N2): HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occ / стало: AssertionError: смена должна быть начислена ровно один раз: expected 196800n to be 98400n // Object.is equality |
| K6/D5 | RED | RED | было: AssertionError: подтверждение смены (предусловие; падает, пока открыт K3): HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value / стало: AssertionError: после отклонения оплаченной смены должно быть сторно: итог начислений 0: expected 98400n to be 0n // Object.is equality |
| K8/D1 | RED | RED | было: AssertionError: подтверждение смены (предусловие; падает, пока открыт K3): HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value / стало: AssertionError: C4 verify: HTTP 404 {"message":"Route GET:/api/v1/staff/payroll/runs/<ulid>/verify not found","error":"Not Found","statusCode":404}: expected 404 to be 20 |
# F14: форматирование ветки (оверлей tests/e2e/evidence удалён перед проверкой — в ветке исполнителя нет записи .gitignore для него)
$ node node_modules/prettier/bin/prettier.cjs --check .
Checking formatting...
All matched files use Prettier code style!
# Было (основная ветка f5ac179): [warn] Code style issues found in 23 files.
# Перепроверка: ветку обновили force-push во время приёмки; новый HEAD b289dd6d63b8f5bcd7c03a88c07200e2e4a704bc (2026-09-26 ~15:40 UTC+7)
$ cd <worktree @ b289dd6> && E2E_MIGRATIONS=roundtrip E2E_DATABASE_NAME=krona_staff_acc node scripts/test/run-e2e.mjs
== roundtrip OK: rolledBack=11 reapplied=11
Tests 41 failed | 13 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K3/N2 | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K4/N1 | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
exit=1
| ID | было | стало | фактический вывод |
| A4 | RED | RED | было: AssertionError: тела 500 с деталями PostgreSQL: expected [ …(2) ] to deeply equal [] / стало: AssertionError: тела 500 с деталями PostgreSQL: expected [ { …(2) } ] to deeply equal [] |
| K13/SYNC-A | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_work_session","status":"applied","result":{"id":"<ulid>","revision":1,"status" / стало: passed |
| K13/SYNC-B | RED | GREEN | было: AssertionError: HTTP 200 {"results":[{"idempotency_key":"e2e-<ulid>","command_type":"upsert_timesheet_entry","status":"applied","result":{"id":"<ulid>","revision":1,"stat / стало: passed |
| K3/N2 | RED | GREEN | было: AssertionError: подтверждение смены: HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occurred_at\" of relation / стало: passed |
| K4/N1 | RED | GREEN | было: AssertionError: HTTP 500 {"statusCode":500,"code":"42P08","error":"Internal Server Error","message":"inconsistent types deduced for parameter $2"}: expected 500 to be 201 / стало: passed |
| K5/N4 | RED | RED | было: AssertionError: подтверждение смены (предусловие, см. N2): HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value in column \"occ / стало: AssertionError: смена должна быть начислена ровно один раз: expected 196800n to be 98400n // Object.is equality |
| K6/D5 | RED | RED | было: AssertionError: подтверждение смены (предусловие; падает, пока открыт K3): HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value / стало: AssertionError: после отклонения оплаченной смены должно быть сторно: итог начислений 0: expected 98400n to be 0n // Object.is equality |
| K8/D1 | RED | RED | было: AssertionError: подтверждение смены (предусловие; падает, пока открыт K3): HTTP 500 {"statusCode":500,"code":"23502","error":"Internal Server Error","message":"null value / стало: AssertionError: C4 verify: HTTP 404 {"message":"Route GET:/api/v1/staff/payroll/runs/<ulid>/verify not found","error":"Not Found","statusCode":404}: expected 404 to be 20 |

View file

@ -3,19 +3,12 @@ import { describe, expect, it } from 'vitest';
import { portalCssEnhanced, portalHtml, portalJsEnhanced, portalManifest } from '../../src/portal-ui.js';
describe('Krona Staff workspace shell', () => {
it('exposes the operational workspace sections with deep routes', () => {
expect(portalHtml).toContain('data-route="/staff/dashboard"');
expect(portalHtml).toContain('data-route="/staff/employees"');
expect(portalHtml).toContain('data-route="/staff/finance"');
expect(portalHtml).toContain('data-route="/staff/schedules"');
expect(portalHtml).toContain('data-route="/staff/payroll"');
expect(portalHtml).toContain('data-route="/staff/attendance">');
expect(portalHtml).toContain('data-route="/staff/shifts">');
expect(portalHtml).toContain('data-route="/staff/rules">');
expect(portalHtml).toContain('data-route="/staff/terminal">');
expect(portalHtml).toContain('id="employee-inspector"');
expect(portalHtml).toContain('id="finance-entries"');
expect(portalHtml).toContain('id="calendar-grid"');
it('exposes the five approved top-level sections with deep routes', () => {
expect(portalHtml).toContain('data-route="/staff/dashboard">Дашборд');
expect(portalHtml).toContain('data-route="/staff/employees">Сотрудники');
expect(portalHtml).toContain('data-route="/staff/finance">Финансы');
expect(portalHtml).toContain('data-route="/staff/schedules">Графики');
expect(portalHtml).toContain('data-route="/staff/payroll">Зарплата');
expect(portalHtml).not.toContain('<aside class="sidebar"');
});
@ -30,8 +23,6 @@ describe('Krona Staff workspace shell', () => {
it('keeps navigation addressable and starts the PWA on the dashboard', () => {
expect(portalJsEnhanced).toContain("'/staff/employees':'employees-view'");
expect(portalJsEnhanced).toContain("'/staff/attendance':'attendance-view'");
expect(portalJsEnhanced).toContain("'/staff/reports':'reports-view'");
expect(portalJsEnhanced).toContain("window.addEventListener('popstate'");
expect(JSON.parse(portalManifest)).toMatchObject({ start_url: '/staff/dashboard', scope: '/staff' });
});