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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user