init
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
import { drizzle } from "drizzle-orm/node-postgres";
|
||||
import * as schema from "./schema/index";
|
||||
|
||||
const db = drizzle(process.env.DATABASE_URL!, { schema });
|
||||
|
||||
export default db;
|
||||
@@ -0,0 +1,33 @@
|
||||
import {
|
||||
pgTable,
|
||||
uuid,
|
||||
varchar,
|
||||
timestamp,
|
||||
integer,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import { serverSessions } from "./serverSessions";
|
||||
|
||||
export const apps = pgTable("apps", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
name: varchar("name").notNull(), // Имя приложения (например, "minecraft")
|
||||
title: varchar("title").notNull(), // Название приложения (например, "Майнкрафт")
|
||||
gpuLimitMb: integer("gpu_limit_mb"), // Лимит GPU в мегабайтах (только для stream серверов)
|
||||
psVersion: integer("ps_version"), // Версия Pixel Streaming (например, "1")
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
// Zod schemas for validation
|
||||
export const insertAppSchema = createInsertSchema(apps);
|
||||
export const selectAppSchema = createSelectSchema(apps);
|
||||
|
||||
// Relations
|
||||
export const appsRelations = relations(apps, ({ many }) => ({
|
||||
serverSessions: many(serverSessions),
|
||||
}));
|
||||
|
||||
// Type exports
|
||||
export type App = typeof apps.$inferSelect;
|
||||
export type NewApp = typeof apps.$inferInsert;
|
||||
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
pgTable,
|
||||
uuid,
|
||||
varchar,
|
||||
timestamp,
|
||||
text,
|
||||
inet,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import { users } from "./users";
|
||||
|
||||
// Храним пользовательские сессии. accessToken хранится как bcrypt-хэш
|
||||
export const authSessions = pgTable("auth_sessions", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
userId: uuid("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id),
|
||||
// bcrypt-хэш токена доступа. Длина 60-72 символа, но оставим запас
|
||||
accessTokenHash: varchar("access_token_hash", { length: 72 }).notNull(),
|
||||
// Доп. метаданные устройства/браузера
|
||||
userAgent: text("user_agent"),
|
||||
ipAddress: inet("ip_address"),
|
||||
// Срок действия и отзыв
|
||||
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
||||
revokedAt: timestamp("revoked_at", { withTimezone: true }),
|
||||
createdAt: timestamp("created_at", { withTimezone: true })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
updatedAt: timestamp("updated_at", { withTimezone: true })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
});
|
||||
|
||||
// Relations
|
||||
export const authSessionsRelations = relations(authSessions, ({ one }) => ({
|
||||
user: one(users, {
|
||||
fields: [authSessions.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
// Zod schemas for validation
|
||||
export const insertAuthSessionSchema = createInsertSchema(authSessions);
|
||||
export const selectAuthSessionSchema = createSelectSchema(authSessions);
|
||||
|
||||
// Type exports
|
||||
export type AuthSession = typeof authSessions.$inferSelect;
|
||||
export type NewAuthSession = typeof authSessions.$inferInsert;
|
||||
@@ -0,0 +1,9 @@
|
||||
import { pgEnum } from "drizzle-orm/pg-core";
|
||||
|
||||
// Enum для ролей пользователей
|
||||
export const roleNameEnum = pgEnum("role_name", [
|
||||
"admin",
|
||||
"director",
|
||||
"manager",
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Export all schemas
|
||||
export * from "./enums";
|
||||
export * from "./streamServers";
|
||||
export * from "./localServers";
|
||||
export * from "./apps";
|
||||
export * from "./users";
|
||||
export * from "./serverSessions";
|
||||
export * from "./authSessions";
|
||||
export * from "./protectedRoutes";
|
||||
@@ -0,0 +1,27 @@
|
||||
import { pgTable, uuid, varchar } from "drizzle-orm/pg-core";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import { serverSessions } from "./serverSessions";
|
||||
|
||||
export const localServers = pgTable("local_servers", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
localIp: varchar("local_ip", { length: 45 }).notNull(), // IPv6 can be up to 45 chars
|
||||
hostname: varchar("hostname", { length: 255 }).notNull(),
|
||||
location: varchar("location", { length: 10 }).notNull(), // ru1, uae1
|
||||
type: varchar("type", { length: 10 }).notNull(), // demo, prod
|
||||
});
|
||||
|
||||
// Zod schemas for validation
|
||||
export const insertLocalServerSchema = createInsertSchema(localServers);
|
||||
export const selectLocalServerSchema = createSelectSchema(localServers);
|
||||
|
||||
// Relations
|
||||
export const localServersRelations = relations(localServers, ({ many }) => ({
|
||||
serverSessions: many(serverSessions, {
|
||||
relationName: "session_local_server",
|
||||
}),
|
||||
}));
|
||||
|
||||
// Type exports
|
||||
export type LocalServer = typeof localServers.$inferSelect;
|
||||
export type NewLocalServer = typeof localServers.$inferInsert;
|
||||
@@ -0,0 +1,31 @@
|
||||
import { pgTable, varchar, text, timestamp } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import { roleNameEnum } from "./enums";
|
||||
|
||||
export const protectedRoutes = pgTable("protected_routes", {
|
||||
path: varchar("path", { length: 255 }).primaryKey(), // /auth/register-user
|
||||
methods: varchar("methods", { length: 50 })
|
||||
.array()
|
||||
.notNull()
|
||||
.default([]), // Массив: ["GET", "POST", "PUT", "DELETE", "PATCH"]
|
||||
roles: roleNameEnum("roles")
|
||||
.array()
|
||||
.notNull()
|
||||
.default([]), // Массив: ["admin", "director", "manager"]
|
||||
description: text("description"), // Описание маршрута
|
||||
createdAt: timestamp("created_at", { withTimezone: true })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
updatedAt: timestamp("updated_at", { withTimezone: true })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
});
|
||||
|
||||
// Zod schemas for validation
|
||||
export const insertProtectedRouteSchema = createInsertSchema(protectedRoutes);
|
||||
export const selectProtectedRouteSchema = createSelectSchema(protectedRoutes);
|
||||
|
||||
// Type exports
|
||||
export type ProtectedRoute = typeof protectedRoutes.$inferSelect;
|
||||
export type NewProtectedRoute = typeof protectedRoutes.$inferInsert;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { pgTable, uuid, integer, timestamp, pgEnum } from "drizzle-orm/pg-core";
|
||||
import { streamServers } from "./streamServers";
|
||||
import { localServers } from "./localServers";
|
||||
import { apps } from "./apps";
|
||||
import { users } from "./users";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
|
||||
// Enums
|
||||
export const sessionModeEnum = pgEnum("session_mode", ["stream", "local"]);
|
||||
|
||||
export const serverSessions = pgTable("server_sessions", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
serverId: uuid("server_id").notNull(),
|
||||
appId: uuid("app_id")
|
||||
.notNull()
|
||||
.references(() => apps.id),
|
||||
userId: uuid("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id),
|
||||
startAt: timestamp("start_at").defaultNow().notNull(),
|
||||
endAt: timestamp("end_at"), // Default 30 minutes from start_at
|
||||
appPid: integer("app_pid"),
|
||||
cirrusPid: integer("cirrus_pid"),
|
||||
mode: sessionModeEnum("mode").notNull(), // stream, local
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
// Relations
|
||||
export const serverSessionsRelations = relations(serverSessions, ({ one }) => ({
|
||||
app: one(apps, {
|
||||
fields: [serverSessions.appId],
|
||||
references: [apps.id],
|
||||
}),
|
||||
user: one(users, {
|
||||
fields: [serverSessions.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
// Полиморфная реляция для serverId
|
||||
// В зависимости от mode, serverId может ссылаться на stream_servers или local_servers
|
||||
streamServer: one(streamServers, {
|
||||
fields: [serverSessions.serverId],
|
||||
references: [streamServers.id],
|
||||
relationName: "session_stream_server",
|
||||
}),
|
||||
localServer: one(localServers, {
|
||||
fields: [serverSessions.serverId],
|
||||
references: [localServers.id],
|
||||
relationName: "session_local_server",
|
||||
}),
|
||||
}));
|
||||
|
||||
// Zod schemas for validation
|
||||
export const insertServerSessionSchema = createInsertSchema(serverSessions);
|
||||
export const selectServerSessionSchema = createSelectSchema(serverSessions);
|
||||
|
||||
// Type exports
|
||||
export type ServerSession = typeof serverSessions.$inferSelect;
|
||||
export type NewServerSession = typeof serverSessions.$inferInsert;
|
||||
@@ -0,0 +1,31 @@
|
||||
import { pgTable, uuid, varchar, pgEnum } from "drizzle-orm/pg-core";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import { serverSessions } from "./serverSessions";
|
||||
|
||||
// Enums
|
||||
export const serverLocationEnum = pgEnum("server_location", ["ru1", "uae1"]);
|
||||
export const serverTypeEnum = pgEnum("server_type", ["demo", "prod"]);
|
||||
|
||||
export const streamServers = pgTable("stream_servers", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
localIp: varchar("local_ip", { length: 45 }).notNull(), // IPv6 can be up to 45 chars
|
||||
hostname: varchar("hostname", { length: 255 }).notNull(),
|
||||
location: serverLocationEnum("location").notNull(),
|
||||
type: serverTypeEnum("type").notNull(),
|
||||
});
|
||||
|
||||
// Zod schemas for validation
|
||||
export const insertStreamServerSchema = createInsertSchema(streamServers);
|
||||
export const selectStreamServerSchema = createSelectSchema(streamServers);
|
||||
|
||||
// Relations
|
||||
export const streamServersRelations = relations(streamServers, ({ many }) => ({
|
||||
serverSessions: many(serverSessions, {
|
||||
relationName: "session_stream_server",
|
||||
}),
|
||||
}));
|
||||
|
||||
// Type exports
|
||||
export type StreamServer = typeof streamServers.$inferSelect;
|
||||
export type NewStreamServer = typeof streamServers.$inferInsert;
|
||||
@@ -0,0 +1,34 @@
|
||||
import { pgTable, uuid, varchar, timestamp } from "drizzle-orm/pg-core";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import { roleNameEnum } from "./enums";
|
||||
import { serverSessions } from "./serverSessions";
|
||||
import { authSessions } from "./authSessions";
|
||||
|
||||
export const users = pgTable("users", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
email: varchar("email", { length: 255 }).notNull().unique(),
|
||||
password: varchar("password", { length: 255 }).notNull(), // scrypt hash
|
||||
fullName: varchar("full_name", { length: 255 }).notNull(), // ФИО
|
||||
role: roleNameEnum("role").notNull().default("manager"),
|
||||
createdAt: timestamp("created_at", { withTimezone: true })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
updatedAt: timestamp("updated_at", { withTimezone: true })
|
||||
.defaultNow()
|
||||
.notNull(),
|
||||
});
|
||||
|
||||
// Zod schemas for validation
|
||||
export const insertUserSchema = createInsertSchema(users);
|
||||
export const selectUserSchema = createSelectSchema(users);
|
||||
|
||||
// Relations
|
||||
export const usersRelations = relations(users, ({ many }) => ({
|
||||
serverSessions: many(serverSessions),
|
||||
authSessions: many(authSessions),
|
||||
}));
|
||||
|
||||
// Type exports
|
||||
export type User = typeof users.$inferSelect;
|
||||
export type NewUser = typeof users.$inferInsert;
|
||||
Reference in New Issue
Block a user