diff --git a/package-lock.json b/package-lock.json
index dfe6c74..02c5649 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "app-ts",
- "version": "2.4.33",
+ "version": "2.4.34",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "app-ts",
- "version": "2.4.33",
+ "version": "2.4.34",
"license": "ISC",
"dependencies": {
"@anthropic-ai/sdk": "^0.102.0",
diff --git a/package.json b/package.json
index 226e881..e8d9798 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "app-ts",
- "version": "2.4.33",
+ "version": "2.4.34",
"description": "",
"main": "dist/server.js",
"scripts": {
diff --git a/prisma/seed.ts b/prisma/seed.ts
index 4f38ba3..2ec5d54 100644
--- a/prisma/seed.ts
+++ b/prisma/seed.ts
@@ -391,12 +391,12 @@ async function main() {
console.log(` Admin role now has all ${allPerms.length} permissions`);
// 4. Ensure admin user exists
- let adminUser = await prisma.users.findFirst({
+ const adminUser = await prisma.users.findFirst({
where: { username: "admin" },
});
if (!adminUser) {
const hash = bcrypt.hashSync("admin", 10);
- adminUser = await prisma.users.create({
+ await prisma.users.create({
data: {
username: "admin",
email: "admin@boha.local",
diff --git a/scripts/migrate-received-invoices-to-nas.ts b/scripts/migrate-received-invoices-to-nas.ts
index 38081b7..fc4eaf9 100644
--- a/scripts/migrate-received-invoices-to-nas.ts
+++ b/scripts/migrate-received-invoices-to-nas.ts
@@ -59,7 +59,7 @@ async function main() {
// fails we KEEP file_data and report the row as failed.
const expectedSize = rec.file_data.length;
const readBack = nasFinancialsManager.readReceivedInvoice(result.filePath);
- let writtenSize = -1;
+ let writtenSize: number;
if (readBack) {
writtenSize = readBack.data.length;
} else {
diff --git a/src/__tests__/plan.test.ts b/src/__tests__/plan.test.ts
index e5b841b..d877e48 100644
--- a/src/__tests__/plan.test.ts
+++ b/src/__tests__/plan.test.ts
@@ -1090,26 +1090,6 @@ async function authPost(path: string, token: string, body: unknown) {
});
}
-async function authPatch(path: string, token: string, body: unknown) {
- return app.inject({
- method: "PATCH",
- url: path,
- headers: {
- Authorization: `Bearer ${token}`,
- "Content-Type": "application/json",
- },
- payload: body as object,
- });
-}
-
-async function authDelete(path: string, token: string) {
- return app.inject({
- method: "DELETE",
- url: path,
- headers: { Authorization: `Bearer ${token}` },
- });
-}
-
beforeAll(async () => {
app = await buildApp();
diff --git a/src/admin/components/PlanCellModal.tsx b/src/admin/components/PlanCellModal.tsx
index 9c25d38..75d73d0 100644
--- a/src/admin/components/PlanCellModal.tsx
+++ b/src/admin/components/PlanCellModal.tsx
@@ -148,7 +148,7 @@ const TrashIcon = (
);
export default function PlanCellModal(props: Props) {
- const { open, mode, onClose } = props;
+ const { open, mode } = props;
if (!open || mode.kind === "closed") return null;
if (mode.kind === "view") return ;
if (mode.kind === "day-in-range")
diff --git a/src/admin/hooks/useAttendanceAdmin.ts b/src/admin/hooks/useAttendanceAdmin.ts
index 5870eb1..27a41b7 100644
--- a/src/admin/hooks/useAttendanceAdmin.ts
+++ b/src/admin/hooks/useAttendanceAdmin.ts
@@ -234,7 +234,6 @@ function computeUserTotals(
}
const holidayDates = holidaysInMonth(yr, mo + 1);
- const holidayCount = holidayDates.length;
for (const uid of Object.keys(totals)) {
const t = totals[uid];
@@ -476,14 +475,12 @@ function buildUserSectionHtml(
// Sum of vacation/sick/unpaid hours (in hours, not minutes). The
// "holiday" leave_type is auto-computed from Czech holidays further down
// and no longer selectable in the UI, so it's deliberately omitted here.
- let vacationHours = 0,
- sickHours = 0;
+ let vacationHours = 0;
for (const r of userRecords) {
const lt = r.leave_type || "work";
if (lt === "work") continue;
const h = Number(r.leave_hours) || 8;
if (lt === "vacation") vacationHours += h;
- else if (lt === "sick") sickHours += h;
}
// Odpracováno: floor(worked / 8) × 8.
@@ -492,7 +489,6 @@ function buildUserSectionHtml(
// Free Svátek: 8h per holiday date the user did not work.
const holidayDates = holidaysInMonth(yr, mo);
- const holidayCount = holidayDates.length;
const workedDates = new Set(
userRecords
.filter((r) => (r.leave_type || "work") === "work")
diff --git a/src/admin/lib/queries/mutations.ts b/src/admin/lib/queries/mutations.ts
index 9a3504f..a93674b 100644
--- a/src/admin/lib/queries/mutations.ts
+++ b/src/admin/lib/queries/mutations.ts
@@ -92,7 +92,7 @@ async function performMutation(opts: {
return result.data as TOut;
}
-export interface ApiMutationOptions {
+export interface ApiMutationOptions {
url: string | ((input: TIn) => string);
method: HttpMethod | ((input: TIn) => HttpMethod);
/** Query-key prefixes to invalidate on success. Broad per CLAUDE.md. */
@@ -122,7 +122,7 @@ export interface ApiMutationOptions {
* as `ApiError` (with `.status` attached) so callers can branch on HTTP code.
*/
export function useApiMutation(
- opts: ApiMutationOptions &
+ opts: ApiMutationOptions &
Omit, "mutationFn">,
) {
const { url, method, invalidate, envelope, onSuccess, ...rest } = opts;
diff --git a/src/admin/lib/queries/plan.ts b/src/admin/lib/queries/plan.ts
index e253cd3..f94a9bc 100644
--- a/src/admin/lib/queries/plan.ts
+++ b/src/admin/lib/queries/plan.ts
@@ -1,5 +1,4 @@
import { queryOptions } from "@tanstack/react-query";
-import apiFetch from "../../utils/api";
import { jsonQuery } from "../apiAdapter";
export interface PlanUser {
diff --git a/src/admin/pages/AttendanceHistory.tsx b/src/admin/pages/AttendanceHistory.tsx
index 495bc74..7dce0ad 100644
--- a/src/admin/pages/AttendanceHistory.tsx
+++ b/src/admin/pages/AttendanceHistory.tsx
@@ -1,5 +1,5 @@
import { useState, useMemo, useRef } from "react";
-import { useQuery, useQueryClient } from "@tanstack/react-query";
+import { useQuery } from "@tanstack/react-query";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { useAuth } from "../context/AuthContext";
@@ -9,7 +9,6 @@ import { iconBadgeSx } from "../theme";
import {
attendanceHistoryOptions,
type AttendanceRecord,
- type ProjectLogEntry,
} from "../lib/queries/attendance";
import {
formatDate,
@@ -201,7 +200,6 @@ const renderProjectCell = (record: AttendanceRecord) => {
export default function AttendanceHistory() {
const { user, hasPermission } = useAuth();
- const queryClient = useQueryClient();
const { data: companySettings } = useQuery(companySettingsOptions());
const companyName = companySettings?.company_name || "";
const printRef = useRef(null);
diff --git a/src/admin/pages/AttendanceLocation.tsx b/src/admin/pages/AttendanceLocation.tsx
index 1cd5117..cc0c84d 100644
--- a/src/admin/pages/AttendanceLocation.tsx
+++ b/src/admin/pages/AttendanceLocation.tsx
@@ -26,10 +26,7 @@ const LocationMap = styled("div")(({ theme }) => ({
}));
import { formatDate, formatTime } from "../utils/attendanceHelpers";
-import {
- attendanceLocationOptions,
- type LocationRecord,
-} from "../lib/queries/attendance";
+import { attendanceLocationOptions } from "../lib/queries/attendance";
import { Button, Card, LoadingState, PageEnter, PageHeader } from "../ui";
const BackIcon = (
diff --git a/src/admin/pages/CompanySettings.tsx b/src/admin/pages/CompanySettings.tsx
index 0c19d03..62fabcd 100644
--- a/src/admin/pages/CompanySettings.tsx
+++ b/src/admin/pages/CompanySettings.tsx
@@ -3,10 +3,7 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
-import {
- companySettingsOptions,
- type CompanySettingsData,
-} from "../lib/queries/settings";
+import { companySettingsOptions } from "../lib/queries/settings";
import { bankAccountsOptions, type BankAccount } from "../lib/queries/common";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
@@ -23,7 +20,6 @@ import {
TextField,
Select,
CheckboxField,
- StatusChip,
FileUpload,
LoadingState,
type DataColumn,
diff --git a/src/admin/pages/OrderDetail.tsx b/src/admin/pages/OrderDetail.tsx
index 72e03b1..19896a8 100644
--- a/src/admin/pages/OrderDetail.tsx
+++ b/src/admin/pages/OrderDetail.tsx
@@ -1,14 +1,7 @@
import { useState, useEffect, useMemo, useRef } from "react";
import DOMPurify from "dompurify";
import { useQuery } from "@tanstack/react-query";
-import {
- orderDetailOptions,
- type OrderData,
- type OrderItem,
- type OrderSection,
- type OrderInvoice,
- type OrderProject,
-} from "../lib/queries/orders";
+import { orderDetailOptions, type OrderItem } from "../lib/queries/orders";
import { useApiMutation } from "../lib/queries/mutations";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
diff --git a/src/admin/pages/ProjectDetail.tsx b/src/admin/pages/ProjectDetail.tsx
index 1bb1a8e..ef7b5bb 100644
--- a/src/admin/pages/ProjectDetail.tsx
+++ b/src/admin/pages/ProjectDetail.tsx
@@ -11,7 +11,6 @@ import MenuItem from "@mui/material/MenuItem";
import {
projectDetailOptions,
- type ProjectData,
type ProjectNote,
} from "../lib/queries/projects";
import { userListOptions, type User as ApiUser } from "../lib/queries/users";
diff --git a/src/admin/pages/Trips.tsx b/src/admin/pages/Trips.tsx
index cb283e4..1a09de0 100644
--- a/src/admin/pages/Trips.tsx
+++ b/src/admin/pages/Trips.tsx
@@ -199,7 +199,7 @@ export default function Trips() {
TripForm,
{ message?: string; error?: string }
>({
- url: (formData) =>
+ url: () =>
editingTrip ? `${API_BASE}/trips/${editingTrip.id}` : `${API_BASE}/trips`,
method: () => (editingTrip ? "PUT" : "POST"),
invalidate: ["trips", "vehicles"],
diff --git a/src/admin/pages/WarehouseInventoryForm.tsx b/src/admin/pages/WarehouseInventoryForm.tsx
index 368b1db..29bf853 100644
--- a/src/admin/pages/WarehouseInventoryForm.tsx
+++ b/src/admin/pages/WarehouseInventoryForm.tsx
@@ -23,7 +23,7 @@ interface InventoryItem {
}
function parseDecimal(raw: string): number {
- const cleaned = raw.replace(/[eE+\-]/g, "");
+ const cleaned = raw.replace(/[eE+-]/g, "");
const n = Number(cleaned);
return Number.isFinite(n) ? n : 0;
}
diff --git a/src/admin/pages/WarehouseIssueForm.tsx b/src/admin/pages/WarehouseIssueForm.tsx
index ced9e00..dc7633e 100644
--- a/src/admin/pages/WarehouseIssueForm.tsx
+++ b/src/admin/pages/WarehouseIssueForm.tsx
@@ -65,7 +65,7 @@ interface BatchesResponse {
}
function parseDecimal(raw: string): number {
- const cleaned = raw.replace(/[eE+\-]/g, "");
+ const cleaned = raw.replace(/[eE+-]/g, "");
const n = Number(cleaned);
return Number.isFinite(n) ? n : 0;
}
diff --git a/src/admin/pages/WarehouseReceiptForm.tsx b/src/admin/pages/WarehouseReceiptForm.tsx
index f71ff3f..38ccb9f 100644
--- a/src/admin/pages/WarehouseReceiptForm.tsx
+++ b/src/admin/pages/WarehouseReceiptForm.tsx
@@ -50,7 +50,7 @@ interface MovementItem {
}
function parseDecimal(raw: string): number {
- const cleaned = raw.replace(/[eE+\-]/g, "");
+ const cleaned = raw.replace(/[eE+-]/g, "");
const n = Number(cleaned);
return Number.isFinite(n) ? n : 0;
}
diff --git a/src/middleware/auth.ts b/src/middleware/auth.ts
index 09610c8..4120fb9 100644
--- a/src/middleware/auth.ts
+++ b/src/middleware/auth.ts
@@ -1,7 +1,6 @@
import { FastifyRequest, FastifyReply } from "fastify";
import { verifyAccessToken } from "../services/auth";
import { error } from "../utils/response";
-import { AuthData } from "../types";
export async function requireAuth(
request: FastifyRequest,
diff --git a/src/routes/admin/customers.ts b/src/routes/admin/customers.ts
index 619e810..2ef7cd2 100644
--- a/src/routes/admin/customers.ts
+++ b/src/routes/admin/customers.ts
@@ -1,6 +1,6 @@
import { FastifyInstance } from "fastify";
import prisma from "../../config/database";
-import { requireAuth, requirePermission } from "../../middleware/auth";
+import { requirePermission } from "../../middleware/auth";
import { logAudit } from "../../services/audit";
import { success, error, parseId, paginated } from "../../utils/response";
import { parsePagination, buildPaginationMeta } from "../../utils/pagination";
diff --git a/src/routes/admin/invoices.ts b/src/routes/admin/invoices.ts
index 03b0c6c..8ef2a50 100644
--- a/src/routes/admin/invoices.ts
+++ b/src/routes/admin/invoices.ts
@@ -13,7 +13,6 @@ import {
markOverdueInvoices,
listInvoices,
getInvoiceListTotals,
- getNextInvoiceNumberFormatted,
getNextInvoiceNumberPreview,
getInvoiceStats,
getOrderDataForInvoice,
diff --git a/src/routes/admin/project-files.ts b/src/routes/admin/project-files.ts
index a2129cf..4096de9 100644
--- a/src/routes/admin/project-files.ts
+++ b/src/routes/admin/project-files.ts
@@ -199,7 +199,7 @@ export default async function projectFilesRoutes(
const subPath = parsedQuery.data.path || "";
const rawFileName = file.filename;
- const fileName = rawFileName.replace(/[\/\\:*?"<>|]/g, "_");
+ const fileName = rawFileName.replace(/[/\\:*?"<>|]/g, "_");
const buffer = await file.toBuffer();
const err = await fm.uploadFile(
diff --git a/src/routes/admin/warehouse.ts b/src/routes/admin/warehouse.ts
index 79873b4..f3e1c6d 100644
--- a/src/routes/admin/warehouse.ts
+++ b/src/routes/admin/warehouse.ts
@@ -2,7 +2,7 @@ import { FastifyInstance } from "fastify";
import multipart from "@fastify/multipart";
import prisma from "../../config/database";
import { config } from "../../config/env";
-import { requireAuth, requirePermission } from "../../middleware/auth";
+import { requirePermission } from "../../middleware/auth";
import { logAudit } from "../../services/audit";
import { success, error, parseId, paginated } from "../../utils/response";
import { contentDisposition } from "../../utils/content-disposition";
@@ -2209,7 +2209,7 @@ export default async function warehouseRoutes(
// Build items with auto-filled system_qty and calculated difference
const itemsData = await Promise.all(
body.items.map(async (item) => {
- let systemQty = 0;
+ let systemQty: number;
if (item.location_id != null) {
// Get stock at specific location
@@ -2318,7 +2318,7 @@ export default async function warehouseRoutes(
if (body.items) {
itemsData = await Promise.all(
body.items.map(async (item) => {
- let systemQty = 0;
+ let systemQty: number;
if (item.location_id != null) {
const loc = await prisma.sklad_item_locations.findUnique({
diff --git a/src/services/attendance.service.ts b/src/services/attendance.service.ts
index 6a9a5cc..6a17a04 100644
--- a/src/services/attendance.service.ts
+++ b/src/services/attendance.service.ts
@@ -791,7 +791,7 @@ export async function getProjectReport(year: number) {
// Use detailed project logs (started_at/ended_at or hours/minutes)
for (const log of rec.attendance_project_logs) {
- let hours = 0;
+ let hours: number;
if (log.hours != null || log.minutes != null) {
hours = (Number(log.hours) || 0) + (Number(log.minutes) || 0) / 60;
} else if (log.started_at && log.ended_at) {
diff --git a/src/services/auth.ts b/src/services/auth.ts
index d723e93..57805d2 100644
--- a/src/services/auth.ts
+++ b/src/services/auth.ts
@@ -1,7 +1,7 @@
import crypto from "crypto";
import jwt from "jsonwebtoken";
import bcrypt from "bcryptjs";
-import { FastifyRequest, FastifyReply } from "fastify";
+import { FastifyRequest } from "fastify";
import prisma from "../config/database";
import { config } from "../config/env";
import { AuthData, JwtPayload } from "../types";
diff --git a/src/utils/pagination.ts b/src/utils/pagination.ts
index eb80c6c..460d49d 100644
--- a/src/utils/pagination.ts
+++ b/src/utils/pagination.ts
@@ -1,4 +1,4 @@
-import { PaginationQuery, PaginationMeta } from "../types";
+import { PaginationMeta } from "../types";
/**
* Parse common pagination/sort/search query params.