mirror of
https://github.com/soconnor0919/beenvoice.git
synced 2026-02-05 08:16:31 -05:00
Add Turso/Vercel deployment configuration
- Updated database connection to support Turso auth token - Added vercel.json with bun build configuration - Updated environment schema for production deployment - Added new features and components for production readiness
This commit is contained in:
@@ -13,7 +13,11 @@ const globalForDb = globalThis as unknown as {
|
||||
};
|
||||
|
||||
export const client =
|
||||
globalForDb.client ?? createClient({ url: env.DATABASE_URL });
|
||||
globalForDb.client ??
|
||||
createClient({
|
||||
url: env.DATABASE_URL,
|
||||
authToken: env.DATABASE_AUTH_TOKEN,
|
||||
});
|
||||
if (env.NODE_ENV !== "production") globalForDb.client = client;
|
||||
|
||||
export const db = drizzle(client, { schema });
|
||||
|
||||
@@ -27,6 +27,7 @@ export const users = createTable("user", (d) => ({
|
||||
export const usersRelations = relations(users, ({ many }) => ({
|
||||
accounts: many(accounts),
|
||||
clients: many(clients),
|
||||
businesses: many(businesses),
|
||||
invoices: many(invoices),
|
||||
}));
|
||||
|
||||
@@ -127,6 +128,50 @@ export const clientsRelations = relations(clients, ({ one, many }) => ({
|
||||
invoices: many(invoices),
|
||||
}));
|
||||
|
||||
export const businesses = createTable(
|
||||
"business",
|
||||
(d) => ({
|
||||
id: d
|
||||
.text({ length: 255 })
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => crypto.randomUUID()),
|
||||
name: d.text({ length: 255 }).notNull(),
|
||||
email: d.text({ length: 255 }),
|
||||
phone: d.text({ length: 50 }),
|
||||
addressLine1: d.text({ length: 255 }),
|
||||
addressLine2: d.text({ length: 255 }),
|
||||
city: d.text({ length: 100 }),
|
||||
state: d.text({ length: 50 }),
|
||||
postalCode: d.text({ length: 20 }),
|
||||
country: d.text({ length: 100 }),
|
||||
website: d.text({ length: 255 }),
|
||||
taxId: d.text({ length: 100 }),
|
||||
logoUrl: d.text({ length: 500 }),
|
||||
isDefault: d.integer({ mode: "boolean" }).default(false),
|
||||
createdById: d
|
||||
.text({ length: 255 })
|
||||
.notNull()
|
||||
.references(() => users.id),
|
||||
createdAt: d
|
||||
.integer({ mode: "timestamp" })
|
||||
.default(sql`(unixepoch())`)
|
||||
.notNull(),
|
||||
updatedAt: d.integer({ mode: "timestamp" }).$onUpdate(() => new Date()),
|
||||
}),
|
||||
(t) => [
|
||||
index("business_created_by_idx").on(t.createdById),
|
||||
index("business_name_idx").on(t.name),
|
||||
index("business_email_idx").on(t.email),
|
||||
index("business_is_default_idx").on(t.isDefault),
|
||||
],
|
||||
);
|
||||
|
||||
export const businessesRelations = relations(businesses, ({ one, many }) => ({
|
||||
createdBy: one(users, { fields: [businesses.createdById], references: [users.id] }),
|
||||
invoices: many(invoices),
|
||||
}));
|
||||
|
||||
export const invoices = createTable(
|
||||
"invoice",
|
||||
(d) => ({
|
||||
@@ -136,6 +181,9 @@ export const invoices = createTable(
|
||||
.primaryKey()
|
||||
.$defaultFn(() => crypto.randomUUID()),
|
||||
invoiceNumber: d.text({ length: 100 }).notNull(),
|
||||
businessId: d
|
||||
.text({ length: 255 })
|
||||
.references(() => businesses.id),
|
||||
clientId: d
|
||||
.text({ length: 255 })
|
||||
.notNull()
|
||||
@@ -144,6 +192,7 @@ export const invoices = createTable(
|
||||
dueDate: d.integer({ mode: "timestamp" }).notNull(),
|
||||
status: d.text({ length: 50 }).notNull().default("draft"), // draft, sent, paid, overdue
|
||||
totalAmount: d.real().notNull().default(0),
|
||||
taxRate: d.real().notNull().default(0.00),
|
||||
notes: d.text({ length: 1000 }),
|
||||
createdById: d
|
||||
.text({ length: 255 })
|
||||
@@ -156,6 +205,7 @@ export const invoices = createTable(
|
||||
updatedAt: d.integer({ mode: "timestamp" }).$onUpdate(() => new Date()),
|
||||
}),
|
||||
(t) => [
|
||||
index("invoice_business_id_idx").on(t.businessId),
|
||||
index("invoice_client_id_idx").on(t.clientId),
|
||||
index("invoice_created_by_idx").on(t.createdById),
|
||||
index("invoice_number_idx").on(t.invoiceNumber),
|
||||
@@ -164,6 +214,7 @@ export const invoices = createTable(
|
||||
);
|
||||
|
||||
export const invoicesRelations = relations(invoices, ({ one, many }) => ({
|
||||
business: one(businesses, { fields: [invoices.businessId], references: [businesses.id] }),
|
||||
client: one(clients, { fields: [invoices.clientId], references: [clients.id] }),
|
||||
createdBy: one(users, { fields: [invoices.createdById], references: [users.id] }),
|
||||
items: many(invoiceItems),
|
||||
@@ -186,6 +237,7 @@ export const invoiceItems = createTable(
|
||||
hours: d.real().notNull(),
|
||||
rate: d.real().notNull(),
|
||||
amount: d.real().notNull(),
|
||||
position: d.integer().notNull().default(0), // NEW: position for ordering
|
||||
createdAt: d
|
||||
.integer({ mode: "timestamp" })
|
||||
.default(sql`(unixepoch())`)
|
||||
@@ -194,6 +246,7 @@ export const invoiceItems = createTable(
|
||||
(t) => [
|
||||
index("invoice_item_invoice_id_idx").on(t.invoiceId),
|
||||
index("invoice_item_date_idx").on(t.date),
|
||||
index("invoice_item_position_idx").on(t.position), // NEW: index for position
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user