community feature
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { pgTable } from 'drizzle-orm/pg-core'
|
||||
import { createInsertSchema, createSelectSchema } from 'drizzle-zod'
|
||||
import { id, timestamps } from '../../helpers'
|
||||
import { users } from './users'
|
||||
|
||||
export const accounts = pgTable('auth_accounts', (t) => ({
|
||||
id: id('account'),
|
||||
userId: t
|
||||
.text('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
providerId: t.text('provider_id').notNull(),
|
||||
accountId: t.text('account_id').notNull(),
|
||||
password: t.text('password'),
|
||||
accessToken: t.text('access_token'),
|
||||
refreshToken: t.text('refresh_token'),
|
||||
idToken: t.text('id_token'),
|
||||
accessTokenExpiresAt: t.timestamp('access_token_expires_at', {
|
||||
withTimezone: true,
|
||||
}),
|
||||
refreshTokenExpiresAt: t.timestamp('refresh_token_expires_at', {
|
||||
withTimezone: true,
|
||||
}),
|
||||
scope: t.text('scope'),
|
||||
...timestamps,
|
||||
})).enableRLS()
|
||||
|
||||
export type Account = typeof accounts.$inferSelect
|
||||
export type NewAccount = typeof accounts.$inferInsert
|
||||
export const insertAccountSchema = createInsertSchema(accounts)
|
||||
export const selectAccountSchema = createSelectSchema(accounts)
|
||||
@@ -0,0 +1,15 @@
|
||||
import { pgTable } from 'drizzle-orm/pg-core'
|
||||
import { createInsertSchema, createSelectSchema } from 'drizzle-zod'
|
||||
import { createdAt, id } from '../../helpers'
|
||||
|
||||
export const jwks = pgTable('auth_jwks', (t) => ({
|
||||
id: id('jwks'),
|
||||
publicKey: t.text('public_key').notNull(),
|
||||
privateKey: t.text('private_key').notNull(),
|
||||
createdAt,
|
||||
})).enableRLS()
|
||||
|
||||
export type Jwks = typeof jwks.$inferSelect
|
||||
export type NewJwks = typeof jwks.$inferInsert
|
||||
export const insertJwksSchema = createInsertSchema(jwks)
|
||||
export const selectJwksSchema = createSelectSchema(jwks)
|
||||
@@ -0,0 +1,28 @@
|
||||
import { pgTable } from 'drizzle-orm/pg-core'
|
||||
import { createInsertSchema, createSelectSchema } from 'drizzle-zod'
|
||||
import { id, timestamps } from '../../helpers'
|
||||
import { users } from './users'
|
||||
|
||||
export const sessions = pgTable('auth_sessions', (t) => ({
|
||||
id: id('session'),
|
||||
userId: t
|
||||
.text('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
expiresAt: t.timestamp('expires_at', { withTimezone: true }),
|
||||
token: t.text('token').notNull(),
|
||||
ipAddress: t.text('ip_address'),
|
||||
userAgent: t.text('user_agent'),
|
||||
// Custom: active property for the session context
|
||||
activePropertyId: t.text('active_property_id'),
|
||||
// Admin plugin support: tracks who is impersonating this session
|
||||
impersonatedBy: t
|
||||
.text('impersonated_by')
|
||||
.references(() => users.id, { onDelete: 'set null' }),
|
||||
...timestamps,
|
||||
})).enableRLS()
|
||||
|
||||
export type Session = typeof sessions.$inferSelect
|
||||
export type NewSession = typeof sessions.$inferInsert
|
||||
export const insertSessionSchema = createInsertSchema(sessions)
|
||||
export const selectSessionSchema = createSelectSchema(sessions)
|
||||
@@ -0,0 +1,28 @@
|
||||
import { pgEnum, pgTable, uniqueIndex } from 'drizzle-orm/pg-core'
|
||||
import { createInsertSchema, createSelectSchema } from 'drizzle-zod'
|
||||
import { id, lower, timestampsColumns } from '../../helpers'
|
||||
|
||||
export const USER_ROLES = ['user', 'admin'] as const
|
||||
export const userRoles = pgEnum('auth_user_roles', USER_ROLES)
|
||||
|
||||
export const users = pgTable(
|
||||
'auth_users',
|
||||
(t) => ({
|
||||
id: id('user'),
|
||||
email: t.text('email').notNull(),
|
||||
emailVerified: t.boolean('email_verified').notNull().default(false),
|
||||
name: t.text('name').notNull(),
|
||||
image: t.text('image'),
|
||||
role: userRoles('role').notNull().default('user'),
|
||||
banned: t.boolean('banned').notNull().default(false),
|
||||
banReason: t.text('ban_reason'),
|
||||
banExpires: t.timestamp('ban_expires', { withTimezone: true }),
|
||||
...timestampsColumns,
|
||||
}),
|
||||
(t) => [uniqueIndex('email_unique_index').on(lower(t.email))],
|
||||
).enableRLS()
|
||||
|
||||
export type User = typeof users.$inferSelect
|
||||
export type NewUser = typeof users.$inferInsert
|
||||
export const insertUserSchema = createInsertSchema(users)
|
||||
export const selectUserSchema = createSelectSchema(users)
|
||||
@@ -0,0 +1,22 @@
|
||||
import { index, pgTable } from 'drizzle-orm/pg-core'
|
||||
import { createInsertSchema, createSelectSchema } from 'drizzle-zod'
|
||||
import { id, timestamps } from '../../helpers'
|
||||
|
||||
export const verifications = pgTable(
|
||||
'auth_verifications',
|
||||
(t) => ({
|
||||
id: id('verification'),
|
||||
value: t.text('value').notNull(),
|
||||
identifier: t.text('identifier').notNull(),
|
||||
expiresAt: t.timestamp('expires_at', {
|
||||
withTimezone: true,
|
||||
}),
|
||||
...timestamps,
|
||||
}),
|
||||
(t) => [index('verification_identifier_index').on(t.identifier)],
|
||||
).enableRLS()
|
||||
|
||||
export type Verification = typeof verifications.$inferSelect
|
||||
export type NewVerification = typeof verifications.$inferInsert
|
||||
export const insertVerificationSchema = createInsertSchema(verifications)
|
||||
export const selectVerificationSchema = createSelectSchema(verifications)
|
||||
@@ -0,0 +1,11 @@
|
||||
// Auth tables
|
||||
export * from './auth/accounts'
|
||||
export * from './auth/jwks'
|
||||
export * from './auth/sessions'
|
||||
export * from './auth/users'
|
||||
export * from './auth/verifications'
|
||||
|
||||
// Property tables
|
||||
export * from './properties/addresses'
|
||||
export * from './properties/models'
|
||||
export * from './properties/properties'
|
||||
@@ -0,0 +1,53 @@
|
||||
import { pgTable, unique } from 'drizzle-orm/pg-core'
|
||||
import { z } from 'zod'
|
||||
import { id, timestampsColumns } from '../../helpers'
|
||||
|
||||
export const addresses = pgTable(
|
||||
'properties_addresses',
|
||||
(t) => ({
|
||||
id: id('address'),
|
||||
streetNumber: t.text('street_number'),
|
||||
route: t.text('route'),
|
||||
routeShort: t.text('route_short'),
|
||||
neighborhood: t.text('neighborhood'),
|
||||
city: t.text('city'),
|
||||
county: t.text('county'),
|
||||
state: t.text('state'),
|
||||
stateLong: t.text('state_long'),
|
||||
postalCode: t.text('postal_code'),
|
||||
postalCodeSuffix: t.text('postal_code_suffix'),
|
||||
country: t.text('country'),
|
||||
countryLong: t.text('country_long'),
|
||||
latitude: t.numeric('latitude'),
|
||||
longitude: t.numeric('longitude'),
|
||||
rawJson: t.jsonb('raw_json'),
|
||||
...timestampsColumns,
|
||||
}),
|
||||
(t) => [
|
||||
// Unique constraint on core address components to prevent duplicates
|
||||
unique('address_components_unique').on(t.streetNumber, t.route, t.city, t.state, t.postalCode),
|
||||
],
|
||||
).enableRLS()
|
||||
|
||||
// Create address schema manually to avoid issues with generated columns
|
||||
export const addressSchema = z.object({
|
||||
streetNumber: z.string().optional(),
|
||||
route: z.string().optional(),
|
||||
routeShort: z.string().optional(),
|
||||
neighborhood: z.string().optional(),
|
||||
city: z.string().optional(),
|
||||
county: z.string().optional(),
|
||||
state: z.string().optional(),
|
||||
stateLong: z.string().optional(),
|
||||
postalCode: z.string().optional(),
|
||||
postalCodeSuffix: z.string().optional(),
|
||||
country: z.string().default('US'),
|
||||
countryLong: z.string().optional(),
|
||||
latitude: z.string().optional(),
|
||||
longitude: z.string().optional(),
|
||||
rawJson: z.record(z.string(), z.unknown()).optional(),
|
||||
})
|
||||
|
||||
export type AddressSchema = z.infer<typeof addressSchema>
|
||||
export type Address = typeof addresses.$inferSelect
|
||||
export type NewAddress = typeof addresses.$inferInsert
|
||||
@@ -0,0 +1,31 @@
|
||||
import { relations } from 'drizzle-orm'
|
||||
import { pgTable } from 'drizzle-orm/pg-core'
|
||||
import { createInsertSchema, createSelectSchema } from 'drizzle-zod'
|
||||
import { id, timestampsColumnsSoftDelete } from '../../helpers'
|
||||
import { properties } from './properties'
|
||||
|
||||
export const models = pgTable('properties_models', (t) => ({
|
||||
id: id('model'),
|
||||
name: t.text('name'),
|
||||
version: t.integer('version').default(1),
|
||||
description: t.text('description'),
|
||||
draft: t.boolean('draft').default(true),
|
||||
propertyId: t
|
||||
.text('property_id')
|
||||
.references(() => properties.id, { onDelete: 'set null' }),
|
||||
sceneGraph: t.jsonb('scene_graph'),
|
||||
metadata: t.jsonb('metadata'),
|
||||
...timestampsColumnsSoftDelete,
|
||||
})).enableRLS()
|
||||
|
||||
export const modelsRelations = relations(models, ({ one }) => ({
|
||||
property: one(properties, {
|
||||
fields: [models.propertyId],
|
||||
references: [properties.id],
|
||||
}),
|
||||
}))
|
||||
|
||||
export type Model = typeof models.$inferSelect
|
||||
export type NewModel = typeof models.$inferInsert
|
||||
export const insertModelSchema = createInsertSchema(models)
|
||||
export const selectModelSchema = createSelectSchema(models)
|
||||
@@ -0,0 +1,44 @@
|
||||
import { relations } from 'drizzle-orm'
|
||||
import { index, pgTable } from 'drizzle-orm/pg-core'
|
||||
import { createInsertSchema, createSelectSchema } from 'drizzle-zod'
|
||||
import { id, timestampsColumns } from '../../helpers'
|
||||
import { users } from '../auth/users'
|
||||
import { addresses } from './addresses'
|
||||
|
||||
export const properties = pgTable(
|
||||
'properties',
|
||||
(t) => ({
|
||||
id: id('property'),
|
||||
name: t.text('name'),
|
||||
addressId: t
|
||||
.text('address_id')
|
||||
.references(() => addresses.id, { onDelete: 'set null' })
|
||||
.unique(),
|
||||
ownerId: t
|
||||
.text('owner_id')
|
||||
.references(() => users.id, { onDelete: 'set null' }),
|
||||
detailsJson: t.jsonb('details_json'),
|
||||
metadata: t.jsonb('metadata'),
|
||||
...timestampsColumns,
|
||||
}),
|
||||
(t) => [
|
||||
index('property_address_idx').on(t.addressId),
|
||||
index('property_owner_idx').on(t.ownerId),
|
||||
],
|
||||
).enableRLS()
|
||||
|
||||
export const propertiesRelations = relations(properties, ({ one }) => ({
|
||||
address: one(addresses, {
|
||||
fields: [properties.addressId],
|
||||
references: [addresses.id],
|
||||
}),
|
||||
owner: one(users, {
|
||||
fields: [properties.ownerId],
|
||||
references: [users.id],
|
||||
}),
|
||||
}))
|
||||
|
||||
export type Property = typeof properties.$inferSelect
|
||||
export type NewProperty = typeof properties.$inferInsert
|
||||
export const insertPropertySchema = createInsertSchema(properties)
|
||||
export const selectPropertySchema = createSelectSchema(properties)
|
||||
Reference in New Issue
Block a user