Refactor app management to use Drizzle ORM

- Replaced Sequelize models with Drizzle ORM for app and app list management.
- Updated routes in app-manager to utilize new database queries.
- Removed obsolete Sequelize model files for app, app list, and app domain.
- Introduced new helper functions for app and app domain management.
- Enhanced user app management with improved file handling and user migration.
- Adjusted public API routes to align with new database structure.
- Implemented caching mechanisms for domain management.
This commit is contained in:
2026-02-07 01:26:16 +08:00
parent d62a75842f
commit 7dfa96d165
40 changed files with 1066 additions and 1171 deletions

View File

@@ -1,20 +1,35 @@
import { DataTypes, Model, Op, Sequelize } from 'sequelize';
import { useContextKey } from '@kevisual/context';
import { SyncOpts, User } from './user.ts';
import { User } from './user.ts';
import { db } from '../../modules/db.ts';
import { cfOrgs, cfUser } from '../../db/drizzle/schema.ts';
import { eq, inArray, sql, InferSelectModel, InferInsertModel } from 'drizzle-orm';
const orgsTable = cfOrgs;
const usersTable = cfUser;
type AddUserOpts = {
role: string;
};
export enum OrgRole {
admin = 'admin',
member = 'member',
owner = 'owner',
}
export class Org extends Model {
declare id: string;
declare username: string;
declare description: string;
declare users: { role: string; uid: string }[];
export type OrgUser = {
role: string;
uid: string;
};
export type OrgSelect = InferSelectModel<typeof cfOrgs>;
export type OrgInsert = InferInsertModel<typeof cfOrgs>;
export class Org {
id: string;
username: string;
description: string;
users: OrgUser[];
constructor(data: OrgSelect) {
Object.assign(this, data);
}
/**
* operateId 是真实操作者的id
* @param user
@@ -67,8 +82,8 @@ export class Org extends Model {
} else {
users.push({ role: opts?.role || 'member', uid: user.id });
}
await Org.update({ users }, { where: { id: this.id } });
await db.update(orgsTable).set({ users }).where(eq(orgsTable.id, this.id));
this.users = users;
}
/**
* operateId 是真实操作者的id
@@ -89,7 +104,8 @@ export class Org extends Model {
}
await user.expireOrgs();
const users = this.users.filter((u) => u.uid !== user.id || u.role === 'owner');
await Org.update({ users }, { where: { id: this.id } });
await db.update(orgsTable).set({ users }).where(eq(orgsTable.id, this.id));
this.users = users;
}
/**
* operateId 是真实操作者的id
@@ -112,13 +128,7 @@ export class Org extends Model {
}
}
}
const _users = await User.findAll({
where: {
id: {
[Op.in]: usersIds,
},
},
});
const _users = await db.select().from(usersTable).where(inArray(usersTable.id, usersIds));
const users = _users.map((u) => {
const role = orgUser.find((r) => r.uid === u.id)?.role;
@@ -139,46 +149,45 @@ export class Org extends Model {
const user = this.users.find((u) => u.uid === userId && u.role === role);
return !!user;
}
}
/**
* 组织模型在sequelize之后初始化
*/
export const OrgInit = async (newSequelize?: any, tableName?: string, sync?: SyncOpts) => {
const sequelize = useContextKey<Sequelize>('sequelize');
Org.init(
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
username: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
description: {
type: DataTypes.STRING,
allowNull: true,
},
users: {
type: DataTypes.JSONB,
allowNull: true,
defaultValue: [],
},
},
{
sequelize: newSequelize || sequelize,
modelName: tableName || 'cf_org',
paranoid: true,
},
);
if (sync) {
await Org.sync({ alter: true, logging: false, ...sync }).catch((e) => {
console.error('Org sync', e);
});
return Org;
/**
* 根据主键查找
*/
static async findByPk(id: string): Promise<Org | null> {
const orgs = await db.select().from(orgsTable).where(eq(orgsTable.id, id)).limit(1);
return orgs.length > 0 ? new Org(orgs[0]) : null;
}
return Org;
};
/**
* 根据条件查找一个
*/
static async findOne(where: { username?: string; id?: string }): Promise<Org | null> {
let query = db.select().from(orgsTable);
if (where.username) {
query = query.where(eq(orgsTable.username, where.username)) as any;
} else if (where.id) {
query = query.where(eq(orgsTable.id, where.id)) as any;
}
const orgs = await query.limit(1);
return orgs.length > 0 ? new Org(orgs[0]) : null;
}
/**
* 创建组织
*/
static async create(data: { username: string; description?: string; users: OrgUser[] }): Promise<Org> {
const inserted = await db.insert(orgsTable).values(data).returning();
return new Org(inserted[0]);
}
/**
* 更新组织
*/
static async update(data: Partial<OrgInsert>, where: { id: string }) {
await db.update(orgsTable).set(data).where(eq(orgsTable.id, where.id));
}
}
export const OrgModel = useContextKey('OrgModel', () => Org);