Open FranCanias opened 5 months ago
Also faced with it
> drizzle-kit push
drizzle-kit: v0.21.4
drizzle-orm: v0.30.10
No config path provided, using default path
Reading config file '/my-app-path/drizzle.config.ts'
Using 'pg' driver for database querying
[✓] Pulling schema from database...TypeError: Cannot use 'in' operator to search for 'default' in undefined
at /my-app-path/node_modules/drizzle-kit/bin.cjs:18362:23
at Array.map (<anonymous>)
at alternationsInColumn (/my-app-path/node_modules/drizzle-kit/bin.cjs:18361:10)
at /my-app-path/node_modules/drizzle-kit/bin.cjs:18321:49
at Array.map (<anonymous>)
at findAlternationsInTable (/my-app-path/node_modules/drizzle-kit/bin.cjs:18321:37)
at /my-app-path/node_modules/drizzle-kit/bin.cjs:18203:14
at Array.map (<anonymous>)
at applyJsonDiff (/my-app-path/node_modules/drizzle-kit/bin.cjs:18201:69)
at applyPgSnapshotsDiff (/my-app-path/node_modules/drizzle-kit/bin.cjs:19822:26)
please provide database/typescript drizzle schema
The schema its kinda big, i leave it here
import { mysqlTableCreator, primaryKey, unique, varchar, int, text, json, tinyint, datetime, date, time, serial, timestamp, float, boolean, double, MySqlEnumColumn, mysqlEnum, bigint, MySqlTextBuilder } from 'drizzle-orm/mysql-core'
import { relations, sql, type InferSelectModel, type SQL } from 'drizzle-orm'
import { customType } from 'drizzle-orm/mysql-core'
import { z } from 'zod'
import { createInsertSchema, createSelectSchema } from 'drizzle-zod';
// #region TYPES
const ECMysqlTable = mysqlTableCreator((name) => `EC_${name}`)
const mysqlTable = mysqlTableCreator((name) => `PANEL_${name}`)
// #region EASYCHARTER
// #region CustomDrivers
type SQLValues = { coordinates: number[] }
type SQLValuesArray = { coordinates: number[][] }
type SQLPolygon = [number, number][][]
const point = <TData extends { lat: number; lng: number }>(name: string) =>
customType<{ data: TData; driverData: SQLValues }>({
dataType() {
return 'point'
},
toDriver(value: TData): SQL {
return sql`ST_GeomFromText('POINT(${value.lat} ${value.lng})',4326)`
},
fromDriver(value: SQLValues): TData {
const points = value.coordinates
return { lat: points?.[1] ?? 0, lng: points?.[0] ?? 0 } as TData
},
})(name)
const lineString = <TData extends { lat: number; lng: number }[]>(name: string) =>
customType<{ data: TData; driverData: SQLValuesArray }>({
dataType() {
return 'linestring'
},
toDriver(value: TData): SQL {
const data = 'LINESTRING(' + value.map((point) => point.lat + ' ' + point.lng).join() + ')'
return sql`ST_GeomFromText(${data},4326)`
},
fromDriver(value: SQLValuesArray): TData {
const linestring = value.coordinates
const latLng = linestring.map((point) => {
return { lat: point[1], lng: point[0] }
})
return latLng as TData
},
})(name)
export const polygon = <TData extends { lat: number; lng: number }[]>(name: string) =>
customType<{ data: TData; driverData: SQLPolygon }>({
dataType() {
return 'polygon'
},
toDriver(value: TData): SQL {
const data = 'POLYGON((' + value.map((point) => point.lat + ' ' + point.lng).join() + '))'
return sql`ST_GeomFromText(${data},4326)`
},
})(name)
// #endregion CustomDrivers
// #region Account
export const ecaccount = mysqlTable(
'Account',
{
id: varchar('id', { length: 191 })
.notNull()
.default(sql`(uuid())`),
userId: varchar('userId', { length: 191 }).notNull(),
type: varchar('type', { length: 191 }).notNull(),
provider: varchar('provider', { length: 191 }).notNull(),
providerAccountId: varchar('providerAccountId', { length: 191 }).notNull(),
refreshToken: varchar('refresh_token', { length: 191 }),
accessToken: varchar('access_token', { length: 191 }),
expiresAt: int('expires_at'),
tokenType: varchar('token_type', { length: 191 }),
scope: varchar('scope', { length: 191 }),
idToken: varchar('id_token', { length: 191 }),
sessionState: varchar('session_state', { length: 191 }),
},
(table) => {
return {
accountId: primaryKey({columns: [table.id], name: 'PANEL_Account_id'}),
accountProviderProviderAccountIdKey: unique('Account_provider_providerAccountId_key').on(table.provider, table.providerAccountId),
}
}
)
// #endregion Account
// #region Boat
// #region BoatTypes
export enum EQUIPMENT_CATEGORY {
EXTERIOR = 'Exterior',
COMFORT = 'Comfort',
NAVIGATION = 'Navegacion',
COOKING = 'Cocina',
RECREATIVE = 'Ocio',
}
// #endregion BoatTypes
export const boat = mysqlTable(
'Boat',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').notNull(),
status: tinyint('status').$type<0 | 1 | 2>().default(0).notNull(),
photos: json('photos').$type<string[]>(),
bail: int('bail').default(0),
contractId: int('contractId'),
description: text('description'),
length: text('length'),
lengthCopy: float('lengthCopy'),
width: text('width'),
capacity: int('capacity'),
cabins: int('cabins'),
weight: int('weight'),
maxWeight: int('maxWeight'),
licence: text('licence'),
flag: text('flag'),
motors: int('motors'),
motorType: text('motorType'),
motorMaker: text('motorMaker'),
motorPower: int('motorPower'),
maxSpeed: int('maxSpeed'),
cruiseSpeed: int('cruiseSpeed'),
placeId: text('placeId'),
placesId: int('placesId'),
position: point('position').$type<{ lat: number; lng: number }>(),
positionObj: json('positionObj').$type<{lat: number, lng: number}>(),
type: text('type').$type<'Sin Definir' | 'Lancha' | 'Llaut' | 'Neumatico' | 'Velero' | 'Catamaran' | 'Semirigida' | 'Yate'>().default('Sin Definir'),
insuranceDoc: text('insuranceDoc'),
insuranceProvider: text('insuranceProvider'),
insuranceStart: date('insuranceStart'),
insuranceEnd: date('insuranceEnd'),
prepTime: int('prepTime'),
details: json('details').$type<{
place?: string
maker?: string
model?: string
year?: string
registration?: string
renovation?: string
fuel?: string
engine?: number
rooms?: number
beds?: number
}>(),
includesCaptain: boolean('includesCaptain').default(false),
seasons: json('seasons').$type<
{
id: number
status: number
rates: {
duration: number
price: number
captain?: number
}[]
}[]
>(),
verifications: json('verifications').$type<
{
name: string
image?: string
description: string
price: number
when: 'checkin' | 'checkout' | 'both'
}[]
>(),
gpsOptions: json('gpsOptions'),
extras: json('extras').$type<number[]>(),
services: json('services').$type<{ id: number; variant: number }[]>(),
equipment: json('equipment').$type<string[]>(),
groupId: int('groupId'),
companyId: text('companyId').notNull(),
createdAt: timestamp('createdAt').default(sql`now()`),
fees: json('fees').$type<{ halfday: number; fullday: number; sunset: number }>(),
increment: json('increment').$type<{ halfday: number; fullday: number; sunset: number }>(),
},
(table) => {
return {
boatId: primaryKey({ columns: [table.id], name: 'PANEL_Boat_id'}),
}
}
)
export const boatConfig = relations(boat, ({ one, many }) => ({
reserves: many(reserve),
positions: many(position),
finances: many(finance),
group: one(boat, { fields: [boat.groupId], references: [boat.id], relationName: 'group' }),
child: many(boat, { relationName: 'group' }),
company: one(company, { fields: [boat.companyId], references: [company.id] }),
documents: many(document),
contract: one(contract, { fields: [boat.contractId], references: [contract.id] }),
tasks: many(task),
shopItems: many(shopItem),
discounts: many(discountToBoat),
place: one(place, { fields: [boat.placesId], references: [place.id] }),
}))
export const insetBoatSchema = createInsertSchema(boat, {
type: z.literal('Sin Definir').or(z.literal('Lancha')).or(z.literal('Llaut')).or(z.literal('Neumatico')).or(z.literal('Velero')).or(z.literal('Catamaran')).or(z.literal('Yate')).or(z.literal('Semirigida')).optional(),
status: z.literal(0).or(z.literal(1)).or(z.literal(2)).optional(),
photos: z.array(z.string()).optional(),
positionObj: z.object({ lat: z.number(), lng: z.number() }).optional(),
details: z
.object({
place: z.string().optional(),
maker: z.string().optional(),
model: z.string().optional(),
year: z.string().optional(),
registration: z.string().optional(),
renovation: z.string().optional(),
fuel: z.string().optional(),
engine: z.number().optional(),
rooms: z.number().optional(),
beds: z.number().optional(),
})
.optional(),
seasons: z
.array(
z.object({
id: z.number(),
status: z.number(),
rates: z.array(
z.object({
duration: z.number(),
price: z.number(),
})
),
})
)
.optional(),
extras: z.array(z.number()).optional(),
services: z.array(z.object({ id: z.number(), variant: z.number() })).optional(),
verifications: z
.array(
z.object({
name: z.string(),
price: z.number(),
description: z.string(),
image: z.string().optional(),
when: z.literal('checkin').or(z.literal('checkout')).or(z.literal('both')),
})
)
.optional(),
equipment: z.array(z.string()).optional(),
fees: z.object({ halfday: z.number(), fullday: z.number(), sunset: z.number() }).optional(),
increment: z.object({ halfday: z.number(), fullday: z.number(), sunset: z.number() }).optional(),
})
export type Boat = InferSelectModel<typeof boat>
export type GpsBoat = InferSelectModel<typeof boat> & {
positions: InferSelectModel<typeof position>[]
reserves: GpsReserve[]
}
// #endregion Boat
// #region PartnerBoat
export const partnerBoat = mysqlTable(
'PartnerBoat',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').notNull(),
photo: text('photo'),
description: text('description'),
length: text('length'),
capacity: int('capacity'),
licence: text('licence'),
type: text('type').$type<'Sin Definir' | 'Lancha' | 'Llaut' | 'Neumatico' | 'Velero' | 'Catamaran' | 'Semirigida' | 'Yate'>().default('Sin Definir'),
maker: text('maker'),
model: text('model'),
engine: int('engine'),
prices: json('prices').$type<{ halfday: number; fullday: number }>(),
partnerId: text('partnerId').notNull(),
createdAt: timestamp('createdAt').default(sql`now()`),
},
(table) => {
return {
partnerBoatId: primaryKey({columns: [table.id], name: 'PANEL_PartnerBoat_id'}),
}
}
)
export const partnerBoatConfig = relations(partnerBoat, ({ one }) => ({
partner: one(partner, { fields: [partnerBoat.partnerId], references: [partner.id] }),
}))
export const updatePartnerBoatSchema = createSelectSchema(partnerBoat, {
id: z.number(),
name: z.string().optional(),
type: z.literal('Sin Definir').or(z.literal('Lancha')).or(z.literal('Llaut')).or(z.literal('Neumatico')).or(z.literal('Velero')).or(z.literal('Catamaran')).or(z.literal('Semirigida')).or(z.literal('Yate')).optional(),
prices: z.object({ halfday: z.number(), fullday: z.number() }).optional(),
})
// #endregion PartnerBoat
// #region Company
export const company = mysqlTable(
'Company',
{
id: varchar('id', { length: 191 })
.notNull()
.unique()
.default(sql`(uuid())`),
name: text('name'),
legalName: text('legalName'),
docType: text('docType'),
document: text('document'),
address: text('address'),
addressId: text('addressId'),
zip: text('zip'),
phone: text('phone'),
email: text('email'),
managerName: text('managerName'),
managerPhone: text('managerPhone'),
managerEmail: text('managerEmail'),
website: text('website'),
logo: text('logo'),
timezone: text('timezone'),
settings: json('settings').$type<{ prepTime: number }>().default({ prepTime: 0 }),
priority: int('priority').default(0),
active: boolean('active').default(true),
},
(table) => {
return {
companyId: primaryKey({columns: [table.id], name: 'PANEL_Extra_idCompany_id'}),
}
}
)
export const companyConfig = relations(company, ({ many }) => ({
reserves: many(reserve),
boats: many(boat),
finances: many(finance),
partners: many(partner),
seasons: many(season),
extras: many(extra),
services: many(service),
clients: many(client),
resellers: many(reseller),
methods: many(method),
employees: many(ecuser),
financeCategories: many(financeCategory),
departments: many(department),
origins: many(origin),
discounts: many(discount),
contracts: many(contract),
}))
export type Company = InferSelectModel<typeof company> & {
seasons: InferSelectModel<typeof season>[]
finances: InferSelectModel<typeof finance>[]
resellers: InferSelectModel<typeof reseller>[]
employees: InferSelectModel<typeof ecuser>[]
}
// #endregion Company
// #region Extra
export const extra = mysqlTable(
'Extra',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').default('').notNull(),
description: text('description'),
photo: text('photo'),
status: int('status').$type<0 | 1>().default(0).notNull(),
type: text('type').$type<'permanent' | 'consumable'>().default('permanent').notNull(),
variants: json('variants')
.$type<
(
| {
id: number
type: 'array'
name: string
stock: number
prices: { duration: number; price: number }[]
}
| {
id: number
type: 'simple'
name: string
stock: number
price: number
}
)[]
>()
.notNull()
.default([]),
companyId: text('companyId').notNull(),
},
(table) => {
return {
extrasId: primaryKey({columns: [table.id], name: 'PANEL_Extra_id'}),
}
}
)
export const extrasConfig = relations(extra, ({ one }) => ({
company: one(company, { fields: [extra.companyId], references: [company.id] }),
}))
export type Extra = InferSelectModel<typeof extra>
// #endregion Extra
// #region Document
export const document = mysqlTable(
'Document',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').notNull(),
boatId: int('boatId').notNull(),
name: text('name').default('').notNull(),
description: text('description'),
images: json('images').$type<string[]>().default([]),
},
(table) => {
return {
documentId: primaryKey({columns: [table.id], name: 'PANEL_Document_id'}),
}
}
)
export const documentConfig = relations(document, ({ one }) => ({
boat: one(boat, { fields: [document.boatId], references: [boat.id] }),
company: one(company, { fields: [document.companyId], references: [company.id] }),
}))
// #endregion Document
// #region Contract
type ContractBlock =
| {
id: number
type: 'paragraph' | 'heading'
content: string
}
| {
id: number
type: 'table'
content: {
headers: [string, string]
rows: [string, string][]
}
}
export const contract = mysqlTable(
'Contract',
{
id: int('id').notNull().unique().autoincrement(),
originalId: int('originalId'),
version: int('version').default(1).notNull(),
companyId: text('companyId').notNull(),
name: text('name').default('').notNull(),
es: json('es').$type<ContractBlock[]>(),
en: json('en').$type<ContractBlock[]>(),
fr: json('fr').$type<ContractBlock[]>(),
de: json('de').$type<ContractBlock[]>(),
it: json('it').$type<ContractBlock[]>(),
},
(table) => {
return {
contractId: primaryKey({columns: [table.id], name: 'PANEL_Contract_id'}),
}
}
)
export const contractConfig = relations(contract, ({ one, many }) => ({
company: one(company, { fields: [contract.companyId], references: [company.id] }),
original: one(contract, { fields: [contract.originalId], references: [contract.id], relationName: 'original' }),
child: many(contract, { relationName: 'original' }),
}))
export type Contract = InferSelectModel<typeof contract>
// #endregion Contract
// #region Finance
export const finance = mysqlTable(
'Finance',
{
id: int('id').notNull().unique().autoincrement(),
date: datetime('date', { fsp: 3 })
.notNull()
.default(sql`CURRENT_TIMESTAMP(3)`),
sign: int('sign').notNull(),
amount: double('amount').notNull(),
category: text('category'),
description: text('description'),
photo: text('photo'),
refundFrom: int('refundFrom'),
methodId: int('methodId'),
boatId: int('boatId'),
taskId: int('taskId'),
clientId: bigint('clientId', { mode: 'number' }),
reserveId: int('reserveId'),
companyId: varchar('companyId', { length: 191 }).notNull(),
originId: int('originId'),
categoryId: int('categoryId'),
departmentId: int('departmentId'),
createdBy: text('createdBy'),
initial: boolean('initial').default(false),
},
(table) => {
return {
financesId: primaryKey({columns: [table.id], name: 'PANEL_Finance_id'}),
}
}
)
export const financesConfig = relations(finance, ({ one }) => ({
reserve: one(reserve, { fields: [finance.reserveId], references: [reserve.id] }),
company: one(company, { fields: [finance.companyId], references: [company.id] }),
boat: one(boat, { fields: [finance.boatId], references: [boat.id] }),
client: one(client, { fields: [finance.clientId], references: [client.id] }),
origin: one(origin, { fields: [finance.originId], references: [origin.id] }),
method: one(method, { fields: [finance.methodId], references: [method.id] }),
task: one(task, { fields: [finance.taskId], references: [task.id] }),
refunded: one(finance, { fields: [finance.refundFrom], references: [finance.id] }),
refund: one(finance, { fields: [finance.id], references: [finance.refundFrom] }),
department: one(department, { fields: [finance.departmentId], references: [department.id] }),
categoryRelated: one(financeCategory, { fields: [finance.categoryId], references: [financeCategory.id] }),
user: one(ecuser, { fields: [finance.createdBy], references: [ecuser.id] }),
}))
export type Finances = InferSelectModel<typeof finance>
export type ReserveFinance = InferSelectModel<typeof finance> & {
refund: InferSelectModel<typeof finance> & {
user: InferSelectModel<typeof ecuser> | null
}| null
refunded: InferSelectModel<typeof finance> | null
method: InferSelectModel<typeof method> | null
user: InferSelectModel<typeof ecuser> | null
}
// #endregion Finance
// #region Geofence
export const geofence = mysqlTable(
'Geofence',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').notNull().default(''),
path: polygon('path'),
point: point('point'),
radius: float('radius'),
options: json('options'),
type: int('type'),
color: text('color'),
description: text('description'),
category: int('category').default(-1),
interest: boolean('interest').default(false),
photos: json('photos').$type<string[]>().default([]).notNull(),
stars: int('stars').default(1).notNull(),
companyId: varchar('companyId', { length: 191 }).notNull(),
},
(table) => {
return {
geofenceId: primaryKey({columns: [table.id], name: 'PANEL_Geofence_id'}),
}
}
)
export const geofenceConfig = relations(geofence, ({ one }) => ({
company: one(company, { fields: [geofence.companyId], references: [company.id] }),
}))
export type Geofence = InferSelectModel<typeof geofence>
// #endregion Geofence
// #region Partner
export const partner = mysqlTable(
'Partner',
{
id: varchar('id', { length: 191 })
.notNull()
.unique()
.default(sql`(uuid())`),
companyId: text('companyId').notNull(),
name: text('name').notNull(),
detail: text('detail'),
logo: text('logo'),
status: int('status').notNull(),
priority: int('priority').notNull().default(0),
place: text('place'),
placeId: text('placeId'),
phone: text('phone'),
email: text('email'),
website: text('website'),
instagram: text('instagram'),
facebook: text('facebook'),
linkedin: text('linkedin'),
updatedAt: datetime('updatedAt')
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),
ratings: json('ratings').$type<{ website: number; facebook: number; reserveSystem: number; instagram: number; linkedin: number }>().notNull().default({ website: 0, facebook: 0, reserveSystem: 0, instagram: 0, linkedin: 0 }),
origin: text('origin'),
reserveSystem: text('reserveSystem'),
},
(table) => {
return {
partnersId: primaryKey({columns: [table.id], name: 'PANEL_Partner_id'}),
}
}
)
export const partnersConfig = relations(partner, ({ one, many }) => ({
company: one(company, { fields: [partner.companyId], references: [company.id] }),
comments: many(partnerComment),
boats: many(partnerBoat),
}))
export type Partner = InferSelectModel<typeof partner> & {
boats: InferSelectModel<typeof partnerBoat>[]
}
// #endregion Partner
// #region Position
export const position = mysqlTable(
'Position',
{
id: varchar('id', { length: 191 }).notNull().unique(),
latest: point('latest').$type<{ lat: number; lng: number }>(),
pastPoint: point('pastPoint').$type<{ lat: number; lng: number }>(),
path: lineString('path').$type<{ lat: number; lng: number }[]>(),
times: json('times').$type<number[]>().default([]).notNull(),
speed: json('speed').$type<number[]>().default([]).notNull(),
ignition: json('ignition').$type<boolean[]>().default([]).notNull(),
createdAt: timestamp('createdAt').default(sql`now()`),
updatedAt: timestamp('updatedAt')
.default(sql`now()`)
.onUpdateNow()
.notNull(),
deviceId: int('deviceId'),
geofences: json('geofences').default([]),
lastGeofence: json('lastGeofence'),
pastGeofence: json('pastGeofence'),
},
(table) => {
return {
positionId: primaryKey({columns: [table.id], name: 'PANEL_Position_id'}),
}
}
)
export const positionConfig = relations(position, ({ one }) => ({
boat: one(boat, { fields: [position.deviceId], references: [boat.id] }),
}))
export type Position = InferSelectModel<typeof position>
// #endregion Position
// #region Reserve
export const reserve = mysqlTable(
'Reserve',
{
id: int('id').notNull().unique().autoincrement(),
status: int('status').default(0).notNull(),
departure: datetime('departure', { fsp: 3 }).notNull(),
duration: int('duration').notNull(),
checkin: datetime('checkin', { fsp: 3 }),
checkout: datetime('checkout', { fsp: 3 }),
tripulation: json('tripulation').$type<{ adults: number; kids: number; babies: number }>().notNull().default({ adults: 0, kids: 0, babies: 0 }),
comment: text('comment'),
extras: json('extras').$type<{ id: number; variant: number; amount: number }[]>().default([]).notNull(),
services: json('services').$type<{ id: number; variant: number; amount: number }[]>().default([]).notNull(),
requiresCaptain: boolean('requiresCaptain').default(false).notNull(),
discounts: json('discounts').$type<{ id: number; name: string; code?: string; amount: number; sign: string }[]>().default([]).notNull(),
contracts: json('contracts').$type<{checkin: {id: number, sign: string, language: string}}>(),
companyId: text('companyId').notNull(),
boatId: int('boatId').notNull(),
clientId: bigint('clientId', { mode: 'number' }),
resellerId: int('resellerId'),
originId: int('originId'),
captainId: varchar('captainId', { length: 191 }),
createdBy: text('createdBy'),
ecResellerId: text('ecResellerId'),
price: float('price'),
},
(table) => {
return {
reservesId: primaryKey({columns: [table.id], name: 'PANEL_Reserve_id'}),
}
}
)
export const reservesConfig = relations(reserve, ({ one, many }) => ({
finances: many(finance),
company: one(company, { fields: [reserve.companyId], references: [company.id] }),
boat: one(boat, { fields: [reserve.boatId], references: [boat.id] }),
client: one(client, { fields: [reserve.clientId], references: [client.id] }),
reseller: one(reseller, { fields: [reserve.resellerId], references: [reseller.id] }),
origin: one(origin, { fields: [reserve.originId], references: [origin.id] }),
captain: one(ecuser, { fields: [reserve.captainId], references: [ecuser.id], relationName: 'captain' }),
messages: many(reserveMsg),
//user: one(user, { fields: [reserve.createdBy], references: [user.id], relationName: 'createdBy' }),
}))
export type Reserve = InferSelectModel<typeof reserve> & {
finances: InferSelectModel<typeof finance>[] | null
boat: InferSelectModel<typeof boat> | null
client: InferSelectModel<typeof client> | null
reseller: InferSelectModel<typeof reseller> | null
origin: InferSelectModel<typeof origin> | null
captain: InferSelectModel<typeof ecuser> | null
}
export type CleanReserve = InferSelectModel<typeof reserve>
export type GpsReserve = InferSelectModel<typeof reserve> & {
client: InferSelectModel<typeof client>
}
// #endregion Reserve
// #region ReserveMsg
export const reserveMsg = mysqlTable(
'ReserveMsg',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').notNull(),
reserveId: int('reserveId').notNull(),
content: text('content').notNull(),
createdBy: text('createdBy').notNull(),
createdAt: timestamp('createdAt')
.default(sql`now()`)
.notNull(),
},
(table) => {
return {
reservesId: primaryKey({columns: [table.id], name: 'PANEL_ReserveMsg_id'}),
}
}
)
export const reserveMsgConfig = relations(reserveMsg, ({ one }) => ({
reserve: one(reserve, { fields: [reserveMsg.reserveId], references: [reserve.id] }),
user: one(ecuser, { fields: [reserveMsg.createdBy], references: [ecuser.id] }),
}))
// #endregion ReserveMsg
// #region Season
export const season = mysqlTable(
'Season',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name'),
start: date('start').notNull(),
end: date('end').notNull(),
status: int('status').default(0).notNull(),
close: int('close').default(0).notNull(),
open: int('open').default(0).notNull(),
color: text('color'),
companyId: text('companyId'),
},
(table) => {
return {
seasonsId: primaryKey({columns: [table.id], name: 'PANEL_Season_id'}),
}
}
)
export const seasonConfig = relations(season, ({ one }) => ({
company: one(company, { fields: [season.companyId], references: [company.id] }),
}))
export type Season = InferSelectModel<typeof season>
// #endregion Season
// #region Service
export const service = mysqlTable(
'Service',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').default('').notNull(),
description: text('description'),
photo: text('photo'),
status: int('status').$type<0 | 1>().default(0).notNull(),
variants: json('variants')
.$type<
(
| {
id: number
type: 'array'
name: string
stock: number
prices: { duration: number; price: number }[]
}
| {
id: number
type: 'simple'
name: string
stock: number
price: number
}
)[]
>()
.notNull()
.default([]),
companyId: text('companyId').notNull(),
},
(table) => {
return {
servicesId: primaryKey({columns: [table.id], name: 'PANEL_Service_id'}),
}
}
)
export const serviceConfig = relations(service, ({ one }) => ({
company: one(company, { fields: [service.companyId], references: [company.id] }),
}))
export type Service = InferSelectModel<typeof service>
// #endregion Service
// #region Session
export const ecsession = mysqlTable(
'Session',
{
id: varchar('id', { length: 191 })
.notNull()
.unique()
.default(sql`(uuid())`),
sessionToken: varchar('sessionToken', { length: 191 }).notNull(),
userId: varchar('userId', { length: 191 }).notNull(),
expires: datetime('expires', { mode: 'string', fsp: 3 }).notNull(),
},
(table) => {
return {
sessionId: primaryKey({columns: [table.id], name: 'PANEL_Session_id'}),
sessionSessionTokenKey: unique('Session_sessionToken_key').on(table.sessionToken),
}
}
)
// #endregion Session
// #region User
export const ecuser = mysqlTable(
'User',
{
id: varchar('id', { length: 191 })
.notNull()
.primaryKey()
.default(sql`(uuid())`),
name: varchar('name', { length: 191 }),
lastname: varchar('lastname', { length: 191 }),
companyId: varchar('companyId', { length: 191 }).notNull(),
email: varchar('email', { length: 191 }),
emailVerified: datetime('emailVerified', { mode: 'string', fsp: 3 })
.default(sql`CURRENT_TIMESTAMP(3)`)
.notNull(),
image: varchar('image', { length: 191 }),
permissions: json('permissions').$type<{ boats?: 0 | 1 | 2; gps?: 0 | 1 | 2; reserves?: 0 | 1 | 2; company?: 0 | 1 | 2; partners?: 0 | 1 | 2; finances?: 0 | 1 | 2; spectate?: 0 | 1 | 2 ; elliot?: 0 | 1 | 2}>(),
boats: json('boats').$type<number[]>(),
captainDetails: json('captainDetails').$type<{ licence: string; prices: { duration: number; price: number }[]; comment: string }>(),
phone: varchar('phone', { length: 191 }),
settings: json('settings')
.$type<EcUserSettings>()
.default({ ui: { theme: 'dark' }, gps: { units: 'metric', geofences: true, insidePort: true, colors: 'boat', measurments: true, boatLabels: true } }),
lastLogin: timestamp('lastLogin'),
},
(table) => {
return {
userId: primaryKey({columns: [table.id], name: 'PANEL_User_id'}),
userEmailKey: unique('User_email_key').on(table.email),
}
}
)
export const userConfig = relations(ecuser, ({ one, many }) => ({
company: one(company, { fields: [ecuser.companyId], references: [company.id] }),
reserves: many(reserve),
}))
export type EcUserSettings = {
ui: {
theme: 'dark' | 'light'
}
gps: {
units: 'metric' | 'imperial' | 'nautical'
geofences: boolean
insidePort: boolean
colors: 'boat' | 'direction' | 'geofences'
measurments: boolean
boatLabels: boolean
}
}
export type User = InferSelectModel<typeof ecuser>
// #endregion User
// #region VerificationToken
export const ecverificationToken = mysqlTable(
'VerificationToken',
{
identifier: varchar('identifier', { length: 191 }).notNull(),
token: varchar('token', { length: 191 }).notNull(),
expires: datetime('expires', { mode: 'string', fsp: 3 }).notNull(),
},
(table) => {
return {
verificationTokenTokenKey: unique('VerificationToken_token_key').on(table.token),
verificationTokenIdentifierTokenKey: unique('VerificationToken_identifier_token_key').on(table.identifier, table.token),
}
}
)
// #endregion VerificationToken
// #region Client
export const client = mysqlTable(
'Client',
{
id: bigint('id', { mode: 'number' }).notNull().unique().autoincrement(),
lastname: text('lastname'),
name: text('name').notNull(),
companyId: text('companyId').default('0').notNull(),
email: text('email'),
phone: text('phone'),
photo: text('photo'),
licence: text('licence'),
licenceNumber: text('licenceNumber'),
licenceName: text('licenceName'),
licenceCountry: text('licenceCountry'),
licencePhoto: text('licencePhoto'),
licenceVerified: boolean('licenceVerified').default(true).notNull(),
comment: text('comment'),
docType: text('docType'),
document: text('document'),
documentPhoto: text('documentPhoto'),
updatedAt: timestamp('updatedAt')
.default(sql`now()`)
.onUpdateNow()
.notNull(),
},
(table) => {
return {
clientId: primaryKey({columns: [table.id], name: 'PANEL_Client_id'}),
}
}
)
export const clientConfig = relations(client, ({ one, many }) => ({
company: one(company, { fields: [client.companyId], references: [company.id] }),
reserves: many(reserve),
}))
export type Client = InferSelectModel<typeof client>
// #endregion Client
// #region Reseller
export const reseller = mysqlTable(
'Reseller',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').notNull(),
email: text('email'),
phone: text('phone'),
website: text('website'),
comment: text('comment'),
duty: int('duty').default(0).notNull(),
discount: int('discount').default(0).notNull(),
format: int('format').default(0).notNull(),
companyId: text('companyId').default('0').notNull(),
methodId: int('methodId'),
},
(table) => {
return {
resellerId: primaryKey({columns: [table.id], name: 'PANEL_Reseller_id'}),
}
}
)
export const resellerConfig = relations(reseller, ({ one, many }) => ({
company: one(company, { fields: [reseller.companyId], references: [company.id] }),
method: one(method, { fields: [reseller.methodId], references: [method.id] }),
reserves: many(reserve),
}))
// #endregion Reseller
// #region Method
export const method = mysqlTable(
'Method',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').notNull(),
companyId: text('companyId').default('0').notNull(),
description: text('description'),
type: int('type').default(0).notNull(),
use: json('use').$type<{ expenses: boolean; payments: boolean; resellers: boolean }>(),
},
(table) => {
return {
methodId: primaryKey({columns: [table.id], name: 'PANEL_Method_id'}),
}
}
)
export const methodConfig = relations(method, ({ one, many }) => ({
company: one(company, { fields: [method.companyId], references: [company.id] }),
finances: many(finance),
resellers: many(reseller),
}))
export type Method = InferSelectModel<typeof method>
// #endregion Method
// #region Task
// #region TaskTypes
export enum TASK_STATUS {
PENDING = 'PENDING',
DONE = 'DONE',
DELETED = 'DELETED',
}
export enum TASK_TYPE {
UNIQUE = 'UNIQUE',
RECURRING = 'RECURRING',
}
export enum TASK_PRIORITY {
LOW = '0LOW',
MEDIUM = '1MEDIUM',
HIGH = '2HIGH',
}
export enum TASK_RELATED {
BOAT = 'BOAT',
EXTRA = 'EXTRA',
SERVICE = 'SERVICE',
EMPLOYEE = 'EMPLOYEE',
RESERVE = 'RESERVE',
COMPANY = 'COMPANY',
NONE = 'NONE',
}
export type TASK_BODY = {
description: string
images: string[]
}
export type SUBTASK = {
title: string
pending: boolean
}
export type TASK_BUDGET = {
amount: number
createdAt: string
}
export type TASK_SHOP_ITEM = {
name: string
price: number
store: string
url: string
pending: boolean
}
// #endregion TaskTypes
export const task = mysqlTable(
'Task',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').default('0').notNull(),
status: mysqlEnum('status', [TASK_STATUS.PENDING, ...Object.values(TASK_STATUS).filter((i) => i != TASK_STATUS.PENDING)])
.default(TASK_STATUS.PENDING)
.notNull(),
type: mysqlEnum('type', [TASK_TYPE.UNIQUE, ...Object.values(TASK_TYPE).filter((i) => i != TASK_TYPE.UNIQUE)])
.default(TASK_TYPE.UNIQUE)
.notNull(),
priority: mysqlEnum('priority', [TASK_PRIORITY.LOW, ...Object.values(TASK_PRIORITY).filter((i) => i != TASK_PRIORITY.LOW)])
.default(TASK_PRIORITY.LOW)
.notNull(),
assignedTo: json('assignedTo').$type<string[]>().default([]).notNull(),
title: text('title').notNull(),
body: json('body').$type<TASK_BODY>().default({ description: '', images: [] }).notNull(),
budget: json('budget').$type<TASK_BUDGET[]>().default([]).notNull(),
subTasks: json('subTasks').$type<SUBTASK[]>().default([]).notNull(),
createdAt: timestamp('createdAt')
.default(sql`now()`)
.notNull(),
updatedAt: timestamp('updatedAt')
.default(sql`now()`)
.onUpdateNow()
.notNull(),
createdBy: text('createdBy').default('').notNull(),
notifyBy: timestamp('notifyBy'),
startDate: timestamp('startDate'),
endDate: timestamp('endDate'),
departmentId: int('departmentId'),
boatId: int('boatId'),
reserveId: int('reserveId'),
serviceId: int('serviceId'),
extraId: int('extraId'),
},
(table) => {
return {
taskId: primaryKey({columns: [table.id], name: 'PANEL_Task_id'}),
}
}
)
export const taskConfig = relations(task, ({ many, one }) => ({
child: many(taskToTasks, { relationName: 'children' }),
parent: many(taskToTasks, { relationName: 'parent' }),
finances: many(finance),
comments: many(taskComment),
createdByUser: one(ecuser, { fields: [task.createdBy], references: [ecuser.id] }),
department: one(department, { fields: [task.departmentId], references: [department.id] }),
boat: one(boat, { fields: [task.boatId], references: [boat.id] }),
reserve: one(reserve, { fields: [task.reserveId], references: [reserve.id] }),
service: one(service, { fields: [task.serviceId], references: [service.id] }),
extra: one(extra, { fields: [task.extraId], references: [extra.id] }),
shopList: one(shopList),
}))
export const updateTaskSchema = createInsertSchema(task, {
id: z.number(),
assignedTo: z.array(z.string()).optional(),
body: z.object({ description: z.string(), images: z.array(z.string()).optional().default([]) }),
budget: z.array(z.object({ amount: z.number(), createdAt: z.string() })),
subTasks: z.array(z.object({ title: z.string(), pending: z.boolean() })),
})
interface TaskFinance extends InferSelectModel<typeof finance> {
department: InferSelectModel<typeof department> | null
method: InferSelectModel<typeof method> | null
categoryRelated: InferSelectModel<typeof financeCategory> | null
}
interface TaskComments extends InferSelectModel<typeof taskComment> {
user: { id: string; name: string | null; lastname: string | null } | null
}
export type Task = InferSelectModel<typeof task> & {
department: InferSelectModel<typeof department> | null
finances: InferSelectModel<typeof finance>[]
comments: InferSelectModel<typeof taskComment>[]
boat: { name: string } | null
extra: { name: string } | null
service: { name: string } | null
shopList: InferSelectModel<typeof shopList> | null
}
export type FullTask = InferSelectModel<typeof task> & {
department: InferSelectModel<typeof department> | null
finances: TaskFinance[]
comments: TaskComments[]
boat: InferSelectModel<typeof boat> | null
extra: InferSelectModel<typeof extra> | null
service: InferSelectModel<typeof service> | null
reserve: InferSelectModel<typeof reserve> | null
shopList: InferSelectModel<typeof shopList> | null
}
// #endregion Task
// #region TaskComment
export const taskComment = mysqlTable(
'TaskComment',
{
id: int('id').notNull().unique().autoincrement(),
taskId: int('taskId').notNull(),
body: text('body').notNull(),
createdAt: timestamp('createdAt')
.default(sql`now()`)
.notNull(),
createdBy: text('createdBy').default('').notNull(),
},
(table) => {
return {
taskCommentId: primaryKey({columns: [table.id], name: 'PANEL_TaskComment_id'}),
}
}
)
export const taskCommentConfig = relations(taskComment, ({ one }) => ({
task: one(task, { fields: [taskComment.taskId], references: [task.id] }),
user: one(ecuser, { fields: [taskComment.createdBy], references: [ecuser.id] }),
}))
export type TaskComment = InferSelectModel<typeof taskComment> & {
user?: { id: string; name: string; lastname: string }
}
// #endregion TaskComment
// #region TaskToTasks
export const taskToTasks = mysqlTable(
'TaskToTasks',
{
parentId: int('parentId').notNull(),
childId: int('childId').notNull(),
},
(table) => {
return {
child: primaryKey(table.childId),
}
}
)
export const taskToTasksRelations = relations(taskToTasks, ({ one }) => ({
child: one(task, { fields: [taskToTasks.childId], references: [task.id], relationName: 'parent' }),
parent: one(task, { fields: [taskToTasks.parentId], references: [task.id], relationName: 'children' }),
}))
// #endregion TaskToTasks
// #region Chat
// #region ChatTypes
export enum CHAT_STATUS {
SELECT_STATUS = 'SELECT_STATUS',
WAITING_FOR_PAY = 'WAITING_FOR_PAY',
WAITING_FOR_ASSISTANT = 'WAITING_FOR_ASSISTANT',
CONCLUDE_CHAT = 'CONCLUDE_CHAT',
}
export enum CHAT_TOPIC {
IDLE = 'IDLE',
BOOKING = 'BOOKING',
INFO = 'INFO',
CLAIM = 'CLAIM',
}
// #endregion ChatTypes
export const chat = mysqlTable(
'Chat',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').default('0').notNull(),
detail: text('detail'),
pinned: boolean('pinned').default(false).notNull(),
status: mysqlEnum('status', [CHAT_STATUS.SELECT_STATUS, ...Object.values(CHAT_STATUS).filter((i) => i != CHAT_STATUS.SELECT_STATUS)])
.default(CHAT_STATUS.SELECT_STATUS)
.notNull(),
topic: mysqlEnum('topic', [CHAT_TOPIC.IDLE, ...Object.values(CHAT_TOPIC).filter((i) => i != CHAT_TOPIC.IDLE)])
.default(CHAT_TOPIC.IDLE)
.notNull(),
createdAt: timestamp('createdAt')
.default(sql`now()`)
.notNull(),
updatedAt: timestamp('updatedAt')
.default(sql`now()`)
.onUpdateNow()
.notNull(),
clientId: bigint('clientId', { mode: 'number' }).notNull(),
assignTo: text('assignTo'),
},
(table) => {
return {
chatId: primaryKey({columns: [table.id], name: 'PANEL_Chat_id'}),
}
}
)
export const chatConfig = relations(chat, ({ one, many }) => ({
messages: many(chatMessage),
client: one(client, { fields: [chat.clientId], references: [client.id] }),
assignedUser: one(ecuser, { fields: [chat.assignTo], references: [ecuser.id] }),
}))
export type Chat = InferSelectModel<typeof chat> & {
messages: InferSelectModel<typeof chatMessage>[]
client: InferSelectModel<typeof client>
}
// #endregion Chat
// #region ChatMessage
export const chatMessage = mysqlTable(
'ChatMessage',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').default('0').notNull(),
content: text('content').notNull(),
createdAt: timestamp('createdAt')
.default(sql`now()`)
.notNull(),
userId: text('userId'),
clientId: bigint('clientId', { mode: 'number' }),
chatId: int('chatId').notNull(),
},
(table) => {
return {
chatId: primaryKey({columns: [table.id], name: 'PANEL_ChatMessage_id'}),
}
}
)
export const chatMessageConfig = relations(chatMessage, ({ one }) => ({
chat: one(chat, { fields: [chatMessage.chatId], references: [chat.id] }),
client: one(client, { fields: [chatMessage.clientId], references: [client.id] }),
user: one(ecuser, { fields: [chatMessage.userId], references: [ecuser.id] }),
}))
export type ChatMessage = InferSelectModel<typeof chatMessage>
// #endregion ChatMessage
// #region PartnerComment
export const partnerComment = mysqlTable(
'PartnerComment',
{
id: int('id').notNull().unique().autoincrement(),
partnerId: varchar('partnerId', { length: 191 }).notNull(),
content: text('content').notNull(),
createdAt: timestamp('createdAt')
.default(sql`now()`)
.notNull(),
createdBy: text('createdBy').default('').notNull(),
},
(table) => {
return {
chatId: primaryKey({columns: [table.id], name: 'PANEL_PartnerComment_id'}),
}
}
)
export const partnerCommentConfig = relations(partnerComment, ({ one }) => ({
partner: one(partner, { fields: [partnerComment.partnerId], references: [partner.id] }),
user: one(ecuser, { fields: [partnerComment.createdBy], references: [ecuser.id] }),
}))
// #endregion PartnerComment
// #region Department
export const department = mysqlTable(
'Department',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').notNull(),
companyId: text('companyId').default('0').notNull(),
status: boolean('status').default(true).notNull(),
},
(table) => {
return {
DepartmentId: primaryKey({columns: [table.id], name: 'PANEL_Department_id'}),
}
}
)
export const departmentConfig = relations(department, ({ one }) => ({
company: one(company, { fields: [department.companyId], references: [company.id] }),
}))
// #endregion Department
// #region FinanceCategory
export const financeCategory = mysqlTable(
'FinanceCategory',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').notNull(),
name: text('category'),
description: text('description'),
status: boolean('status').default(true).notNull(),
},
(table) => {
return {
financesId: primaryKey({columns: [table.id], name: 'PANEL_FinanceCategory_id'}),
}
}
)
export const financeCategoryConfig = relations(financeCategory, ({ one, many }) => ({
finances: many(finance),
company: one(company, { fields: [financeCategory.companyId], references: [company.id] }),
}))
// #endregion FinanceCategory
// #region ShopList
export type SHOPLIST_ITEM = {
name: string
price: number
store: string
url: string
pending: boolean
image?: string
}
export enum SHOPLIST_STATUS {
PENDING = 'PENDING',
DONE = 'DONE',
DELETED = 'DELETED',
}
export const shopList = mysqlTable(
'ShopList',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').default('0').notNull(),
status: mysqlEnum('status', [SHOPLIST_STATUS.PENDING, ...Object.values(SHOPLIST_STATUS).filter((i) => i != SHOPLIST_STATUS.PENDING)])
.default(SHOPLIST_STATUS.PENDING)
.notNull(),
title: text('title').notNull(),
description: text('description'),
items: json('items').$type<SHOPLIST_ITEM[]>().default([]).notNull(),
createdAt: timestamp('createdAt')
.default(sql`now()`)
.notNull(),
updatedAt: timestamp('updatedAt')
.default(sql`now()`)
.onUpdateNow()
.notNull(),
departmentId: int('departmentId'),
boatId: int('boatId'),
reserveId: int('reserveId'),
serviceId: int('serviceId'),
extraId: int('extraId'),
taskId: int('taskId'),
},
(table) => {
return {
shopListId: primaryKey({columns: [table.id], name: 'PANEL_ShopList_id'}),
}
}
)
export const shopListConfig = relations(shopList, ({ one }) => ({
department: one(department, { fields: [shopList.departmentId], references: [department.id] }),
boat: one(boat, { fields: [shopList.boatId], references: [boat.id] }),
reserve: one(reserve, { fields: [shopList.reserveId], references: [reserve.id] }),
service: one(service, { fields: [shopList.serviceId], references: [service.id] }),
extra: one(extra, { fields: [shopList.extraId], references: [extra.id] }),
task: one(task, { fields: [shopList.taskId], references: [task.id] }),
}))
export const shopItem = mysqlTable(
'ShopItem',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').default('0').notNull(),
name: text('name').notNull(),
price: int('price'),
store: text('store'),
url: text('url'),
description: text('description'),
pending: boolean('pending').default(true).notNull(),
image: text('image'),
departmentId: int('departmentId'),
boatId: int('boatId'),
reserveId: int('reserveId'),
serviceId: int('serviceId'),
extraId: int('extraId'),
taskId: int('taskId'),
},
(table) => {
return {
shopItemId: primaryKey({columns: [table.id], name: 'PANEL_ShopItem_id'}),
}
}
)
export const shopItemConfig = relations(shopItem, ({ one }) => ({
department: one(department, { fields: [shopItem.departmentId], references: [department.id] }),
boat: one(boat, { fields: [shopItem.boatId], references: [boat.id] }),
reserve: one(reserve, { fields: [shopItem.reserveId], references: [reserve.id] }),
service: one(service, { fields: [shopItem.serviceId], references: [service.id] }),
extra: one(extra, { fields: [shopItem.extraId], references: [extra.id] }),
task: one(task, { fields: [shopItem.taskId], references: [task.id] }),
}))
export const shopItemSchema = createInsertSchema(shopItem)
export const updateShopItemSchema = createInsertSchema(shopItem, {
id: z.number(),
})
export const updateShopListSchema = createInsertSchema(shopList, {
id: z.number(),
items: z.array(z.object({ name: z.string(), price: z.number().default(0), store: z.string(), url: z.string(), pending: z.boolean(), image: z.string().optional() })),
})
export type ShopItem = InferSelectModel<typeof shopItem>
export type SimpleShopList = InferSelectModel<typeof shopList>
export type ShopList = InferSelectModel<typeof shopList> & {
department: InferSelectModel<typeof department> | null
boat: { id: number; name: string } | null
extra: { id: number; name: string } | null
service: { id: number; name: string } | null
reserve: InferSelectModel<typeof reserve> | null
task: { id: number; title: string } | null
}
export type FullShopList = InferSelectModel<typeof shopList> & {
department: InferSelectModel<typeof department> | null
boat: InferSelectModel<typeof boat> | null
extra: InferSelectModel<typeof extra> | null
service: InferSelectModel<typeof service> | null
reserve: InferSelectModel<typeof reserve> | null
task: InferSelectModel<typeof task> | null
}
// #endregion ShopList
// #region SearchResults
export const searchResults = mysqlTable(
'SearchResults',
{
id: int('id').notNull().unique().autoincrement(),
companyId: text('companyId').default('0').notNull(),
title: text('title').default('Titulo').notNull(),
description: text('description').default('Descripcion').notNull(),
url: text('url').default('URL').notNull(),
favicons: json('favicons').$type<{ high_res: string; low_res: string }>().default({ high_res: '', low_res: '' }).notNull(),
status: text('status').default('PENDING').notNull(),
query: text('query').default('').notNull(),
},
(table) => {
return {
searchResultsId: primaryKey({columns: [table.id], name: 'PANEL_SearchResults_id'}),
}
}
)
// #endregion SearchResults
// #region Origin
export enum ORIGIN_TYPE {
RESELLER = 'RESELLER',
DIRECT = 'DIRECT',
}
export const origin = mysqlTable(
'Origin',
{
id: int('id').notNull().unique().autoincrement(),
type: mysqlEnum('type', [ORIGIN_TYPE.DIRECT, ...Object.values(ORIGIN_TYPE).filter((i) => i != ORIGIN_TYPE.DIRECT)])
.default(ORIGIN_TYPE.DIRECT)
.notNull(),
name: text('name').notNull(),
email: text('email'),
phone: text('phone'),
website: text('website'),
detail: text('detail'),
duty: float('duty'),
discount: int('discount'),
charges: float('charges'),
chargesSign: text('chargesSign'),
includesTaxes: boolean('includesTaxes').default(false).notNull(),
companyId: text('companyId').default('0').notNull(),
methodId: int('methodId'),
},
(table) => {
return {
originId: primaryKey({columns: [table.id], name: 'PANEL_Origin_id'}),
}
}
)
export const originConfig = relations(origin, ({ one }) => ({
company: one(company, { fields: [origin.companyId], references: [company.id] }),
method: one(method, { fields: [origin.methodId], references: [method.id] }),
}))
export type Origin = InferSelectModel<typeof origin>
// #endregion Origin
// #region Suscriber
export const suscribers = mysqlTable(
'Suscribers',
{
id: int('id').notNull().unique().autoincrement(),
email: text('email'),
createdAt: timestamp('createdAt')
.default(sql`now()`)
.notNull(),
},
(table) => {
return {
suscriberId: primaryKey({columns: [table.id], name: 'PANEL_Suscribers_id'}),
}
}
)
// #endregion Suscriber
// #region Discount
export const discount = mysqlTable(
'Discount',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').notNull(),
from: date('from'),
to: date('to'),
percent: int('percent'),
amount: int('amount'),
code: text('code'),
visible: boolean('visible').default(false).notNull(),
companyId: text('companyId').default('0').notNull(),
methodId: int('methodId'),
},
(table) => {
return {
discountId: primaryKey({columns: [table.id], name: 'PANEL_Discount_id'}),
}
}
)
export const discountConfig = relations(discount, ({ one, many }) => ({
company: one(company, { fields: [discount.companyId], references: [company.id] }),
method: one(method, { fields: [discount.methodId], references: [method.id] }),
boats: many(discountToBoat),
}))
export type Discount = InferSelectModel<typeof discount>
// #endregion Discount
// #region DiscountToBoat
export const discountToBoat = mysqlTable(
'DiscountToBoat',
{
discountId: int('discountId').notNull(),
boatId: int('boatId').notNull(),
},
(table) => {
return {
child: primaryKey(table.boatId),
}
}
)
export const discountToBoatRelations = relations(discountToBoat, ({ one }) => ({
boat: one(boat, { fields: [discountToBoat.boatId], references: [boat.id], relationName: 'discount' }),
discount: one(discount, { fields: [discountToBoat.discountId], references: [discount.id], relationName: 'boat' }),
}))
// #endregion DiscountToBoat
// #region Places
export const place = mysqlTable(
'Place',
{
id: int('id').notNull().unique().autoincrement(),
name: text('name').notNull(),
position: json('position').$type<{ lat: number; lng: number }>().notNull(),
map: text('map'),
photos: json('photos').$type<string[]>().default([]).notNull(),
priority: int('priority').default(0).notNull(),
},
(table) => {
return {
placeId: primaryKey({columns: [table.id], name: 'PANEL_Place_id'}),
}
}
)
export const placeConfig = relations(place, ({ many }) => ({
boats: many(boat),
}))
// #endregion Places
// #endregion EASYCHARTER
// #region User
export type UserSettings = {
ui: {
theme: 'dark' | 'light'
}
}
export const user = ECMysqlTable(
'User',
{
id: varchar('id', { length: 191 })
.notNull()
.primaryKey()
.default(sql`(uuid())`),
code: varchar('code', { length: 191 }),
name: varchar('name', { length: 191 }),
lastname: varchar('lastname', { length: 191 }),
email: varchar('email', { length: 191 }),
emailVerified: datetime('emailVerified', { mode: 'string', fsp: 3 })
.default(sql`CURRENT_TIMESTAMP(3)`)
.notNull(),
image: varchar('image', { length: 191 }),
phone: varchar('phone', { length: 191 }),
docType: text('docType'),
document: text('document'),
birthdate: datetime('birthdate', { fsp: 3 }),
settings: json('settings')
.$type<UserSettings>()
.default({ ui: { theme: 'dark' } }),
reseller: boolean('reseller').default(false).notNull(),
address: text('address'),
placeId: text('placeId'),
lastLogin: timestamp('lastLogin'),
},
(table) => {
return {
userId: primaryKey({ columns: [table.id], name: 'EC_User_id' }),
userEmailKey: unique('User_email_key').on(table.email),
userCodeKey: unique('User_code_key').on(table.code),
}
}
)
// #endregion User
// #region VerificationToken
export const verificationToken = ECMysqlTable(
'VerificationToken',
{
identifier: varchar('identifier', { length: 191 }).notNull(),
token: varchar('token', { length: 191 }).notNull(),
expires: datetime('expires', { mode: 'string', fsp: 3 }).notNull(),
},
(table) => {
return {
verificationTokenTokenKey: unique('VerificationToken_token_key').on(table.token),
verificationTokenIdentifierTokenKey: unique('VerificationToken_identifier_token_key').on(table.identifier, table.token),
}
}
)
// #endregion VerificationToken
// #region Session
export const session = ECMysqlTable(
'Session',
{
id: varchar('id', { length: 191 })
.notNull()
.unique()
.default(sql`(uuid())`),
sessionToken: varchar('sessionToken', { length: 191 }).notNull(),
userId: varchar('userId', { length: 191 }).notNull(),
expires: datetime('expires', { mode: 'string', fsp: 3 }).notNull(),
},
(table) => {
return {
sessionId: primaryKey({ columns: [table.id], name: 'EC_Session_id' }),
sessionSessionTokenKey: unique('Session_sessionToken_key').on(table.sessionToken),
}
}
)
// #endregion Session
// #region Account
export const account = ECMysqlTable(
'Account',
{
id: varchar('id', { length: 191 })
.notNull()
.default(sql`(uuid())`),
userId: varchar('userId', { length: 191 }).notNull(),
type: varchar('type', { length: 191 }).notNull(),
provider: varchar('provider', { length: 191 }).notNull(),
providerAccountId: varchar('providerAccountId', { length: 191 }).notNull(),
refreshToken: varchar('refresh_token', { length: 191 }),
accessToken: varchar('access_token', { length: 191 }),
expiresAt: int('expires_at'),
tokenType: varchar('token_type', { length: 191 }),
scope: varchar('scope', { length: 191 }),
idToken: varchar('id_token', { length: 191 }),
sessionState: varchar('session_state', { length: 191 }),
},
(table) => {
return {
accountId: primaryKey({ columns: [table.id], name: 'EC_Account_id' }),
accountProviderProviderAccountIdKey: unique('Account_provider_providerAccountId_key').on(table.provider, table.providerAccountId),
}
}
)
// #endregion Account
@AlexBlokh
Hello!
In my case, the error occurs during the following action:
The database is empty, the table does not exist
> drizzle-kit push
The table was created without errors, run the command again
> drizzle-kit push
drizzle-kit: v0.21.4 drizzle-orm: v0.30.10
No config path provided, using default path
Reading config file '/app/drizzle.config.ts'
Using 'pg' driver for database querying
[✓] Pulling schema from database...TypeError: Cannot use 'in' operator to search for 'default' in undefined
at /app/node_modules/drizzle-kit/bin.cjs:18362:23
at Array.map (
My scheme:
```ts
import { pgTable, serial, timestamp } from 'drizzle-orm/pg-core';
export const test = pgTable('test', {
id: serial('id').primaryKey().notNull(),
deactivatedDate: timestamp('deactivated_date', {
mode: 'date',
precision: 0,
}),
});
Config:
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
dialect: 'postgresql',
out: './migrations',
schema: [
'./drizzle-test/*.schema.ts',
],
dbCredentials: {
host: 'localhost',
port: 5432,
user: 'user',
password: 'password',
database: 'drizzle-test',
},
verbose: true,
strict: true,
});
Also, when I remove the deactivated_date
column, there is no error when running the command
Also, when I remove the
deactivated_date
column, there is no error when running the command
I am also facing the same issue, the problem is with timestamp, any solutions?
Hi! i have this error when i do 'npx drizzle-kit push', i fixed it adding a question mark on 'node_modules/drizzle-kit/bin.cjs:111813:123'
this is the following error im getting in the terminal:
npx: 10.2.4 node: v20.11.0
the line i modified to fix it is the following: