feat(server): add doc meta for ignored docs (#12021)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Ignored documents in workspace embedding now display additional metadata, including document title, creation and update timestamps, and the names and avatars of users who created or updated the document.
- **Enhancements**
  - The list of ignored documents provides richer information for easier identification and management within the workspace.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
darkskygit
2025-04-28 11:56:09 +00:00
parent 9d21d13a5e
commit 21dc550b9d
8 changed files with 111 additions and 4 deletions

View File

@@ -120,3 +120,15 @@ export type CopilotWorkspaceFile = CopilotWorkspaceFileMetadata & {
fileId: string;
createdAt: Date;
};
export type IgnoredDoc = {
docId: string;
createdAt: Date;
// metadata
docCreatedAt: Date | undefined;
docUpdatedAt: Date | undefined;
title: string | undefined;
createdBy: string | undefined;
createdByAvatar: string | undefined;
updatedBy: string | undefined;
};

View File

@@ -11,6 +11,7 @@ import type {
CopilotWorkspaceFileMetadata,
Embedding,
FileChunkSimilarity,
IgnoredDoc,
} from './common';
@Injectable()
@@ -50,12 +51,13 @@ export class CopilotWorkspaceConfigModel extends BaseModel {
return added.length + ignored.size;
}
@Transactional()
async listIgnoredDocs(
workspaceId: string,
options?: {
includeRead?: boolean;
} & PaginationInput
): Promise<{ docId: string; createdAt: Date }[]> {
): Promise<IgnoredDoc[]> {
const row = await this.db.aiWorkspaceIgnoredDocs.findMany({
where: {
workspaceId,
@@ -68,7 +70,29 @@ export class CopilotWorkspaceConfigModel extends BaseModel {
skip: options?.offset,
take: options?.first,
});
return row;
const ids = row.map(r => ({ workspaceId, docId: r.docId }));
const docs = await this.models.doc.findMetas(ids);
const docsMap = new Map(
docs.filter(r => !!r).map(r => [`${r.workspaceId}-${r.docId}`, r])
);
const authors = await this.models.doc.findAuthors(ids);
const authorsMap = new Map(
authors.filter(r => !!r).map(r => [`${r.workspaceId}-${r.id}`, r])
);
return row.map(r => {
const docMeta = docsMap.get(`${workspaceId}-${r.docId}`);
const docAuthor = authorsMap.get(`${workspaceId}-${r.docId}`);
return {
...r,
docCreatedAt: docAuthor?.createdAt,
docUpdatedAt: docAuthor?.updatedAt,
title: docMeta?.title || undefined,
createdBy: docAuthor?.createdByUser?.name,
createdByAvatar: docAuthor?.createdByUser?.avatarUrl || undefined,
updatedBy: docAuthor?.updatedByUser?.name,
};
});
}
async countIgnoredDocs(workspaceId: string): Promise<number> {

View File

@@ -373,6 +373,29 @@ export class DocModel extends BaseModel {
});
}
async findAuthors(ids: { workspaceId: string; docId: string }[]) {
const rows = await this.db.snapshot.findMany({
where: {
workspaceId: { in: ids.map(id => id.workspaceId) },
id: { in: ids.map(id => id.docId) },
},
select: {
workspaceId: true,
id: true,
createdAt: true,
updatedAt: true,
createdByUser: { select: publicUserSelect },
updatedByUser: { select: publicUserSelect },
},
});
const resultMap = new Map(
rows.map(row => [`${row.workspaceId}-${row.id}`, row])
);
return ids.map(
id => resultMap.get(`${id.workspaceId}-${id.docId}`) ?? null
);
}
async findMetas(ids: { workspaceId: string; docId: string }[]) {
const rows = await this.db.workspaceDoc.findMany({
where: {

View File

@@ -2,7 +2,7 @@ import { Field, ObjectType } from '@nestjs/graphql';
import { SafeIntResolver } from 'graphql-scalars';
import { Paginated } from '../../../base';
import { CopilotWorkspaceFile } from '../../../models';
import { CopilotWorkspaceFile, IgnoredDoc } from '../../../models';
declare global {
interface Events {
@@ -16,12 +16,30 @@ declare global {
}
@ObjectType('CopilotWorkspaceIgnoredDoc')
export class CopilotWorkspaceIgnoredDocType {
export class CopilotWorkspaceIgnoredDocType implements IgnoredDoc {
@Field(() => String)
docId!: string;
@Field(() => Date)
createdAt!: Date;
@Field(() => Date, { nullable: true })
docCreatedAt!: Date | undefined;
@Field(() => Date, { nullable: true })
docUpdatedAt!: Date | undefined;
@Field(() => String, { nullable: true })
title!: string | undefined;
@Field(() => String, { nullable: true })
createdBy!: string | undefined;
@Field(() => String, { nullable: true })
createdByAvatar!: string | undefined;
@Field(() => String, { nullable: true })
updatedBy!: string | undefined;
}
@ObjectType()

View File

@@ -295,7 +295,13 @@ type CopilotWorkspaceFileTypeEdge {
type CopilotWorkspaceIgnoredDoc {
createdAt: DateTime!
createdBy: String
createdByAvatar: String
docCreatedAt: DateTime
docId: String!
docUpdatedAt: DateTime
title: String
updatedBy: String
}
type CopilotWorkspaceIgnoredDocTypeEdge {