From 3207d1440388c1a66460a16f98a627db05996739 Mon Sep 17 00:00:00 2001 From: YuTengjing Date: Tue, 17 Mar 2026 18:20:03 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A8=20chore:=20add=20batch=20query=20m?= =?UTF-8?q?ethods=20for=20UserModel=20and=20MessageModel=20(#13060)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/db-migrations/SKILL.md | 2 +- .agents/skills/pr/SKILL.md | 1 - .github/CODEOWNERS | 3 +++ AGENTS.md | 1 - CLAUDE.md | 1 - GEMINI.md | 1 - packages/database/src/models/message.ts | 16 ++++++++++++++++ packages/database/src/models/user.ts | 5 +++++ 8 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 .github/CODEOWNERS diff --git a/.agents/skills/db-migrations/SKILL.md b/.agents/skills/db-migrations/SKILL.md index 55b4ef8b71..ee3589fb6a 100644 --- a/.agents/skills/db-migrations/SKILL.md +++ b/.agents/skills/db-migrations/SKILL.md @@ -1,6 +1,6 @@ --- name: db-migrations -description: Database migration guide. Use when generating migrations, writing migration SQL, or modifying database schemas. Triggers on migration generation, schema changes, or idempotent SQL questions. +description: Database migration guide (Drizzle ORM + PostgreSQL). MUST USE when any of these occur: (1) generating or regenerating migration files (drizzle-kit generate), (2) adding/removing/modifying columns or tables in database schema, (3) resolving migration sequence conflicts after rebase, (4) writing or reviewing migration SQL (idempotent patterns), (5) renaming migration files. Triggers on keywords: migration, db:generate, ALTER TABLE, ADD COLUMN, CREATE TABLE, schema change, migration conflict. --- # Database Migrations Guide diff --git a/.agents/skills/pr/SKILL.md b/.agents/skills/pr/SKILL.md index 41e98a13cc..07f9d452af 100644 --- a/.agents/skills/pr/SKILL.md +++ b/.agents/skills/pr/SKILL.md @@ -69,6 +69,5 @@ Use `.github/PULL_REQUEST_TEMPLATE.md` as the body structure. Key sections: ## Notes -- **Release impact**: PR titles with `✨ feat/` or `🐛 fix` trigger releases — use carefully - **Language**: All PR content must be in English - If a PR already exists for the branch, inform the user instead of creating a duplicate diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..4e415e22ee --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# Database migrations require approval from core maintainers + +/packages/database/migrations/ @arvinxx @nekomeowww @tjx666 diff --git a/AGENTS.md b/AGENTS.md index 11eda18068..64b0ced619 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -47,7 +47,6 @@ lobehub/ - Git commit messages should prefix with gitmoji - Git branch name format: `username/feat/feature-name` - Use `.github/PULL_REQUEST_TEMPLATE.md` for PR descriptions -- PR titles with `✨ feat/` or `🐛 fix` trigger releases ### Package Management diff --git a/CLAUDE.md b/CLAUDE.md index 025c2711b3..aea2d0e54a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -90,7 +90,6 @@ Open this URL to develop locally against the production backend (app.lobehub.com - Use rebase for `git pull` - Commit messages: prefix with gitmoji - Branch format: `/` -- PR titles with `✨ feat/` or `🐛 fix` trigger releases ### Package Management diff --git a/GEMINI.md b/GEMINI.md index 7cdcffae2a..191f16e013 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -38,7 +38,6 @@ lobehub/ - Use rebase for `git pull` - Commit messages: prefix with gitmoji - Branch format: `/` -- PR titles with `✨ feat/` or `🐛 fix` trigger releases ### Package Management diff --git a/packages/database/src/models/message.ts b/packages/database/src/models/message.ts index 5b69278905..85d3249a62 100644 --- a/packages/database/src/models/message.ts +++ b/packages/database/src/models/message.ts @@ -1841,4 +1841,20 @@ export class MessageModel { if (!!threadId) return eq(messages.threadId, threadId); return isNull(messages.threadId); }; + + /** + * Check which user IDs from the given list have at least one message. + */ + static checkUsersHaveMessages = async ( + db: LobeChatDatabase, + userIds: string[], + ): Promise> => { + if (userIds.length === 0) return new Set(); + const result = await db + .select({ userId: messages.userId }) + .from(messages) + .where(inArray(messages.userId, userIds)) + .groupBy(messages.userId); + return new Set(result.map((r) => r.userId)); + }; } diff --git a/packages/database/src/models/user.ts b/packages/database/src/models/user.ts index 9915458ea3..6be739e3f4 100644 --- a/packages/database/src/models/user.ts +++ b/packages/database/src/models/user.ts @@ -294,6 +294,11 @@ export class UserModel { return db.query.users.findFirst({ where: eq(users.email, email) }); }; + static findByIds = async (db: LobeChatDatabase, ids: string[]) => { + if (ids.length === 0) return []; + return db.query.users.findMany({ where: inArray(users.id, ids) }); + }; + static getUserApiKeys = async ( db: LobeChatDatabase, id: string,