import { pgTable, text, timestamp, integer, boolean, pgEnum, uuid } from "drizzle-orm/pg-core"; export const roleEnum = pgEnum("role", ["viewer", "initiator", "approver", "admin"]); export const organizations = pgTable("organizations", { id: uuid("id").defaultRandom().primaryKey(), name: text("name").notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const users = pgTable("users", { id: uuid("id").defaultRandom().primaryKey(), address: text("address").notNull().unique(), createdAt: timestamp("created_at").defaultNow().notNull(), }); export const memberships = pgTable("memberships", { id: uuid("id").defaultRandom().primaryKey(), organizationId: uuid("organization_id") .references(() => organizations.id, { onDelete: "cascade" }) .notNull(), userId: uuid("user_id") .references(() => users.id, { onDelete: "cascade" }) .notNull(), role: roleEnum("role").notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), }); export const treasuries = pgTable("treasuries", { id: uuid("id").defaultRandom().primaryKey(), organizationId: uuid("organization_id") .references(() => organizations.id, { onDelete: "cascade" }) .notNull(), chainId: integer("chain_id").notNull(), mainWallet: text("main_wallet").notNull().unique(), label: text("label"), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at").defaultNow().notNull(), }); export const subAccounts = pgTable("sub_accounts", { id: uuid("id").defaultRandom().primaryKey(), treasuryId: uuid("treasury_id") .references(() => treasuries.id, { onDelete: "cascade" }) .notNull(), address: text("address").notNull().unique(), label: text("label"), metadataHash: text("metadata_hash"), createdAt: timestamp("created_at").defaultNow().notNull(), }); export const transactionProposals = pgTable("transaction_proposals", { id: uuid("id").defaultRandom().primaryKey(), treasuryId: uuid("treasury_id") .references(() => treasuries.id, { onDelete: "cascade" }) .notNull(), proposalId: integer("proposal_id").notNull(), walletAddress: text("wallet_address").notNull(), to: text("to").notNull(), value: text("value").notNull(), // Store as string to handle bigint token: text("token"), // null for native token data: text("data"), status: text("status").notNull().default("pending"), // pending, executed, rejected proposer: text("proposer").notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), executedAt: timestamp("executed_at"), }); export const approvals = pgTable("approvals", { id: uuid("id").defaultRandom().primaryKey(), proposalId: uuid("proposal_id") .references(() => transactionProposals.id, { onDelete: "cascade" }) .notNull(), signer: text("signer").notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), }); export const auditLogs = pgTable("audit_logs", { id: uuid("id").defaultRandom().primaryKey(), organizationId: uuid("organization_id") .references(() => organizations.id, { onDelete: "cascade" }) .notNull(), treasuryId: uuid("treasury_id").references(() => treasuries.id, { onDelete: "set null" }), action: text("action").notNull(), // owner_added, owner_removed, threshold_changed, etc. actor: text("actor").notNull(), details: text("details"), // JSON string for additional details createdAt: timestamp("created_at").defaultNow().notNull(), });