feat: add local access control and managed point clouds
This commit is contained in:
22
drizzle/0015_local_users_and_roles.sql
Normal file
22
drizzle/0015_local_users_and_roles.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
ALTER TABLE `users`
|
||||
MODIFY COLUMN `role` ENUM('user', 'admin', 'super_admin') NOT NULL DEFAULT 'user',
|
||||
ADD COLUMN `username` VARCHAR(64) NULL AFTER `id`,
|
||||
ADD COLUMN `passwordHash` VARCHAR(255) NULL AFTER `username`,
|
||||
ADD COLUMN `isActive` INT NOT NULL DEFAULT 0 AFTER `role`,
|
||||
ADD COLUMN `mustChangePassword` INT NOT NULL DEFAULT 1 AFTER `isActive`,
|
||||
ADD COLUMN `sessionVersion` INT NOT NULL DEFAULT 0 AFTER `mustChangePassword`,
|
||||
ADD COLUMN `lastLoginAt` TIMESTAMP NULL AFTER `updatedAt`;
|
||||
|
||||
UPDATE `users`
|
||||
SET `username` = CONCAT('legacy_user_', `id`),
|
||||
`isActive` = 0,
|
||||
`mustChangePassword` = 1,
|
||||
`sessionVersion` = `sessionVersion` + 1;
|
||||
|
||||
ALTER TABLE `users`
|
||||
MODIFY COLUMN `username` VARCHAR(64) NOT NULL,
|
||||
ADD UNIQUE INDEX `users_username_unique` (`username`),
|
||||
DROP INDEX `users_openId_unique`,
|
||||
DROP COLUMN `openId`,
|
||||
DROP COLUMN `loginMethod`,
|
||||
DROP COLUMN `lastSignedIn`;
|
||||
15
drizzle/0016_pointcloud_metadata.sql
Normal file
15
drizzle/0016_pointcloud_metadata.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
ALTER TABLE `model_pointcloud_files`
|
||||
ADD COLUMN `metadataStatus` enum('pending','ready','unsupported','error') NOT NULL DEFAULT 'pending',
|
||||
ADD COLUMN `pointCount` bigint NULL,
|
||||
ADD COLUMN `pointAttributes` json NULL,
|
||||
ADD COLUMN `pointDataFormat` varchar(32) NULL,
|
||||
ADD COLUMN `bytesPerPoint` int NULL,
|
||||
ADD COLUMN `metadataError` text NULL;
|
||||
|
||||
ALTER TABLE `task_pointcloud_files`
|
||||
ADD COLUMN `metadataStatus` enum('pending','ready','unsupported','error') NOT NULL DEFAULT 'pending',
|
||||
ADD COLUMN `pointCount` bigint NULL,
|
||||
ADD COLUMN `pointAttributes` json NULL,
|
||||
ADD COLUMN `pointDataFormat` varchar(32) NULL,
|
||||
ADD COLUMN `bytesPerPoint` int NULL,
|
||||
ADD COLUMN `metadataError` text NULL;
|
||||
@@ -1,17 +1,21 @@
|
||||
import { int, mysqlEnum, mysqlTable, text, timestamp, varchar, bigint, json, uniqueIndex } from "drizzle-orm/mysql-core";
|
||||
import type { PointAttribute } from "../shared/pointcloudMetadata";
|
||||
|
||||
// ─── 用户表(保持不变) ────────────────────────────────────────────────────────
|
||||
// ─── 本地用户 ──────────────────────────────────────────────────────────────────
|
||||
|
||||
export const users = mysqlTable("users", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
openId: varchar("openId", { length: 64 }).notNull().unique(),
|
||||
username: varchar("username", { length: 64 }).notNull().unique(),
|
||||
passwordHash: varchar("passwordHash", { length: 255 }),
|
||||
name: text("name"),
|
||||
email: varchar("email", { length: 320 }),
|
||||
loginMethod: varchar("loginMethod", { length: 64 }),
|
||||
role: mysqlEnum("role", ["user", "admin"]).default("user").notNull(),
|
||||
role: mysqlEnum("role", ["user", "admin", "super_admin"]).default("user").notNull(),
|
||||
isActive: int("isActive").default(1).notNull(),
|
||||
mustChangePassword: int("mustChangePassword").default(1).notNull(),
|
||||
sessionVersion: int("sessionVersion").default(0).notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
|
||||
lastSignedIn: timestamp("lastSignedIn").defaultNow().notNull(),
|
||||
lastLoginAt: timestamp("lastLoginAt"),
|
||||
});
|
||||
|
||||
export type User = typeof users.$inferSelect;
|
||||
@@ -71,6 +75,12 @@ export const modelPointcloudFiles = mysqlTable("model_pointcloud_files", {
|
||||
name: varchar("name", { length: 255 }).notNull(),
|
||||
fileSize: bigint("fileSize", { mode: "number" }).notNull(),
|
||||
filePath: varchar("filePath", { length: 512 }).notNull(),
|
||||
metadataStatus: mysqlEnum("metadataStatus", ["pending", "ready", "unsupported", "error"]).default("pending").notNull(),
|
||||
pointCount: bigint("pointCount", { mode: "number" }),
|
||||
pointAttributes: json("pointAttributes").$type<PointAttribute[]>(),
|
||||
pointDataFormat: varchar("pointDataFormat", { length: 32 }),
|
||||
bytesPerPoint: int("bytesPerPoint"),
|
||||
metadataError: text("metadataError"),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
@@ -136,6 +146,12 @@ export const taskPointcloudFiles = mysqlTable("task_pointcloud_files", {
|
||||
sourcePointcloudFileId: int("sourcePointcloudFileId"),
|
||||
/** 来源车型点云文件 ID(仅 model_library 时有值) */
|
||||
sourceModelPointcloudId: int("sourceModelPointcloudId"),
|
||||
metadataStatus: mysqlEnum("metadataStatus", ["pending", "ready", "unsupported", "error"]).default("pending").notNull(),
|
||||
pointCount: bigint("pointCount", { mode: "number" }),
|
||||
pointAttributes: json("pointAttributes").$type<PointAttribute[]>(),
|
||||
pointDataFormat: varchar("pointDataFormat", { length: 32 }),
|
||||
bytesPerPoint: int("bytesPerPoint"),
|
||||
metadataError: text("metadataError"),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user