first version
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "ShopSettings" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"shopDomain" TEXT NOT NULL,
|
||||
"companyName" TEXT NOT NULL DEFAULT '',
|
||||
"legalForm" TEXT NOT NULL DEFAULT '',
|
||||
"ownerName" TEXT NOT NULL DEFAULT '',
|
||||
"addressLine1" TEXT NOT NULL DEFAULT '',
|
||||
"addressLine2" TEXT NOT NULL DEFAULT '',
|
||||
"postalCode" TEXT NOT NULL DEFAULT '',
|
||||
"city" TEXT NOT NULL DEFAULT '',
|
||||
"countryCode" TEXT NOT NULL DEFAULT 'AT',
|
||||
"phone" TEXT NOT NULL DEFAULT '',
|
||||
"email" TEXT NOT NULL DEFAULT '',
|
||||
"website" TEXT NOT NULL DEFAULT '',
|
||||
"vatId" TEXT NOT NULL DEFAULT '',
|
||||
"taxNumber" TEXT NOT NULL DEFAULT '',
|
||||
"registrationNo" TEXT NOT NULL DEFAULT '',
|
||||
"registrationCourt" TEXT NOT NULL DEFAULT '',
|
||||
"bankName" TEXT NOT NULL DEFAULT '',
|
||||
"iban" TEXT NOT NULL DEFAULT '',
|
||||
"bic" TEXT NOT NULL DEFAULT '',
|
||||
"giroCodeEnabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"numberingMode" TEXT NOT NULL DEFAULT 'shopify_order_number',
|
||||
"invoicePrefix" TEXT NOT NULL DEFAULT 'RE-',
|
||||
"invoiceSeed" INTEGER NOT NULL DEFAULT 1000,
|
||||
"defaultLanguage" TEXT NOT NULL DEFAULT 'de',
|
||||
"paymentTermDays" INTEGER NOT NULL DEFAULT 14,
|
||||
"footerNote" TEXT NOT NULL DEFAULT '',
|
||||
"kleinunternehmer" BOOLEAN NOT NULL DEFAULT false,
|
||||
"logoUrl" TEXT NOT NULL DEFAULT '',
|
||||
"smtpHost" TEXT NOT NULL DEFAULT '',
|
||||
"smtpPort" INTEGER NOT NULL DEFAULT 587,
|
||||
"smtpSecure" BOOLEAN NOT NULL DEFAULT false,
|
||||
"smtpUser" TEXT NOT NULL DEFAULT '',
|
||||
"smtpPassword" TEXT NOT NULL DEFAULT '',
|
||||
"smtpFromName" TEXT NOT NULL DEFAULT '',
|
||||
"smtpFromEmail" TEXT NOT NULL DEFAULT '',
|
||||
"smtpReplyTo" TEXT NOT NULL DEFAULT '',
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Invoice" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"shopDomain" TEXT NOT NULL,
|
||||
"orderId" TEXT NOT NULL,
|
||||
"orderName" TEXT NOT NULL,
|
||||
"orderNumber" INTEGER NOT NULL,
|
||||
"invoiceNumber" TEXT NOT NULL,
|
||||
"language" TEXT NOT NULL DEFAULT 'de',
|
||||
"kind" TEXT NOT NULL DEFAULT 'invoice',
|
||||
"version" INTEGER NOT NULL DEFAULT 1,
|
||||
"cancelsInvoiceId" TEXT,
|
||||
"pdfFileGid" TEXT NOT NULL DEFAULT '',
|
||||
"pdfUrl" TEXT NOT NULL DEFAULT '',
|
||||
"totalsJson" TEXT NOT NULL DEFAULT '{}',
|
||||
"customerJson" TEXT NOT NULL DEFAULT '{}',
|
||||
"issuedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"sentAt" DATETIME,
|
||||
"cancelledAt" DATETIME,
|
||||
"status" TEXT NOT NULL DEFAULT 'issued',
|
||||
"lastError" TEXT NOT NULL DEFAULT '',
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Invoice_shopDomain_fkey" FOREIGN KEY ("shopDomain") REFERENCES "ShopSettings" ("shopDomain") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "InvoiceCounter" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"shopDomain" TEXT NOT NULL,
|
||||
"lastValue" INTEGER NOT NULL DEFAULT 0,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "EmailLog" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"shopDomain" TEXT NOT NULL,
|
||||
"invoiceId" TEXT NOT NULL,
|
||||
"toAddress" TEXT NOT NULL,
|
||||
"subject" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"error" TEXT NOT NULL DEFAULT '',
|
||||
"sentAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LogoCache" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"shopDomain" TEXT NOT NULL,
|
||||
"sourceUrl" TEXT NOT NULL,
|
||||
"bytes" BLOB NOT NULL,
|
||||
"contentType" TEXT NOT NULL DEFAULT 'image/png',
|
||||
"etag" TEXT NOT NULL DEFAULT '',
|
||||
"fetchedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ShopSettings_shopDomain_key" ON "ShopSettings"("shopDomain");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Invoice_shopDomain_orderId_idx" ON "Invoice"("shopDomain", "orderId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Invoice_shopDomain_invoiceNumber_idx" ON "Invoice"("shopDomain", "invoiceNumber");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "InvoiceCounter_shopDomain_key" ON "InvoiceCounter"("shopDomain");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EmailLog_shopDomain_invoiceId_idx" ON "EmailLog"("shopDomain", "invoiceId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "LogoCache_shopDomain_key" ON "LogoCache"("shopDomain");
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "sqlite"
|
||||
@@ -32,3 +32,148 @@ model Session {
|
||||
refreshToken String?
|
||||
refreshTokenExpires DateTime?
|
||||
}
|
||||
|
||||
// Per-shop issuer/configuration data. One row per installed shop.
|
||||
model ShopSettings {
|
||||
id String @id @default(cuid())
|
||||
shopDomain String @unique
|
||||
|
||||
// Issuer / company data
|
||||
companyName String @default("")
|
||||
legalForm String @default("")
|
||||
ownerName String @default("")
|
||||
addressLine1 String @default("")
|
||||
addressLine2 String @default("")
|
||||
postalCode String @default("")
|
||||
city String @default("")
|
||||
countryCode String @default("AT")
|
||||
phone String @default("")
|
||||
email String @default("")
|
||||
website String @default("")
|
||||
|
||||
// Legal identifiers (Austria)
|
||||
vatId String @default("") // UID, e.g. ATU12345678
|
||||
taxNumber String @default("") // Steuernummer
|
||||
registrationNo String @default("") // FN (Firmenbuchnummer)
|
||||
registrationCourt String @default("") // Firmenbuchgericht
|
||||
|
||||
// Bank
|
||||
bankName String @default("")
|
||||
iban String @default("")
|
||||
bic String @default("")
|
||||
giroCodeEnabled Boolean @default(true)
|
||||
|
||||
// Invoice numbering
|
||||
// shopify_order_number | prefix_sequential
|
||||
numberingMode String @default("shopify_order_number")
|
||||
invoicePrefix String @default("RE-")
|
||||
// Used only for prefix_sequential (the next number to issue minus 1)
|
||||
invoiceSeed Int @default(1000)
|
||||
|
||||
// Defaults
|
||||
defaultLanguage String @default("de")
|
||||
paymentTermDays Int @default(14)
|
||||
footerNote String @default("")
|
||||
// Kleinunternehmer (§ 6 Abs. 1 Z 27 UStG)
|
||||
kleinunternehmer Boolean @default(false)
|
||||
|
||||
// Logo (URL on Shopify Files or any reachable URL)
|
||||
logoUrl String @default("")
|
||||
|
||||
// SMTP for email (used in later phase)
|
||||
smtpHost String @default("")
|
||||
smtpPort Int @default(587)
|
||||
smtpSecure Boolean @default(false)
|
||||
smtpUser String @default("")
|
||||
smtpPassword String @default("")
|
||||
smtpFromName String @default("")
|
||||
smtpFromEmail String @default("")
|
||||
smtpReplyTo String @default("")
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
invoices Invoice[]
|
||||
}
|
||||
|
||||
// Generated invoice record. One row per invoice document (versions and stornos
|
||||
// each create new rows; the latest is linked on the order via metafield).
|
||||
model Invoice {
|
||||
id String @id @default(cuid())
|
||||
shopDomain String
|
||||
settings ShopSettings @relation(fields: [shopDomain], references: [shopDomain])
|
||||
|
||||
// Shopify order references
|
||||
orderId String // gid://shopify/Order/...
|
||||
orderName String // e.g. "#1004"
|
||||
orderNumber Int // numeric order_number
|
||||
|
||||
// Invoice identity
|
||||
invoiceNumber String // e.g. "RE-1004"
|
||||
language String @default("de")
|
||||
// invoice | storno
|
||||
kind String @default("invoice")
|
||||
// Increments per regeneration of the same invoiceNumber (always 1 for storno)
|
||||
version Int @default(1)
|
||||
|
||||
// For storno rows: points to the cancelled Invoice.id
|
||||
cancelsInvoiceId String?
|
||||
|
||||
// PDF storage
|
||||
pdfFileGid String @default("") // gid://shopify/GenericFile/...
|
||||
pdfUrl String @default("")
|
||||
|
||||
// Snapshots (JSON strings on sqlite)
|
||||
totalsJson String @default("{}")
|
||||
customerJson String @default("{}")
|
||||
|
||||
// Lifecycle
|
||||
issuedAt DateTime @default(now())
|
||||
sentAt DateTime?
|
||||
cancelledAt DateTime?
|
||||
|
||||
status String @default("issued") // issued | sent | cancelled | failed
|
||||
lastError String @default("")
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([shopDomain, orderId])
|
||||
@@index([shopDomain, invoiceNumber])
|
||||
}
|
||||
|
||||
// Per-shop atomic counter for prefix_sequential numbering mode.
|
||||
model InvoiceCounter {
|
||||
id String @id @default(cuid())
|
||||
shopDomain String @unique
|
||||
// Last issued numeric value; allocate new = lastValue + 1 atomically.
|
||||
lastValue Int @default(0)
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// Email delivery log (used by later Flow send action; declared now so the
|
||||
// generator can record manual sends as well).
|
||||
model EmailLog {
|
||||
id String @id @default(cuid())
|
||||
shopDomain String
|
||||
invoiceId String
|
||||
toAddress String
|
||||
subject String
|
||||
status String // queued | sent | failed
|
||||
error String @default("")
|
||||
sentAt DateTime @default(now())
|
||||
|
||||
@@index([shopDomain, invoiceId])
|
||||
}
|
||||
|
||||
// Per-shop logo bytes cache. Avoids fetching the logo from Shopify Files on
|
||||
// every PDF render.
|
||||
model LogoCache {
|
||||
id String @id @default(cuid())
|
||||
shopDomain String @unique
|
||||
sourceUrl String
|
||||
bytes Bytes
|
||||
contentType String @default("image/png")
|
||||
etag String @default("")
|
||||
fetchedAt DateTime @default(now())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user