refactor: Split ai-kurzy.service.js into domain-specific files

Split 445-line monolith into:
- ai-kurzy/kurzy.service.js: course CRUD + stats
- ai-kurzy/ucastnici.service.js: participant CRUD
- ai-kurzy/registracie.service.js: registration CRUD, combined table,
  field updates, and document (prilohy) operations

Original ai-kurzy.service.js becomes a barrel export preserving all
existing import paths.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
richardtekula
2026-01-28 07:43:32 +01:00
parent 37dbf1b177
commit 57e6a2ea45
4 changed files with 434 additions and 445 deletions

View File

@@ -1,445 +1,7 @@
import { db } from '../config/database.js';
import { kurzy, ucastnici, registracie, prilohy } from '../db/schema.js';
import { and, desc, eq, sql, asc } from 'drizzle-orm';
import { NotFoundError } from '../utils/errors.js';
// ==================== KURZY (Courses) ====================
export const getAllKurzy = async () => {
const result = await db
.select({
id: kurzy.id,
nazov: kurzy.nazov,
typKurzu: kurzy.typKurzu,
popis: kurzy.popis,
cena: kurzy.cena,
maxKapacita: kurzy.maxKapacita,
aktivny: kurzy.aktivny,
farba: kurzy.farba,
createdAt: kurzy.createdAt,
registraciiCount: sql`(SELECT COUNT(*) FROM registracie WHERE kurz_id = ${kurzy.id})::int`,
})
.from(kurzy)
.orderBy(asc(kurzy.nazov));
return result;
};
export const getKurzById = async (id) => {
const [kurz] = await db
.select()
.from(kurzy)
.where(eq(kurzy.id, id))
.limit(1);
if (!kurz) {
throw new NotFoundError('Kurz nenájdený');
}
return kurz;
};
export const createKurz = async (data) => {
const [newKurz] = await db
.insert(kurzy)
.values({
nazov: data.nazov,
typKurzu: data.typKurzu,
popis: data.popis || null,
cena: data.cena,
maxKapacita: data.maxKapacita || null,
aktivny: data.aktivny !== undefined ? data.aktivny : true,
farba: data.farba || null,
})
.returning();
return newKurz;
};
export const updateKurz = async (id, data) => {
await getKurzById(id);
const updateData = {
nazov: data.nazov,
typKurzu: data.typKurzu,
popis: data.popis !== undefined ? data.popis : undefined,
cena: data.cena,
maxKapacita: data.maxKapacita !== undefined ? data.maxKapacita : undefined,
aktivny: data.aktivny !== undefined ? data.aktivny : undefined,
farba: data.farba !== undefined ? data.farba : undefined,
updatedAt: new Date(),
};
// Remove undefined values
Object.keys(updateData).forEach(key => {
if (updateData[key] === undefined) {
delete updateData[key];
}
});
const [updated] = await db
.update(kurzy)
.set(updateData)
.where(eq(kurzy.id, id))
.returning();
return updated;
};
export const deleteKurz = async (id) => {
await getKurzById(id);
await db.delete(kurzy).where(eq(kurzy.id, id));
return { success: true, message: 'Kurz bol odstránený' };
};
// ==================== UCASTNICI (Participants) ====================
export const getAllUcastnici = async () => {
const result = await db
.select({
id: ucastnici.id,
titul: ucastnici.titul,
meno: ucastnici.meno,
priezvisko: ucastnici.priezvisko,
email: ucastnici.email,
telefon: ucastnici.telefon,
firma: ucastnici.firma,
firmaIco: ucastnici.firmaIco,
firmaDic: ucastnici.firmaDic,
firmaIcDph: ucastnici.firmaIcDph,
firmaSidlo: ucastnici.firmaSidlo,
mesto: ucastnici.mesto,
ulica: ucastnici.ulica,
psc: ucastnici.psc,
createdAt: ucastnici.createdAt,
registraciiCount: sql`(SELECT COUNT(*) FROM registracie WHERE ucastnik_id = ${ucastnici.id})::int`,
})
.from(ucastnici)
.orderBy(asc(ucastnici.priezvisko), asc(ucastnici.meno));
return result;
};
export const getUcastnikById = async (id) => {
const [ucastnik] = await db
.select()
.from(ucastnici)
.where(eq(ucastnici.id, id))
.limit(1);
if (!ucastnik) {
throw new NotFoundError('Účastník nenájdený');
}
return ucastnik;
};
export const createUcastnik = async (data) => {
const [newUcastnik] = await db
.insert(ucastnici)
.values({
titul: data.titul || null,
meno: data.meno,
priezvisko: data.priezvisko,
email: data.email,
telefon: data.telefon || null,
firma: data.firma || null,
firmaIco: data.firmaIco || null,
firmaDic: data.firmaDic || null,
firmaIcDph: data.firmaIcDph || null,
firmaSidlo: data.firmaSidlo || null,
mesto: data.mesto || null,
ulica: data.ulica || null,
psc: data.psc || null,
})
.returning();
return newUcastnik;
};
export const updateUcastnik = async (id, data) => {
await getUcastnikById(id);
const [updated] = await db
.update(ucastnici)
.set({
...data,
updatedAt: new Date(),
})
.where(eq(ucastnici.id, id))
.returning();
return updated;
};
export const deleteUcastnik = async (id) => {
await getUcastnikById(id);
await db.delete(ucastnici).where(eq(ucastnici.id, id));
return { success: true, message: 'Účastník bol odstránený' };
};
// ==================== REGISTRACIE (Registrations) ====================
export const getAllRegistracie = async (kurzId = null) => {
const conditions = kurzId ? [eq(registracie.kurzId, kurzId)] : [];
const result = await db
.select({
id: registracie.id,
kurzId: registracie.kurzId,
ucastnikId: registracie.ucastnikId,
datumOd: registracie.datumOd,
datumDo: registracie.datumDo,
formaKurzu: registracie.formaKurzu,
pocetUcastnikov: registracie.pocetUcastnikov,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
// Kurz info
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
// Ucastnik info
ucastnikMeno: ucastnici.meno,
ucastnikPriezvisko: ucastnici.priezvisko,
ucastnikEmail: ucastnici.email,
ucastnikFirma: ucastnici.firma,
})
.from(registracie)
.leftJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.leftJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.where(conditions.length > 0 ? and(...conditions) : undefined)
.orderBy(desc(registracie.datumOd), desc(registracie.createdAt));
return result;
};
export const getRegistraciaById = async (id) => {
const [reg] = await db
.select({
id: registracie.id,
kurzId: registracie.kurzId,
ucastnikId: registracie.ucastnikId,
formaKurzu: registracie.formaKurzu,
pocetUcastnikov: registracie.pocetUcastnikov,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
ucastnikMeno: ucastnici.meno,
ucastnikPriezvisko: ucastnici.priezvisko,
ucastnikEmail: ucastnici.email,
})
.from(registracie)
.leftJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.leftJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.where(eq(registracie.id, id))
.limit(1);
if (!reg) {
throw new NotFoundError('Registrácia nenájdená');
}
return reg;
};
export const createRegistracia = async (data) => {
const [newReg] = await db
.insert(registracie)
.values({
kurzId: data.kurzId,
ucastnikId: data.ucastnikId,
datumOd: data.datumOd ? new Date(data.datumOd) : null,
datumDo: data.datumDo ? new Date(data.datumDo) : null,
formaKurzu: data.formaKurzu || 'prezencne',
pocetUcastnikov: data.pocetUcastnikov || 1,
fakturaCislo: data.fakturaCislo || null,
fakturaVystavena: data.fakturaVystavena || false,
zaplatene: data.zaplatene || false,
stav: data.stav || 'registrovany',
poznamka: data.poznamka || null,
})
.returning();
return newReg;
};
export const updateRegistracia = async (id, data) => {
await getRegistraciaById(id);
const [updated] = await db
.update(registracie)
.set({
...data,
updatedAt: new Date(),
})
.where(eq(registracie.id, id))
.returning();
return updated;
};
export const deleteRegistracia = async (id) => {
await getRegistraciaById(id);
await db.delete(registracie).where(eq(registracie.id, id));
return { success: true, message: 'Registrácia bola odstránená' };
};
// ==================== COMBINED TABLE VIEW (Excel-style) ====================
export const getCombinedTableData = async () => {
const result = await db
.select({
// Registration ID (main row identifier)
id: registracie.id,
// Ucastnik fields
ucastnikId: ucastnici.id,
titul: ucastnici.titul,
meno: ucastnici.meno,
priezvisko: ucastnici.priezvisko,
email: ucastnici.email,
telefon: ucastnici.telefon,
firma: ucastnici.firma,
firmaIco: ucastnici.firmaIco,
firmaDic: ucastnici.firmaDic,
firmaIcDph: ucastnici.firmaIcDph,
firmaSidlo: ucastnici.firmaSidlo,
mesto: ucastnici.mesto,
ulica: ucastnici.ulica,
psc: ucastnici.psc,
// Kurz fields
kurzId: kurzy.id,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
kurzFarba: kurzy.farba,
// Registration fields (dates are now here)
datumOd: registracie.datumOd,
datumDo: registracie.datumDo,
formaKurzu: registracie.formaKurzu,
pocetUcastnikov: registracie.pocetUcastnikov,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
// Document count
dokumentyCount: sql`(SELECT COUNT(*) FROM prilohy WHERE registracia_id = ${registracie.id})::int`,
})
.from(registracie)
.innerJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.innerJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.orderBy(desc(registracie.datumOd), desc(registracie.createdAt));
return result;
};
// Update a single field (for inline editing)
export const updateField = async (registrationId, field, value) => {
// Determine which table to update based on the field
const ucastnikFields = ['titul', 'meno', 'priezvisko', 'email', 'telefon', 'firma', 'firmaIco', 'firmaDic', 'firmaIcDph', 'firmaSidlo', 'mesto', 'ulica', 'psc'];
const registraciaFields = ['datumOd', 'datumDo', 'formaKurzu', 'pocetUcastnikov', 'fakturaCislo', 'fakturaVystavena', 'zaplatene', 'stav', 'poznamka', 'kurzId'];
const dateFields = ['datumOd', 'datumDo'];
// Get the registration to find ucastnikId
const [reg] = await db
.select({ ucastnikId: registracie.ucastnikId })
.from(registracie)
.where(eq(registracie.id, registrationId))
.limit(1);
if (!reg) {
throw new NotFoundError('Registrácia nenájdená');
}
// Convert date strings to Date objects
let processedValue = value;
if (dateFields.includes(field)) {
processedValue = value ? new Date(value) : null;
}
if (ucastnikFields.includes(field)) {
// Update ucastnik table
await db
.update(ucastnici)
.set({ [field]: processedValue, updatedAt: new Date() })
.where(eq(ucastnici.id, reg.ucastnikId));
} else if (registraciaFields.includes(field)) {
// Update registracie table
await db
.update(registracie)
.set({ [field]: processedValue, updatedAt: new Date() })
.where(eq(registracie.id, registrationId));
} else {
throw new Error(`Unknown field: ${field}`);
}
return { success: true };
};
// ==================== PRILOHY (Documents) ====================
export const getPrilohyByRegistracia = async (registraciaId) => {
const result = await db
.select()
.from(prilohy)
.where(eq(prilohy.registraciaId, registraciaId))
.orderBy(desc(prilohy.createdAt));
return result;
};
export const createPriloha = async (data) => {
const [newPriloha] = await db
.insert(prilohy)
.values({
registraciaId: data.registraciaId,
nazovSuboru: data.nazovSuboru,
typPrilohy: data.typPrilohy || 'ine',
cestaKSuboru: data.cestaKSuboru,
mimeType: data.mimeType || null,
velkostSuboru: data.velkostSuboru || null,
popis: data.popis || null,
})
.returning();
return newPriloha;
};
export const deletePriloha = async (id) => {
const [priloha] = await db
.select()
.from(prilohy)
.where(eq(prilohy.id, id))
.limit(1);
if (!priloha) {
throw new NotFoundError('Príloha nenájdená');
}
await db.delete(prilohy).where(eq(prilohy.id, id));
return { success: true, filePath: priloha.cestaKSuboru };
};
// ==================== STATISTICS ====================
export const getKurzyStats = async () => {
const [stats] = await db
.select({
totalKurzy: sql`(SELECT COUNT(*) FROM kurzy)::int`,
aktivneKurzy: sql`(SELECT COUNT(*) FROM kurzy WHERE aktivny = true)::int`,
totalUcastnici: sql`(SELECT COUNT(*) FROM ucastnici)::int`,
totalRegistracie: sql`(SELECT COUNT(*) FROM registracie)::int`,
zaplateneRegistracie: sql`(SELECT COUNT(*) FROM registracie WHERE zaplatene = true)::int`,
absolvovaneRegistracie: sql`(SELECT COUNT(*) FROM registracie WHERE stav = 'absolvoval')::int`,
})
.from(sql`(SELECT 1) AS dummy`);
return stats;
};
export { getAllKurzy, getKurzById, createKurz, updateKurz, deleteKurz, getKurzyStats } from './ai-kurzy/kurzy.service.js';
export { getAllUcastnici, getUcastnikById, createUcastnik, updateUcastnik, deleteUcastnik } from './ai-kurzy/ucastnici.service.js';
export {
getAllRegistracie, getRegistraciaById, createRegistracia, updateRegistracia, deleteRegistracia,
getCombinedTableData, updateField,
getPrilohyByRegistracia, createPriloha, deletePriloha,
} from './ai-kurzy/registracie.service.js';

