v1.8.0: warehouse module (16 commits), docházka mzda model, leave_type=holiday removal, api.ts race fix

Highlights:
- Warehouse module: receipts, issues, reservations, inventory, reports, dashboard,
  master data (categories, suppliers, locations), FIFO service, integration tests
- Docházka: mzda PDF counting model (Odpracováno / Vč. svátků / Přesčas / Svátek /
  So/Ne / Noc) with Czech weekday names and decimal hours
- AttendanceAdmin/AttendanceHistory KPI cards unified to mzda formula with
  fund bar colored by delta, badges for Práce/Dov/Nem/Sv/Nep
- Remove leave_type=holiday entirely (auto-computed from Czech public holidays)
- Allow multiple work shifts per day (overlap detection only)
- Pre-flight refresh in api.ts eliminates spurious 401s on fresh page loads
- Prisma: company_settings gets 6 nullable columns for warehouse numbering
  (PRI/VYD/INV prefixes, default patterns); migration seeds defaults
This commit is contained in:
BOHA
2026-06-03 23:13:10 +02:00
parent dac45baaa8
commit 5233db2002
149 changed files with 11132 additions and 26950 deletions

View File

@@ -1,9 +1,23 @@
import { FastifyInstance } from "fastify";
import { z } from "zod";
import prisma from "../../config/database";
import { requirePermission } from "../../middleware/auth";
import { logAudit } from "../../services/audit";
import { success, paginated, error } from "../../utils/response";
import { parsePagination, buildPaginationMeta } from "../../utils/pagination";
import { parseBody } from "../../schemas/common";
// DELETE_ALL_CONFIRM must be sent literally in the body to authorize a
// full audit-log wipe. Protects against accidental / automated wipes of
// forensic history.
const DELETE_ALL_CONFIRM = "DELETE_ALL_AUDIT" as const;
const AuditCleanupSchema = z
.object({
days: z.number().int().nonnegative().optional(),
confirm: z.string().optional(),
})
.strict();
export default async function auditLogRoutes(
fastify: FastifyInstance,
@@ -44,15 +58,27 @@ export default async function auditLogRoutes(
);
// POST /api/admin/audit-log/cleanup — delete old audit logs
// days=0 with confirm="DELETE_ALL_AUDIT" wipes everything (intentionally
// a two-step path so a stray API call cannot destroy forensic history).
fastify.post(
"/cleanup",
{ preHandler: requirePermission("settings.audit") },
async (request, reply) => {
const body = request.body as Record<string, unknown>;
const days = body.days !== undefined ? Number(body.days) : null;
const parsed = parseBody(AuditCleanupSchema, request.body);
if ("error" in parsed) {
return error(reply, parsed.error, 400);
}
const { days, confirm } = parsed.data;
// days === 0 means "delete all" (from frontend "Vše" option)
if (days === 0 || body.action === "all") {
// Wipe-all path: requires explicit confirmation literal.
if (days === 0) {
if (confirm !== DELETE_ALL_CONFIRM) {
return error(
reply,
`Pro smazání všech audit logů je nutné odeslat confirm: "${DELETE_ALL_CONFIRM}"`,
400,
);
}
const result = await prisma.audit_logs.deleteMany({});
await logAudit({
request,
@@ -64,7 +90,7 @@ export default async function auditLogRoutes(
return success(reply, null, 200, `Smazáno ${result.count} záznamů`);
}
if (days && days > 0) {
if (days !== undefined && days > 0) {
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - days);
const result = await prisma.audit_logs.deleteMany({