BOHA 3ec512faf1 feat(projects/orders): project status machine + bidirectional project-order sync; order reopen
- projects.service: VALID_TRANSITIONS (aktivni->dokonceny/zruseny,
  terminal->aktivni reopen), tolerant of legacy statuses; getProject returns
  valid_transitions; updateProject validates transitions (invalid_transition
  token -> Czech 400 in the route).
- NEW project->order cascade, transactional with the project update: finishing/
  cancelling a project completes/cancels its linked received order — only while
  the order is still open (never resurrects storno, never cancels completed);
  reopen never cascades. Direct tx write, no service recursion; cascaded order
  change gets its own audit row.
- orders.service: reopen edges (dokoncena/stornovana -> v_realizaci);
  syncProjectStatus is reopen-aware (reopen skips project sync) and returns
  the cascaded projects for per-project audit rows in the route.
- orders.schema: fix phantom 'zrusena' enum token -> canonical 'stornovana'
  (every storno PUT through the route 400ed with a raw English Zod message;
  latent until now because no UI sent it) + route-level regression test.
- NEW project-order-status-sync.test.ts: 15 tests — both cascade directions,
  guards, reopen-no-cascade, legacy tolerance, forward-sync regression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 04:33:58 +02:00
2026-03-23 08:46:51 +01:00

boha-app-ts

Internal business-management system for a Czech company (attendance, invoicing, leave/trips, projects, vehicles, warehouse, HR) — a TypeScript/Node.js rewrite of the legacy PHP app. User-facing text is Czech by design.

For full architecture, conventions, and gotchas, see CLAUDE.md.

Stack

  • Backend: Fastify 5 · Prisma 6 → MySQL · Zod 4 · JWT (HS256) + TOTP 2FA
  • Frontend: React 18 · Vite · Material UI v7 (Emotion) · TanStack Query — an SPA in src/admin/, served by the same Fastify process (Vite middleware in dev, static files in prod)
  • Other: Puppeteer (PDF) · nodemailer · node-cron · @anthropic-ai/sdk (the admins-only "Odin" assistant)

Prerequisites

  • Node.js (LTS) and a MySQL database
  • Copy .env.example.env and fill in the required vars (DATABASE_URL, JWT_SECRET, TOTP_ENCRYPTION_KEY — generate the keys with openssl rand -hex 32)

Setup

npm install
npx prisma generate
npx prisma migrate dev      # apply migrations to your dev DB
npx prisma db seed          # optional: dev-only sample data (NEVER on prod)

Develop

npm run dev:server   # API (tsx watch) on http://127.0.0.1:3050
npm run dev:client   # Vite dev server (manage separately)

Build & run

npm run build        # tsc server → dist/  +  vite client → dist-client/
npm start            # node dist/server.js

Test

npm test             # vitest run — hits a real test DB (.env.test); no Prisma mocks

Quality gates

Before committing, all of these must pass:

npx tsc -b --noEmit  # typecheck (NOT `tsc -p tsconfig.json`)
npm run build
npx vitest run
npm run lint         # ESLint (incl. react-hooks) — see eslint.config.js

Database migrations

Every schema/data change is a tracked Prisma migration — never prisma db push or raw SQL on production. Stop the dev server before running prisma migrate dev. See CLAUDE.md → Database Migrations for the full workflow and the production deploy/hotfix process.

License

ISC

Description
No description provided
Readme 30 MiB
v1.5.1 Latest
2026-04-02 20:01:44 +02:00
Languages
TypeScript 99.9%
JavaScript 0.1%