40a859f5e114a9971a95fd179f4f4c8d81528e3d
Invoices now mirror the issued-orders document model: - New invoice_sections table (CZ/EN rich-text "Obsah") edited via the shared SectionsEditor, printed inline right after the items on the PDF. Full-replace on update, same transaction as items. - Printed notes dropped: the notes column is removed (migration merges existing content into internal_notes first); the form field is now "Interni poznamky", never printed. Legacy payloads sending notes are silently stripped. - Form cleanup: Cislo faktury and Vystavil fields removed (number lives in the header, issued_by auto-fills); page header title restyled to the orders/offers pattern (number span + status chip). - Unified per-page PDF header for the red-accent family: shared buildPdfHeaderTemplate in pdf-shared (22mm logo, red heading, red rule) rendered by a Puppeteer headerTemplate on EVERY page of both invoices and issued orders (incl. the /file fallback render); body headers are print-hidden. htmlToPdf gained the headerTemplate option. - Footer parity: invoices get the per-page "Vystavil + Strana X z Y" footer; the invoice bottom block (notice + QR/VAT recap + Prevzal) is break-inside: avoid so a page break can never split it. - @page margins now match the template space (32mm top, 18mm bottom) - Chromium lays out by CSS @page margins, which also fixes issued orders' content running into the 18mm footer zone on full pages. BREAKING CHANGE: invoices.notes column dropped (data merged into internal_notes); deploy must run prisma migrate deploy + generate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(nas): order PDF archive uses orders.view (parity w/ invoices) + document NAS_INVOICES/NAS_ORDERS
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→.envand fill in the required vars (DATABASE_URL,JWT_SECRET,TOTP_ENCRYPTION_KEY— generate the keys withopenssl 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