feat: Add farba field and company details to AI Kurzy module

- Add farba (color) field to kurzy schema and Zod validation
- Add company detail fields (firma_ico, firma_dic, firma_ic_dph, firma_sidlo) to ucastnici
- Remove console logs from ai-kurzy service
- Add SQL migration scripts for schema updates and data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
richardtekula
2026-01-21 14:27:03 +01:00
parent 4089bb4be2
commit 826fd467bc
5 changed files with 197 additions and 2 deletions

View File

@@ -435,6 +435,7 @@ export const kurzy = pgTable('kurzy', {
cena: numeric('cena', { precision: 10, scale: 2 }).notNull(),
maxKapacita: integer('max_kapacita'),
aktivny: boolean('aktivny').default(true).notNull(),
farba: varchar('farba', { length: 20 }), // Color for visual distinction (e.g., 'primary', 'info', 'warning')
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
});
@@ -448,6 +449,10 @@ export const ucastnici = pgTable('ucastnici', {
email: varchar('email', { length: 255 }).notNull().unique(),
telefon: varchar('telefon', { length: 50 }),
firma: varchar('firma', { length: 255 }),
firmaIco: varchar('firma_ico', { length: 20 }), // IČO spoločnosti
firmaDic: varchar('firma_dic', { length: 20 }), // DIČ spoločnosti
firmaIcDph: varchar('firma_ic_dph', { length: 25 }), // IČ DPH spoločnosti
firmaSidlo: text('firma_sidlo'), // Sídlo firmy (full address)
mesto: varchar('mesto', { length: 100 }),
ulica: varchar('ulica', { length: 255 }),
psc: varchar('psc', { length: 10 }),

View File

@@ -51,6 +51,7 @@ const createKurzSchema = z.object({
cena: z.string().or(z.number()),
maxKapacita: z.number().int().positive().optional().nullable(),
aktivny: z.boolean().optional(),
farba: z.string().max(20).optional().nullable(),
});
const updateKurzSchema = createKurzSchema.partial();
@@ -62,6 +63,10 @@ const createUcastnikSchema = z.object({
email: z.string().email().max(255),
telefon: z.string().max(50).optional().nullable(),
firma: z.string().max(255).optional().nullable(),
firmaIco: z.string().max(20).optional().nullable(),
firmaDic: z.string().max(20).optional().nullable(),
firmaIcDph: z.string().max(25).optional().nullable(),
firmaSidlo: z.string().optional().nullable(),
mesto: z.string().max(100).optional().nullable(),
ulica: z.string().max(255).optional().nullable(),
psc: z.string().max(10).optional().nullable(),

View File

@@ -15,6 +15,7 @@ export const getAllKurzy = async () => {
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`,
})
@@ -48,6 +49,7 @@ export const createKurz = async (data) => {
cena: data.cena,
maxKapacita: data.maxKapacita || null,
aktivny: data.aktivny !== undefined ? data.aktivny : true,
farba: data.farba || null,
})
.returning();
@@ -57,7 +59,23 @@ export const createKurz = async (data) => {
export const updateKurz = async (id, data) => {
await getKurzById(id);
const updateData = { ...data, updatedAt: new Date() };
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)
@@ -86,6 +104,10 @@ export const getAllUcastnici = async () => {
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,
@@ -122,6 +144,10 @@ export const createUcastnik = async (data) => {
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,
@@ -280,6 +306,10 @@ export const getCombinedTableData = async () => {
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,
@@ -287,6 +317,7 @@ export const getCombinedTableData = async () => {
kurzId: kurzy.id,
kurzNazov: kurzy.nazov,
kurzTyp: kurzy.typKurzu,
kurzFarba: kurzy.farba,
// Registration fields (dates are now here)
datumOd: registracie.datumOd,
datumDo: registracie.datumDo,
@@ -312,7 +343,7 @@ export const getCombinedTableData = async () => {
// 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', 'mesto', 'ulica', 'psc'];
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'];