Add account hierarchy framework with migrations, RLS policies, and UI components

This commit is contained in:
T. Zehetbauer
2026-03-31 22:18:04 +02:00
parent 7e7da0b465
commit 59546ad6d2
262 changed files with 11671 additions and 3927 deletions

View File

@@ -2,7 +2,13 @@ import { z } from 'zod';
export const DocumentTypeEnum = z.enum(['pdf', 'excel', 'word', 'label']);
export const DocumentTemplateTypeEnum = z.enum([
'member_card', 'invoice', 'label_avery', 'report', 'letter', 'certificate', 'custom',
'member_card',
'invoice',
'label_avery',
'report',
'letter',
'certificate',
'custom',
]);
export const GenerateDocumentSchema = z.object({
@@ -11,21 +17,27 @@ export const GenerateDocumentSchema = z.object({
templateType: DocumentTemplateTypeEnum,
title: z.string().min(1),
data: z.record(z.string(), z.unknown()),
options: z.object({
format: z.enum(['A4', 'A5', 'letter', 'label']).default('A4'),
orientation: z.enum(['portrait', 'landscape']).default('portrait'),
labelFormat: z.string().optional(), // e.g. 'avery-l7163'
}).optional(),
options: z
.object({
format: z.enum(['A4', 'A5', 'letter', 'label']).default('A4'),
orientation: z.enum(['portrait', 'landscape']).default('portrait'),
labelFormat: z.string().optional(), // e.g. 'avery-l7163'
})
.optional(),
});
export type GenerateDocumentInput = z.infer<typeof GenerateDocumentSchema>;
export const GenerateBatchLabelsSchema = z.object({
accountId: z.string().uuid(),
labelFormat: z.string().default('avery-l7163'),
records: z.array(z.object({
line1: z.string(),
line2: z.string().optional(),
line3: z.string().optional(),
line4: z.string().optional(),
})).min(1),
records: z
.array(
z.object({
line1: z.string(),
line2: z.string().optional(),
line3: z.string().optional(),
line4: z.string().optional(),
}),
)
.min(1),
});

View File

@@ -20,7 +20,7 @@ export function createDocumentGeneratorApi() {
// Dynamic import to avoid bundle bloat in SSR
// Actual implementation will use @react-pdf/renderer
throw new Error(
'PDF generation requires @react-pdf/renderer. Install it and implement the renderer in pdf-generator.service.ts'
'PDF generation requires @react-pdf/renderer. Install it and implement the renderer in pdf-generator.service.ts',
);
},
@@ -37,7 +37,7 @@ export function createDocumentGeneratorApi() {
}>;
}): Promise<Uint8Array> {
throw new Error(
'Excel generation requires exceljs. Install it and implement in excel-generator.service.ts'
'Excel generation requires exceljs. Install it and implement in excel-generator.service.ts',
);
},
@@ -51,7 +51,7 @@ export function createDocumentGeneratorApi() {
mergeFields: Record<string, string>;
}): Promise<Uint8Array> {
throw new Error(
'Word generation requires docx. Install it and implement in word-generator.service.ts'
'Word generation requires docx. Install it and implement in word-generator.service.ts',
);
},
@@ -61,7 +61,12 @@ export function createDocumentGeneratorApi() {
*/
generateLabelsHtml(params: {
labelFormat: string;
records: Array<{ line1: string; line2?: string; line3?: string; line4?: string }>;
records: Array<{
line1: string;
line2?: string;
line3?: string;
line4?: string;
}>;
}): string {
const { records } = params;
@@ -71,14 +76,18 @@ export function createDocumentGeneratorApi() {
for (let i = 0; i < records.length; i += labelsPerPage) {
const pageRecords = records.slice(i, i + labelsPerPage);
const labels = pageRecords.map((r) => `
const labels = pageRecords
.map(
(r) => `
<div style="width:99.1mm;height:38.1mm;padding:4mm;box-sizing:border-box;overflow:hidden;font-size:10pt;font-family:Arial,sans-serif;">
<div>${r.line1}</div>
${r.line2 ? `<div>${r.line2}</div>` : ''}
${r.line3 ? `<div>${r.line3}</div>` : ''}
${r.line4 ? `<div>${r.line4}</div>` : ''}
</div>
`).join('');
`,
)
.join('');
pages.push(`
<div style="width:210mm;display:grid;grid-template-columns:1fr 1fr;gap:0;page-break-after:always;">

View File

@@ -1,6 +1,8 @@
{
"extends": "@kit/tsconfig/base.json",
"compilerOptions": { "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" },
"compilerOptions": {
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
},
"include": ["*.ts", "*.tsx", "src"],
"exclude": ["node_modules"]
}