feat(01-02): [BLOCKING] drizzle-kit push — schema live on Postgres
- Connected to postgresql://178.104.27.55:5432/clienthub - 10 tables created: clients, phases, tasks, deliverables, comments, payments, documents, notes, service_catalog, quote_items - UNIQUE constraint on clients.token active at DB level - All FK constraints and CASCADE rules applied - Verified via information_schema.tables query
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { relations } from "drizzle-orm/relations";
|
||||
import { clients, notes, payments, phases, quoteItems, serviceCatalog, documents, tasks, deliverables } from "./schema";
|
||||
|
||||
export const notesRelations = relations(notes, ({one}) => ({
|
||||
client: one(clients, {
|
||||
fields: [notes.clientId],
|
||||
references: [clients.id]
|
||||
}),
|
||||
}));
|
||||
|
||||
export const clientsRelations = relations(clients, ({many}) => ({
|
||||
notes: many(notes),
|
||||
payments: many(payments),
|
||||
phases: many(phases),
|
||||
quoteItems: many(quoteItems),
|
||||
documents: many(documents),
|
||||
}));
|
||||
|
||||
export const paymentsRelations = relations(payments, ({one}) => ({
|
||||
client: one(clients, {
|
||||
fields: [payments.clientId],
|
||||
references: [clients.id]
|
||||
}),
|
||||
}));
|
||||
|
||||
export const phasesRelations = relations(phases, ({one, many}) => ({
|
||||
client: one(clients, {
|
||||
fields: [phases.clientId],
|
||||
references: [clients.id]
|
||||
}),
|
||||
tasks: many(tasks),
|
||||
}));
|
||||
|
||||
export const quoteItemsRelations = relations(quoteItems, ({one}) => ({
|
||||
client: one(clients, {
|
||||
fields: [quoteItems.clientId],
|
||||
references: [clients.id]
|
||||
}),
|
||||
serviceCatalog: one(serviceCatalog, {
|
||||
fields: [quoteItems.serviceId],
|
||||
references: [serviceCatalog.id]
|
||||
}),
|
||||
}));
|
||||
|
||||
export const serviceCatalogRelations = relations(serviceCatalog, ({many}) => ({
|
||||
quoteItems: many(quoteItems),
|
||||
}));
|
||||
|
||||
export const documentsRelations = relations(documents, ({one}) => ({
|
||||
client: one(clients, {
|
||||
fields: [documents.clientId],
|
||||
references: [clients.id]
|
||||
}),
|
||||
}));
|
||||
|
||||
export const tasksRelations = relations(tasks, ({one, many}) => ({
|
||||
phase: one(phases, {
|
||||
fields: [tasks.phaseId],
|
||||
references: [phases.id]
|
||||
}),
|
||||
deliverables: many(deliverables),
|
||||
}));
|
||||
|
||||
export const deliverablesRelations = relations(deliverables, ({one}) => ({
|
||||
task: one(tasks, {
|
||||
fields: [deliverables.taskId],
|
||||
references: [tasks.id]
|
||||
}),
|
||||
}));
|
||||
@@ -0,0 +1,139 @@
|
||||
import { pgTable, foreignKey, text, timestamp, unique, numeric, integer, boolean } from "drizzle-orm/pg-core"
|
||||
import { sql } from "drizzle-orm"
|
||||
|
||||
|
||||
|
||||
export const notes = pgTable("notes", {
|
||||
id: text().primaryKey().notNull(),
|
||||
clientId: text("client_id").notNull(),
|
||||
body: text().notNull(),
|
||||
createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
|
||||
}, (table) => [
|
||||
foreignKey({
|
||||
columns: [table.clientId],
|
||||
foreignColumns: [clients.id],
|
||||
name: "notes_client_id_clients_id_fk"
|
||||
}).onDelete("cascade"),
|
||||
]);
|
||||
|
||||
export const comments = pgTable("comments", {
|
||||
id: text().primaryKey().notNull(),
|
||||
entityType: text("entity_type").notNull(),
|
||||
entityId: text("entity_id").notNull(),
|
||||
author: text().notNull(),
|
||||
body: text().notNull(),
|
||||
createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const clients = pgTable("clients", {
|
||||
id: text().primaryKey().notNull(),
|
||||
name: text().notNull(),
|
||||
brandName: text("brand_name").notNull(),
|
||||
brief: text().notNull(),
|
||||
token: text().notNull(),
|
||||
acceptedTotal: numeric("accepted_total", { precision: 10, scale: 2 }).default('0'),
|
||||
createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
|
||||
}, (table) => [
|
||||
unique("clients_token_unique").on(table.token),
|
||||
]);
|
||||
|
||||
export const payments = pgTable("payments", {
|
||||
id: text().primaryKey().notNull(),
|
||||
clientId: text("client_id").notNull(),
|
||||
label: text().notNull(),
|
||||
amount: numeric({ precision: 10, scale: 2 }).notNull(),
|
||||
status: text().default('da_saldare').notNull(),
|
||||
paidAt: timestamp("paid_at", { withTimezone: true, mode: 'string' }),
|
||||
}, (table) => [
|
||||
foreignKey({
|
||||
columns: [table.clientId],
|
||||
foreignColumns: [clients.id],
|
||||
name: "payments_client_id_clients_id_fk"
|
||||
}).onDelete("cascade"),
|
||||
]);
|
||||
|
||||
export const phases = pgTable("phases", {
|
||||
id: text().primaryKey().notNull(),
|
||||
clientId: text("client_id").notNull(),
|
||||
title: text().notNull(),
|
||||
sortOrder: integer("sort_order").default(0).notNull(),
|
||||
status: text().default('upcoming').notNull(),
|
||||
}, (table) => [
|
||||
foreignKey({
|
||||
columns: [table.clientId],
|
||||
foreignColumns: [clients.id],
|
||||
name: "phases_client_id_clients_id_fk"
|
||||
}).onDelete("cascade"),
|
||||
]);
|
||||
|
||||
export const quoteItems = pgTable("quote_items", {
|
||||
id: text().primaryKey().notNull(),
|
||||
clientId: text("client_id").notNull(),
|
||||
serviceId: text("service_id").notNull(),
|
||||
quantity: numeric({ precision: 10, scale: 2 }).notNull(),
|
||||
unitPrice: numeric("unit_price", { precision: 10, scale: 2 }).notNull(),
|
||||
subtotal: numeric({ precision: 10, scale: 2 }).notNull(),
|
||||
}, (table) => [
|
||||
foreignKey({
|
||||
columns: [table.clientId],
|
||||
foreignColumns: [clients.id],
|
||||
name: "quote_items_client_id_clients_id_fk"
|
||||
}).onDelete("cascade"),
|
||||
foreignKey({
|
||||
columns: [table.serviceId],
|
||||
foreignColumns: [serviceCatalog.id],
|
||||
name: "quote_items_service_id_service_catalog_id_fk"
|
||||
}).onDelete("restrict"),
|
||||
]);
|
||||
|
||||
export const serviceCatalog = pgTable("service_catalog", {
|
||||
id: text().primaryKey().notNull(),
|
||||
name: text().notNull(),
|
||||
description: text(),
|
||||
unitPrice: numeric("unit_price", { precision: 10, scale: 2 }).notNull(),
|
||||
active: boolean().default(true).notNull(),
|
||||
});
|
||||
|
||||
export const documents = pgTable("documents", {
|
||||
id: text().primaryKey().notNull(),
|
||||
clientId: text("client_id").notNull(),
|
||||
label: text().notNull(),
|
||||
url: text().notNull(),
|
||||
createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
|
||||
}, (table) => [
|
||||
foreignKey({
|
||||
columns: [table.clientId],
|
||||
foreignColumns: [clients.id],
|
||||
name: "documents_client_id_clients_id_fk"
|
||||
}).onDelete("cascade"),
|
||||
]);
|
||||
|
||||
export const tasks = pgTable("tasks", {
|
||||
id: text().primaryKey().notNull(),
|
||||
phaseId: text("phase_id").notNull(),
|
||||
title: text().notNull(),
|
||||
description: text(),
|
||||
status: text().default('todo').notNull(),
|
||||
sortOrder: integer("sort_order").default(0).notNull(),
|
||||
}, (table) => [
|
||||
foreignKey({
|
||||
columns: [table.phaseId],
|
||||
foreignColumns: [phases.id],
|
||||
name: "tasks_phase_id_phases_id_fk"
|
||||
}).onDelete("cascade"),
|
||||
]);
|
||||
|
||||
export const deliverables = pgTable("deliverables", {
|
||||
id: text().primaryKey().notNull(),
|
||||
taskId: text("task_id").notNull(),
|
||||
title: text().notNull(),
|
||||
url: text(),
|
||||
status: text().default('pending').notNull(),
|
||||
approvedAt: timestamp("approved_at", { withTimezone: true, mode: 'string' }),
|
||||
}, (table) => [
|
||||
foreignKey({
|
||||
columns: [table.taskId],
|
||||
foreignColumns: [tasks.id],
|
||||
name: "deliverables_task_id_tasks_id_fk"
|
||||
}).onDelete("cascade"),
|
||||
]);
|
||||
Reference in New Issue
Block a user