chore(release): v2.4.35 — lint cleanup (68→0) + duplicate-Zavřít modal fix

UI fix:
- Close-only modals showing a redundant second close button now use
  hideCancel: ReceivedInvoices paid-detail modal (was two identical "Zavřít"
  buttons) and PlanCellModal "Den je součástí rozsahu".
- Add modal-duplicate-close test enforcing close-only modals set hideCancel.

Lint: cleared all 68 warnings → 0.
- preserve-caught-error: attach { cause } in ai.service / exchange-rates.
- no-require-imports: package.json version read via fs (APP_VERSION) instead
  of require(), avoiding a rootDir-expanding static JSON import.
- react-hooks/exhaustive-deps (11): ref-in-cleanup copies, derived-value
  useMemo wrapping, PlanGrid field extraction, stable nextKey useCallback,
  AuthContext documented cycle-break.
- no-explicit-any (53): precise route param/Prisma types, generic enrich*()
  preserving payload shape, minimal vite module type, frontend body/query-key
  types, SystemInfo for Settings.

Refactor (test enablement): shift-form types moved to dependency-free
shiftFormTypes.ts so the print-HTML builders are unit-testable without the
component graph; characterization test pins their output.

Gates: 649 tests pass, tsc -b clean, lint 0. Verified touched flows live
via Playwright (PlanWork CRUD + optimistic cache, warehouse form keys,
Settings system info, invoice detail).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-13 18:35:31 +02:00
parent 907ee574e6
commit 1ee59b54bc
36 changed files with 954 additions and 140 deletions

View File

@@ -1,4 +1,5 @@
import Fastify from "fastify";
import type { IncomingMessage, ServerResponse } from "http";
import type { ScheduledTask } from "node-cron";
import cors from "@fastify/cors";
import cookie from "@fastify/cookie";
@@ -167,13 +168,26 @@ async function start() {
// --- Frontend: Vite dev middleware (dev only) ---
if (!config.isProduction) {
// `vite` is a dev-only dependency loaded via a runtime import the bundler
// can't see (the Function() trick), so its types aren't resolvable under the
// server's moduleResolution — describe just the slice we use.
type ViteDevServerLike = {
middlewares: (
req: IncomingMessage,
res: ServerResponse,
next: (err?: Error) => void,
) => void;
};
type ViteModuleLike = {
createServer: (opts: {
server: { middlewareMode: boolean };
appType: string;
}) => Promise<ViteDevServerLike>;
};
const viteModule = await (Function(
'return import("vite")',
)() as Promise<any>);
const createViteServer = viteModule.createServer as (
opts: any,
) => Promise<any>;
const vite = await createViteServer({
)() as Promise<ViteModuleLike>);
const vite = await viteModule.createServer({
server: { middlewareMode: true },
appType: "spa",
});