style: run prettier on entire codebase

This commit is contained in:
BOHA
2026-03-24 19:59:14 +01:00
parent 872be42107
commit 3c167cf5c4
148 changed files with 26740 additions and 13990 deletions

View File

@@ -1,14 +1,17 @@
import { FastifyInstance } from 'fastify';
import prisma from '../../config/database';
import { requireAuth, requirePermission } from '../../middleware/auth';
import { logAudit } from '../../services/audit';
import { success, error } from '../../utils/response';
import multipart from '@fastify/multipart';
import { parseBody } from '../../schemas/common';
import { UpdateCompanySettingsSchema } from '../../schemas/company-settings.schema';
import { FastifyInstance } from "fastify";
import prisma from "../../config/database";
import { requireAuth, requirePermission } from "../../middleware/auth";
import { logAudit } from "../../services/audit";
import { success, error } from "../../utils/response";
import multipart from "@fastify/multipart";
import { parseBody } from "../../schemas/common";
import { UpdateCompanySettingsSchema } from "../../schemas/company-settings.schema";
/** Encode custom_fields + supplier_field_order into a single JSON blob (matching PHP format) */
function encodeCustomFields(fields: unknown, fieldOrder: unknown): string | null {
function encodeCustomFields(
fields: unknown,
fieldOrder: unknown,
): string | null {
const f = Array.isArray(fields) ? fields : [];
const o = Array.isArray(fieldOrder) ? fieldOrder : [];
if (f.length === 0 && o.length === 0) return null;
@@ -16,13 +19,24 @@ function encodeCustomFields(fields: unknown, fieldOrder: unknown): string | null
}
/** Decode custom_fields JSON blob into separate fields + field_order for frontend */
function decodeCustomFields(raw: string | null): { custom_fields: unknown[]; supplier_field_order: string[] } {
function decodeCustomFields(raw: string | null): {
custom_fields: unknown[];
supplier_field_order: string[];
} {
if (!raw) return { custom_fields: [], supplier_field_order: [] };
try {
const parsed = JSON.parse(raw);
// PHP format: { fields: [...], field_order: [...] }
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed) && 'fields' in parsed) {
return { custom_fields: parsed.fields || [], supplier_field_order: parsed.field_order || [] };
if (
parsed &&
typeof parsed === "object" &&
!Array.isArray(parsed) &&
"fields" in parsed
) {
return {
custom_fields: parsed.fields || [],
supplier_field_order: parsed.field_order || [],
};
}
// Legacy TS format: raw array
if (Array.isArray(parsed)) {
@@ -34,47 +48,66 @@ function decodeCustomFields(raw: string | null): { custom_fields: unknown[]; sup
}
}
export default async function companySettingsRoutes(fastify: FastifyInstance): Promise<void> {
export default async function companySettingsRoutes(
fastify: FastifyInstance,
): Promise<void> {
await fastify.register(multipart, { limits: { fileSize: 5 * 1024 * 1024 } });
// GET /api/admin/company-settings/logo
fastify.get('/logo', { preHandler: requireAuth }, async (_request, reply) => {
const settings = await prisma.company_settings.findFirst({ select: { logo_data: true } });
if (!settings?.logo_data) return error(reply, 'Logo nenalezeno', 404);
fastify.get("/logo", { preHandler: requireAuth }, async (_request, reply) => {
const settings = await prisma.company_settings.findFirst({
select: { logo_data: true },
});
if (!settings?.logo_data) return error(reply, "Logo nenalezeno", 404);
// Detect image type from magic bytes
const buf = settings.logo_data;
let mime = 'image/png';
if (buf[0] === 0xFF && buf[1] === 0xD8) mime = 'image/jpeg';
else if (buf[0] === 0x47 && buf[1] === 0x49) mime = 'image/gif';
let mime = "image/png";
if (buf[0] === 0xff && buf[1] === 0xd8) mime = "image/jpeg";
else if (buf[0] === 0x47 && buf[1] === 0x49) mime = "image/gif";
return reply.type(mime).send(buf);
});
// POST /api/admin/company-settings/logo
fastify.post('/logo', { preHandler: requirePermission('offers.settings') }, async (request, reply) => {
const file = await request.file();
if (!file) return error(reply, 'Nebyl nahrán žádný soubor', 400);
fastify.post(
"/logo",
{ preHandler: requirePermission("offers.settings") },
async (request, reply) => {
const file = await request.file();
if (!file) return error(reply, "Nebyl nahrán žádný soubor", 400);
const allowed = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];
if (!allowed.includes(file.mimetype)) {
return error(reply, 'Nepodporovaný formát. Povoleno: PNG, JPG, GIF, WebP', 400);
}
const allowed = ["image/png", "image/jpeg", "image/gif", "image/webp"];
if (!allowed.includes(file.mimetype)) {
return error(
reply,
"Nepodporovaný formát. Povoleno: PNG, JPG, GIF, WebP",
400,
);
}
const buffer = await file.toBuffer();
const existing = await prisma.company_settings.findFirst();
if (!existing) return error(reply, 'Nastavení nenalezeno', 404);
const buffer = await file.toBuffer();
const existing = await prisma.company_settings.findFirst();
if (!existing) return error(reply, "Nastavení nenalezeno", 404);
await prisma.company_settings.update({
where: { id: existing.id },
data: { logo_data: new Uint8Array(buffer), modified_at: new Date() },
});
await prisma.company_settings.update({
where: { id: existing.id },
data: { logo_data: new Uint8Array(buffer), modified_at: new Date() },
});
await logAudit({ request, authData: request.authData, action: 'update', entityType: 'company_settings', entityId: existing.id, description: 'Nahráno logo' });
return success(reply, null, 200, 'Logo nahráno');
});
await logAudit({
request,
authData: request.authData,
action: "update",
entityType: "company_settings",
entityId: existing.id,
description: "Nahráno logo",
});
return success(reply, null, 200, "Logo nahráno");
},
);
fastify.get('/', { preHandler: requireAuth }, async (_request, reply) => {
fastify.get("/", { preHandler: requireAuth }, async (_request, reply) => {
let settings = await prisma.company_settings.findFirst({
select: {
id: true,
@@ -102,9 +135,9 @@ export default async function companySettingsRoutes(fastify: FastifyInstance): P
if (!settings) {
settings = await prisma.company_settings.create({
data: {
company_name: '',
quotation_prefix: 'N',
default_currency: 'EUR',
company_name: "",
quotation_prefix: "N",
default_currency: "EUR",
default_vat_rate: 21.0,
},
select: {
@@ -136,49 +169,97 @@ export default async function companySettingsRoutes(fastify: FastifyInstance): P
where: { id: settings.id },
select: { logo_data: true },
});
const has_logo = !!(logoCheck?.logo_data);
const has_logo = !!logoCheck?.logo_data;
const { custom_fields, supplier_field_order } = decodeCustomFields(settings.custom_fields as string | null);
const { custom_fields, supplier_field_order } = decodeCustomFields(
settings.custom_fields as string | null,
);
return success(reply, { ...settings, custom_fields, supplier_field_order, has_logo });
return success(reply, {
...settings,
custom_fields,
supplier_field_order,
has_logo,
});
});
fastify.put('/', { preHandler: requirePermission('offers.settings') }, async (request, reply) => {
const parsed = parseBody(UpdateCompanySettingsSchema, request.body);
if ('error' in parsed) return error(reply, parsed.error, 400);
const body = parsed.data;
fastify.put(
"/",
{ preHandler: requirePermission("offers.settings") },
async (request, reply) => {
const parsed = parseBody(UpdateCompanySettingsSchema, request.body);
if ("error" in parsed) return error(reply, parsed.error, 400);
const body = parsed.data;
const existing = await prisma.company_settings.findFirst();
if (!existing) return error(reply, 'Nastavení nenalezeno', 404);
const existing = await prisma.company_settings.findFirst();
if (!existing) return error(reply, "Nastavení nenalezeno", 404);
const data: Record<string, unknown> = { modified_at: new Date() };
const strFields = ['company_name', 'street', 'city', 'postal_code', 'country', 'company_id', 'vat_id', 'quotation_prefix', 'default_currency', 'order_type_code', 'invoice_type_code'];
const bodyRec = body as Record<string, unknown>;
for (const f of strFields) {
if (bodyRec[f] !== undefined) data[f] = bodyRec[f] ? String(bodyRec[f]) : null;
}
if (body.default_vat_rate !== undefined) data.default_vat_rate = Number(body.default_vat_rate);
if (body.require_2fa !== undefined) data.require_2fa = body.require_2fa === true || body.require_2fa === 1 || body.require_2fa === '1';
if (body.custom_fields !== undefined || body.supplier_field_order !== undefined) {
let existingFields: unknown[] = [];
let existingOrder: unknown[] = [];
if (existing.custom_fields) {
try {
const parsed = JSON.parse(existing.custom_fields);
existingFields = parsed?.fields || [];
existingOrder = parsed?.field_order || [];
} catch { /* invalid JSON, use defaults */ }
const data: Record<string, unknown> = { modified_at: new Date() };
const strFields = [
"company_name",
"street",
"city",
"postal_code",
"country",
"company_id",
"vat_id",
"quotation_prefix",
"default_currency",
"order_type_code",
"invoice_type_code",
];
const bodyRec = body as Record<string, unknown>;
for (const f of strFields) {
if (bodyRec[f] !== undefined)
data[f] = bodyRec[f] ? String(bodyRec[f]) : null;
}
data.custom_fields = encodeCustomFields(
body.custom_fields !== undefined ? body.custom_fields : existingFields,
body.supplier_field_order !== undefined ? body.supplier_field_order : existingOrder,
);
}
data.sync_version = (existing.sync_version ?? 0) + 1;
if (body.default_vat_rate !== undefined)
data.default_vat_rate = Number(body.default_vat_rate);
if (body.require_2fa !== undefined)
data.require_2fa =
body.require_2fa === true ||
body.require_2fa === 1 ||
body.require_2fa === "1";
if (
body.custom_fields !== undefined ||
body.supplier_field_order !== undefined
) {
let existingFields: unknown[] = [];
let existingOrder: unknown[] = [];
if (existing.custom_fields) {
try {
const parsed = JSON.parse(existing.custom_fields);
existingFields = parsed?.fields || [];
existingOrder = parsed?.field_order || [];
} catch {
/* invalid JSON, use defaults */
}
}
data.custom_fields = encodeCustomFields(
body.custom_fields !== undefined
? body.custom_fields
: existingFields,
body.supplier_field_order !== undefined
? body.supplier_field_order
: existingOrder,
);
}
data.sync_version = (existing.sync_version ?? 0) + 1;
await prisma.company_settings.update({ where: { id: existing.id }, data });
await prisma.company_settings.update({
where: { id: existing.id },
data,
});
await logAudit({ request, authData: request.authData, action: 'update', entityType: 'company_settings', entityId: existing.id, description: 'Upraveno firemní nastavení' });
return success(reply, { id: existing.id }, 200, 'Nastavení bylo uloženo');
});
await logAudit({
request,
authData: request.authData,
action: "update",
entityType: "company_settings",
entityId: existing.id,
description: "Upraveno firemní nastavení",
});
return success(reply, { id: existing.id }, 200, "Nastavení bylo uloženo");
},
);
}