import { pgTable, text, boolean, integer, timestamp, primaryKey, index } from 'drizzle-orm/pg-core'; import { ports } from './ports'; import { clients } from './clients'; // Pipeline stages: open, details_sent, in_communication, visited, signed_eoi_nda, deposit_10pct, contract, completed export const interests = pgTable( 'interests', { id: text('id') .primaryKey() .$defaultFn(() => crypto.randomUUID()), portId: text('port_id') .notNull() .references(() => ports.id), clientId: text('client_id') .notNull() .references(() => clients.id), berthId: text('berth_id'), // nullable — FK to berths defined in berths.ts, added via relation yachtId: text('yacht_id'), // FK added via relation; nullable until pipeline leaves 'open' pipelineStage: text('pipeline_stage').notNull().default('open'), leadCategory: text('lead_category'), // general_interest, specific_qualified, hot_lead source: text('source'), // website, manual, referral, broker eoiStatus: text('eoi_status'), // null, waiting_for_signatures, signed, expired documensoId: text('documenso_id'), contractStatus: text('contract_status'), depositStatus: text('deposit_status'), reservationStatus: text('reservation_status'), dateFirstContact: timestamp('date_first_contact', { withTimezone: true }), dateLastContact: timestamp('date_last_contact', { withTimezone: true }), dateEoiSent: timestamp('date_eoi_sent', { withTimezone: true }), dateEoiSigned: timestamp('date_eoi_signed', { withTimezone: true }), dateContractSent: timestamp('date_contract_sent', { withTimezone: true }), dateContractSigned: timestamp('date_contract_signed', { withTimezone: true }), dateDepositReceived: timestamp('date_deposit_received', { withTimezone: true }), reminderEnabled: boolean('reminder_enabled').notNull().default(false), reminderDays: integer('reminder_days'), reminderLastFired: timestamp('reminder_last_fired', { withTimezone: true }), notes: text('notes'), archivedAt: timestamp('archived_at', { withTimezone: true }), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index('idx_interests_port').on(table.portId), index('idx_interests_client').on(table.clientId), index('idx_interests_berth').on(table.berthId), index('idx_interests_yacht').on(table.yachtId), index('idx_interests_stage').on(table.portId, table.pipelineStage), index('idx_interests_archived').on(table.portId, table.archivedAt), ], ); export const interestNotes = pgTable( 'interest_notes', { id: text('id') .primaryKey() .$defaultFn(() => crypto.randomUUID()), interestId: text('interest_id') .notNull() .references(() => interests.id, { onDelete: 'cascade' }), authorId: text('author_id').notNull(), // user ID content: text('content').notNull(), mentions: text('mentions').array(), // array of mentioned user IDs isLocked: boolean('is_locked').notNull().default(false), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(), }, (table) => [index('idx_in_interest').on(table.interestId)], ); export const interestTags = pgTable( 'interest_tags', { interestId: text('interest_id') .notNull() .references(() => interests.id, { onDelete: 'cascade' }), tagId: text('tag_id').notNull(), // references tags.id }, (table) => [primaryKey({ columns: [table.interestId, table.tagId] })], ); export type Interest = typeof interests.$inferSelect; export type NewInterest = typeof interests.$inferInsert; export type InterestNote = typeof interestNotes.$inferSelect; export type NewInterestNote = typeof interestNotes.$inferInsert;