View File

@@ -0,0 +1,105 @@
import { db } from '../../config/database.js';
import { kurzy } from '../../db/schema.js';
import { eq, sql, asc } from 'drizzle-orm';
import { NotFoundError } from '../../utils/errors.js';
export const getAllKurzy = async () => {
const result = await db
.select({
id: kurzy.id,
nazov: kurzy.nazov,
typKurzu: kurzy.typKurzu,
popis: kurzy.popis,
cena: kurzy.cena,
maxKapacita: kurzy.maxKapacita,
aktivny: kurzy.aktivny,
farba: kurzy.farba,
createdAt: kurzy.createdAt,
registraciiCount: sql`(SELECT COUNT(*) FROM registracie WHERE kurz_id = ${kurzy.id})::int`,
})
.from(kurzy)
.orderBy(asc(kurzy.nazov));
return result;
};
export const getKurzById = async (id) => {
const [kurz] = await db
.select()
.from(kurzy)
.where(eq(kurzy.id, id))
.limit(1);
if (!kurz) {
throw new NotFoundError('Kurz nenájdený');
}
return kurz;
};
export const createKurz = async (data) => {
const [newKurz] = await db
.insert(kurzy)
.values({
nazov: data.nazov,
typKurzu: data.typKurzu,
popis: data.popis || null,
cena: data.cena,
maxKapacita: data.maxKapacita || null,
aktivny: data.aktivny !== undefined ? data.aktivny : true,
farba: data.farba || null,
})
.returning();
return newKurz;
};
export const updateKurz = async (id, data) => {
await getKurzById(id);
const updateData = {
nazov: data.nazov,
typKurzu: data.typKurzu,
popis: data.popis !== undefined ? data.popis : undefined,
cena: data.cena,
maxKapacita: data.maxKapacita !== undefined ? data.maxKapacita : undefined,
aktivny: data.aktivny !== undefined ? data.aktivny : undefined,
farba: data.farba !== undefined ? data.farba : undefined,
updatedAt: new Date(),
};
Object.keys(updateData).forEach(key => {
if (updateData[key] === undefined) {
delete updateData[key];
}
});
const [updated] = await db
.update(kurzy)
.set(updateData)
.where(eq(kurzy.id, id))
.returning();
return updated;
};
export const deleteKurz = async (id) => {
await getKurzById(id);
await db.delete(kurzy).where(eq(kurzy.id, id));
return { success: true, message: 'Kurz bol odstránený' };
};
export const getKurzyStats = async () => {
const [stats] = await db
.select({
totalKurzy: sql`(SELECT COUNT(*) FROM kurzy)::int`,
aktivneKurzy: sql`(SELECT COUNT(*) FROM kurzy WHERE aktivny = true)::int`,
totalUcastnici: sql`(SELECT COUNT(*) FROM ucastnici)::int`,
totalRegistracie: sql`(SELECT COUNT(*) FROM registracie)::int`,
zaplateneRegistracie: sql`(SELECT COUNT(*) FROM registracie WHERE zaplatene = true)::int`,
absolvovaneRegistracie: sql`(SELECT COUNT(*) FROM registracie WHERE stav = 'absolvoval')::int`,
})
.from(sql`(SELECT 1) AS dummy`);
return stats;
};

