135 lines
3.6 KiB
TypeScript
135 lines
3.6 KiB
TypeScript
import { sql } from 'drizzle-orm';
|
|
import * as t from 'drizzle-orm/pg-core';
|
|
import { timestamps } from '../timestamps';
|
|
import { municipalities, parishes, states } from './general';
|
|
import { authSchema } from './schemas';
|
|
|
|
// Tabla de Usuarios sistema
|
|
export const users = authSchema.table(
|
|
'users',
|
|
{
|
|
id: t.serial('id').primaryKey(),
|
|
username: t.text('username').unique().notNull(),
|
|
email: t.text('email').unique().notNull(),
|
|
fullname: t.text('fullname').notNull(),
|
|
phone: t.text('phone'),
|
|
password: t.text('password').notNull(),
|
|
state: t
|
|
.integer('state')
|
|
.references(() => states.id, { onDelete: 'set null' }),
|
|
municipality: t
|
|
.integer('municipality')
|
|
.references(() => municipalities.id, { onDelete: 'set null' }),
|
|
parish: t
|
|
.integer('parish')
|
|
.references(() => parishes.id, { onDelete: 'set null' }),
|
|
isTwoFactorEnabled: t
|
|
.boolean('is_two_factor_enabled')
|
|
.notNull()
|
|
.default(false),
|
|
twoFactorSecret: t.text('two_factor_secret'),
|
|
isEmailVerified: t.boolean('is_email_verified').notNull().default(false),
|
|
isActive: t.boolean('is_active').notNull().default(true),
|
|
...timestamps,
|
|
},
|
|
(users) => ({
|
|
usersIdx: t.index('users_idx').on(users.username),
|
|
}),
|
|
);
|
|
|
|
// Tabla de Roles
|
|
export const roles = authSchema.table(
|
|
'roles',
|
|
{
|
|
id: t.serial('id').primaryKey(),
|
|
name: t.text('name').notNull(),
|
|
...timestamps,
|
|
},
|
|
(roles) => ({
|
|
rolesIdx: t.index('roles_idx').on(roles.name),
|
|
}),
|
|
);
|
|
|
|
//tabla User_roles
|
|
export const usersRole = authSchema.table(
|
|
'user_role',
|
|
{
|
|
id: t.serial('id').primaryKey(),
|
|
userId: t
|
|
.integer('user_id')
|
|
.references(() => users.id, { onDelete: 'cascade' }),
|
|
roleId: t
|
|
.integer('role_id')
|
|
.references(() => roles.id, { onDelete: 'set null' }),
|
|
...timestamps,
|
|
},
|
|
(userRole) => ({
|
|
userRoleIdx: t.index('user_role_idx').on(userRole.userId),
|
|
}),
|
|
);
|
|
|
|
export const userAccessView = authSchema.view('user_access_view', {
|
|
userId: t.integer('userId').notNull(),
|
|
username: t.text('username').notNull(),
|
|
email: t.text('email').notNull(),
|
|
fullname: t.text('email').notNull(),
|
|
roleId: t.integer('role_id'),
|
|
roleName: t.text('role_name'),
|
|
}).as(sql`
|
|
SELECT
|
|
u.id AS user_id,
|
|
u.username,
|
|
u.email,
|
|
u.fullname,
|
|
r.id AS role_id,
|
|
r.name AS role_name
|
|
FROM
|
|
auth.users u
|
|
LEFT JOIN
|
|
auth.user_role ur ON u.id = ur.user_id
|
|
LEFT JOIN
|
|
auth.roles r ON ur.role_id = r.id`);
|
|
|
|
// Tabla de Sesiones
|
|
export const sessions = authSchema.table(
|
|
'sessions',
|
|
{
|
|
id: t
|
|
.uuid('id')
|
|
.primaryKey()
|
|
.default(sql`gen_random_uuid()`),
|
|
userId: t
|
|
.integer('user_id')
|
|
.references(() => users.id, { onDelete: 'cascade' })
|
|
.notNull(),
|
|
sessionToken: t.text('session_token').notNull(),
|
|
expiresAt: t.integer('expires_at').notNull(),
|
|
previousSessionToken: t.varchar('previous_session_token'),
|
|
lastRotatedAt: t.timestamp('last_rotated_at'),
|
|
|
|
...timestamps,
|
|
},
|
|
(sessions) => ({
|
|
sessionsIdx: t.index('sessions_idx').on(sessions.sessionToken),
|
|
}),
|
|
);
|
|
|
|
//tabla de tokens de verificación
|
|
export const verificationTokens = authSchema.table(
|
|
'verificationToken',
|
|
{
|
|
identifier: t.text('identifier').notNull(),
|
|
token: t.text('token').notNull(),
|
|
code: t.integer('code'),
|
|
expires: t.timestamp('expires', { mode: 'date' }).notNull(),
|
|
ipAddress: t.text('ip_address').notNull(),
|
|
},
|
|
(verificationToken) => [
|
|
{
|
|
compositePk: t.primaryKey({
|
|
columns: [verificationToken.identifier, verificationToken.token],
|
|
}),
|
|
},
|
|
],
|
|
);
|