generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") shadowDatabaseUrl = env("SHADOW_DATABASE_URL") } enum UserRole { USER ADMIN } model User { id String @id @default(cuid()) email String @unique username String @unique passwordHash String name String role UserRole @default(USER) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt companies Company[] auditLogs AuditLog[] @@map("users") } model AuditLog { id String @id @default(cuid()) userId String? user User? @relation(fields: [userId], references: [id], onDelete: SetNull) action String entity String? entityId String? metadata Json? ipAddress String? createdAt DateTime @default(now()) @@index([userId]) @@index([createdAt]) @@map("audit_logs") } model Company { id String @id @default(cuid()) name String legalForm String? taxId String? vatId String? address String zip String city String country String @default("DE") email String? phone String? website String? bankIban String? bankBic String? bankName String? invoicePrefix String @default("RE") invoiceSequence Int @default(0) kleinunternehmer Boolean @default(false) archived Boolean @default(false) archivedAt DateTime? userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) customers Customer[] invoices Invoice[] services Service[] anlagegueter Anlagegut[] buchungen Buchung[] kategorien BuchungKategorie[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("companies") } model BuchungKategorie { id String @id @default(cuid()) companyId String company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) name String // e.g., "Fußpflege", "Miete", "Privateinlagen" typ String // "EINNAHME" or "AUSGABE" createdAt DateTime @default(now()) @@unique([companyId, name, typ]) @@index([companyId]) @@map("buchung_kategorien") } enum TransactionAccount { KASSE BANK } enum TransactionType { EINLAGE ENTNAHME } model Buchung { id String @id @default(cuid()) companyId String company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) date DateTime account TransactionAccount type TransactionType amount Decimal @db.Decimal(10, 2) description String? @db.Text kategorie String? // Name of BuchungKategorie (nullable for manual transactions) steuersatz Int? // Tax rate: 0, 7, 19 (nullable for non-business records) zahlungsart Zahlungsart? // KASSE or BANK isBusinessRecord Boolean @default(false) // True if this is from Einnahme/Ausgabe linkedBuchungId String? linkedBuchung Buchung? @relation("BuchungLink", fields: [linkedBuchungId], references: [id], onDelete: SetNull) linkedFrom Buchung[] @relation("BuchungLink") invoice Invoice? // Back-relation: Invoice -> Buchung (via buchungId) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([companyId]) @@index([date]) @@index([isBusinessRecord]) @@map("buchungen") } model Service { id String @id @default(cuid()) companyId String company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) name String description String? @db.Text unit String? unitPrice Decimal @db.Decimal(10, 2) taxRate Decimal @db.Decimal(5, 2) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("services") } model Customer { id String @id @default(cuid()) companyId String company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) name String taxId String? address String zip String city String country String @default("DE") email String? phone String? invoices Invoice[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("customers") } model Invoice { id String @id @default(cuid()) number String? companyId String company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) customerId String customer Customer @relation(fields: [customerId], references: [id]) issueDate DateTime deliveryDate DateTime? dueDate DateTime status InvoiceStatus @default(DRAFT) kleinunternehmer Boolean @default(false) notes String? @db.Text items InvoiceItem[] netTotal Decimal @db.Decimal(10, 2) taxTotal Decimal @db.Decimal(10, 2) grossTotal Decimal @db.Decimal(10, 2) buchungId String? @unique // Link to auto-created Buchung when PAID buchung Buchung? @relation(fields: [buchungId], references: [id], onDelete: SetNull) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? @@unique([companyId, number]) @@map("invoices") } enum InvoiceStatus { DRAFT SENT PAID CANCELLED DELETED } enum Zahlungsart { KASSE BANK } model Anlagegut { id String @id @default(cuid()) companyId String company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) bezeichnung String anschaffungsdatum DateTime anschaffungskosten Decimal @db.Decimal(10, 2) nutzungsdauerJahre Int restwert Decimal @db.Decimal(10, 2) @default(0) beschreibung String? @db.Text aktiv Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([companyId]) @@map("anlagegueter") } model InvoiceItem { id String @id @default(cuid()) invoiceId String invoice Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade) position Int description String @db.Text quantity Decimal @db.Decimal(10, 3) unit String? unitPrice Decimal @db.Decimal(10, 2) taxRate Decimal @db.Decimal(5, 2) netAmount Decimal @db.Decimal(10, 2) taxAmount Decimal @db.Decimal(10, 2) grossAmount Decimal @db.Decimal(10, 2) @@map("invoice_items") }