View File

@@ -0,0 +1,234 @@
import { db } from '../../config/database.js';
import { kurzy, ucastnici, registracie, prilohy } from '../../db/schema.js';
import { and, desc, eq, sql } from 'drizzle-orm';
import { NotFoundError } from '../../utils/errors.js';
export const getAllRegistracie = async (kurzId = null) => {
const conditions = kurzId ? [eq(registracie.kurzId, kurzId)] : [];
const result = await db
.select({
id: registracie.id,
kurzId: registracie.kurzId,
ucastnikId: registracie.ucastnikId,
datumOd: registracie.datumOd,
datumDo: registracie.datumDo,
formaKurzu: registracie.formaKurzu,
pocetUcastnikov: registracie.pocetUcastnikov,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
ucastnikMeno: ucastnici.meno,
ucastnikPriezvisko: ucastnici.priezvisko,
ucastnikEmail: ucastnici.email,
ucastnikFirma: ucastnici.firma,
})
.from(registracie)
.leftJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.leftJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.where(conditions.length > 0 ? and(...conditions) : undefined)
.orderBy(desc(registracie.datumOd), desc(registracie.createdAt));
return result;
};
export const getRegistraciaById = async (id) => {
const [reg] = await db
.select({
id: registracie.id,
kurzId: registracie.kurzId,
ucastnikId: registracie.ucastnikId,
formaKurzu: registracie.formaKurzu,
pocetUcastnikov: registracie.pocetUcastnikov,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
ucastnikMeno: ucastnici.meno,
ucastnikPriezvisko: ucastnici.priezvisko,
ucastnikEmail: ucastnici.email,
})
.from(registracie)
.leftJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.leftJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.where(eq(registracie.id, id))
.limit(1);
if (!reg) {
throw new NotFoundError('Registrácia nenájdená');
}
return reg;
};
export const createRegistracia = async (data) => {
const [newReg] = await db
.insert(registracie)
.values({
kurzId: data.kurzId,
ucastnikId: data.ucastnikId,
datumOd: data.datumOd ? new Date(data.datumOd) : null,
datumDo: data.datumDo ? new Date(data.datumDo) : null,
formaKurzu: data.formaKurzu || 'prezencne',
pocetUcastnikov: data.pocetUcastnikov || 1,
fakturaCislo: data.fakturaCislo || null,
fakturaVystavena: data.fakturaVystavena || false,
zaplatene: data.zaplatene || false,
stav: data.stav || 'registrovany',
poznamka: data.poznamka || null,
})
.returning();
return newReg;
};
export const updateRegistracia = async (id, data) => {
await getRegistraciaById(id);
const [updated] = await db
.update(registracie)
.set({
...data,
updatedAt: new Date(),
})
.where(eq(registracie.id, id))
.returning();
return updated;
};
export const deleteRegistracia = async (id) => {
await getRegistraciaById(id);
await db.delete(registracie).where(eq(registracie.id, id));
return { success: true, message: 'Registrácia bola odstránená' };
};
export const getCombinedTableData = async () => {
const result = await db
.select({
id: registracie.id,
ucastnikId: ucastnici.id,
titul: ucastnici.titul,
meno: ucastnici.meno,
priezvisko: ucastnici.priezvisko,
email: ucastnici.email,
telefon: ucastnici.telefon,
firma: ucastnici.firma,
firmaIco: ucastnici.firmaIco,
firmaDic: ucastnici.firmaDic,
firmaIcDph: ucastnici.firmaIcDph,
firmaSidlo: ucastnici.firmaSidlo,
mesto: ucastnici.mesto,
ulica: ucastnici.ulica,
psc: ucastnici.psc,
kurzId: kurzy.id,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
kurzFarba: kurzy.farba,
datumOd: registracie.datumOd,
datumDo: registracie.datumDo,
formaKurzu: registracie.formaKurzu,
pocetUcastnikov: registracie.pocetUcastnikov,
fakturaCislo: registracie.fakturaCislo,
fakturaVystavena: registracie.fakturaVystavena,
zaplatene: registracie.zaplatene,
stav: registracie.stav,
poznamka: registracie.poznamka,
createdAt: registracie.createdAt,
dokumentyCount: sql`(SELECT COUNT(*) FROM prilohy WHERE registracia_id = ${registracie.id})::int`,
})
.from(registracie)
.innerJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
.innerJoin(kurzy, eq(registracie.kurzId, kurzy.id))
.orderBy(desc(registracie.datumOd), desc(registracie.createdAt));
return result;
};
export const updateField = async (registrationId, field, value) => {
const ucastnikFields = ['titul', 'meno', 'priezvisko', 'email', 'telefon', 'firma', 'firmaIco', 'firmaDic', 'firmaIcDph', 'firmaSidlo', 'mesto', 'ulica', 'psc'];
const registraciaFields = ['datumOd', 'datumDo', 'formaKurzu', 'pocetUcastnikov', 'fakturaCislo', 'fakturaVystavena', 'zaplatene', 'stav', 'poznamka', 'kurzId'];
const dateFields = ['datumOd', 'datumDo'];
const [reg] = await db
.select({ ucastnikId: registracie.ucastnikId })
.from(registracie)
.where(eq(registracie.id, registrationId))
.limit(1);
if (!reg) {
throw new NotFoundError('Registrácia nenájdená');
}
let processedValue = value;
if (dateFields.includes(field)) {
processedValue = value ? new Date(value) : null;
}
if (ucastnikFields.includes(field)) {
await db
.update(ucastnici)
.set({ [field]: processedValue, updatedAt: new Date() })
.where(eq(ucastnici.id, reg.ucastnikId));
} else if (registraciaFields.includes(field)) {
await db
.update(registracie)
.set({ [field]: processedValue, updatedAt: new Date() })
.where(eq(registracie.id, registrationId));
} else {
throw new Error(`Unknown field: ${field}`);
}
return { success: true };
};
export const getPrilohyByRegistracia = async (registraciaId) => {
const result = await db
.select()
.from(prilohy)
.where(eq(prilohy.registraciaId, registraciaId))
.orderBy(desc(prilohy.createdAt));
return result;
};
export const createPriloha = async (data) => {
const [newPriloha] = await db
.insert(prilohy)
.values({
registraciaId: data.registraciaId,
nazovSuboru: data.nazovSuboru,
typPrilohy: data.typPrilohy || 'ine',
cestaKSuboru: data.cestaKSuboru,
mimeType: data.mimeType || null,
velkostSuboru: data.velkostSuboru || null,
popis: data.popis || null,
})
.returning();
return newPriloha;
};
export const deletePriloha = async (id) => {
const [priloha] = await db
.select()
.from(prilohy)
.where(eq(prilohy.id, id))
.limit(1);
if (!priloha) {
throw new NotFoundError('Príloha nenájdená');
}
await db.delete(prilohy).where(eq(prilohy.id, id));
return { success: true, filePath: priloha.cestaKSuboru };
};

