feat(invoices): add billingEntityType/Id for polymorphic billing

This commit is contained in:
Matt Ciaccio
2026-04-23 17:58:52 +02:00
parent d43298a74e
commit 117cfae52e
4 changed files with 8551 additions and 3 deletions

View File

@@ -0,0 +1,3 @@
ALTER TABLE "invoices" ADD COLUMN "billing_entity_type" text DEFAULT 'client' NOT NULL;--> statement-breakpoint
ALTER TABLE "invoices" ADD COLUMN "billing_entity_id" text DEFAULT '' NOT NULL;--> statement-breakpoint
CREATE INDEX "idx_invoices_billing_entity" ON "invoices" USING btree ("port_id","billing_entity_type","billing_entity_id");

File diff suppressed because it is too large Load Diff

View File

@@ -43,6 +43,13 @@
"when": 1776959832091, "when": 1776959832091,
"tag": "0005_stale_kronos", "tag": "0005_stale_kronos",
"breakpoints": true "breakpoints": true
},
{
"idx": 6,
"version": "7",
"when": 1776959911400,
"tag": "0006_great_pixie",
"breakpoints": true
} }
] ]
} }

View File

@@ -15,7 +15,9 @@ import { files } from './documents';
export const expenses = pgTable( export const expenses = pgTable(
'expenses', 'expenses',
{ {
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()), id: text('id')
.primaryKey()
.$defaultFn(() => crypto.randomUUID()),
portId: text('port_id') portId: text('port_id')
.notNull() .notNull()
.references(() => ports.id), .references(() => ports.id),
@@ -49,12 +51,16 @@ export const expenses = pgTable(
export const invoices = pgTable( export const invoices = pgTable(
'invoices', 'invoices',
{ {
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()), id: text('id')
.primaryKey()
.$defaultFn(() => crypto.randomUUID()),
portId: text('port_id') portId: text('port_id')
.notNull() .notNull()
.references(() => ports.id), .references(() => ports.id),
invoiceNumber: text('invoice_number').notNull(), // INV-YYYYMM-### auto-generated invoiceNumber: text('invoice_number').notNull(), // INV-YYYYMM-### auto-generated
clientName: text('client_name').notNull(), clientName: text('client_name').notNull(),
billingEntityType: text('billing_entity_type').notNull().default('client'), // 'client' | 'company'
billingEntityId: text('billing_entity_id').notNull().default(''),
billingEmail: text('billing_email'), billingEmail: text('billing_email'),
billingAddress: text('billing_address'), billingAddress: text('billing_address'),
dueDate: date('due_date').notNull(), dueDate: date('due_date').notNull(),
@@ -82,13 +88,20 @@ export const invoices = pgTable(
uniqueIndex('idx_invoices_number').on(table.portId, table.invoiceNumber), uniqueIndex('idx_invoices_number').on(table.portId, table.invoiceNumber),
index('idx_invoices_port').on(table.portId), index('idx_invoices_port').on(table.portId),
index('idx_invoices_status').on(table.portId, table.status), index('idx_invoices_status').on(table.portId, table.status),
index('idx_invoices_billing_entity').on(
table.portId,
table.billingEntityType,
table.billingEntityId,
),
], ],
); );
export const invoiceLineItems = pgTable( export const invoiceLineItems = pgTable(
'invoice_line_items', 'invoice_line_items',
{ {
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()), id: text('id')
.primaryKey()
.$defaultFn(() => crypto.randomUUID()),
invoiceId: text('invoice_id') invoiceId: text('invoice_id')
.notNull() .notNull()
.references(() => invoices.id, { onDelete: 'cascade' }), .references(() => invoices.id, { onDelete: 'cascade' }),