View File

@@ -0,0 +1,88 @@
import { db } from '../../config/database.js';
import { ucastnici } from '../../db/schema.js';
import { eq, sql, asc } from 'drizzle-orm';
import { NotFoundError } from '../../utils/errors.js';
export const getAllUcastnici = async () => {
const result = await db
.select({
id: ucastnici.id,
titul: ucastnici.titul,
meno: ucastnici.meno,
priezvisko: ucastnici.priezvisko,
email: ucastnici.email,
telefon: ucastnici.telefon,
firma: ucastnici.firma,
firmaIco: ucastnici.firmaIco,
firmaDic: ucastnici.firmaDic,
firmaIcDph: ucastnici.firmaIcDph,
firmaSidlo: ucastnici.firmaSidlo,
mesto: ucastnici.mesto,
ulica: ucastnici.ulica,
psc: ucastnici.psc,
createdAt: ucastnici.createdAt,
registraciiCount: sql`(SELECT COUNT(*) FROM registracie WHERE ucastnik_id = ${ucastnici.id})::int`,
})
.from(ucastnici)
.orderBy(asc(ucastnici.priezvisko), asc(ucastnici.meno));
return result;
};
export const getUcastnikById = async (id) => {
const [ucastnik] = await db
.select()
.from(ucastnici)
.where(eq(ucastnici.id, id))
.limit(1);
if (!ucastnik) {
throw new NotFoundError('Účastník nenájdený');
}
return ucastnik;
};
export const createUcastnik = async (data) => {
const [newUcastnik] = await db
.insert(ucastnici)
.values({
titul: data.titul || null,
meno: data.meno,
priezvisko: data.priezvisko,
email: data.email,
telefon: data.telefon || null,
firma: data.firma || null,
firmaIco: data.firmaIco || null,
firmaDic: data.firmaDic || null,
firmaIcDph: data.firmaIcDph || null,
firmaSidlo: data.firmaSidlo || null,
mesto: data.mesto || null,
ulica: data.ulica || null,
psc: data.psc || null,
})
.returning();
return newUcastnik;
};
export const updateUcastnik = async (id, data) => {
await getUcastnikById(id);
const [updated] = await db
.update(ucastnici)
.set({
...data,
updatedAt: new Date(),
})
.where(eq(ucastnici.id, id))
.returning();
return updated;
};
export const deleteUcastnik = async (id) => {
await getUcastnikById(id);
await db.delete(ucastnici).where(eq(ucastnici.id, id));
return { success: true, message: 'Účastník bol odstránený' };
};