#### PR Dependency Tree * **PR #15448** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added workspace artifact upload, browsing, removal, deduplication, and library ownership support. * Copilot now supports scoped document and artifact search, canvas reading, live editor context, and frontend tools. * Added scope and focus selectors with source-resolution receipts in chat. * Added embedding health, progress, synchronization, and retrieval capabilities. * Added BYOK policy visibility, provider restrictions, endpoint dialect selection, and validation. * Added delegated editor interactions and userdata document authorization. * **Bug Fixes** * Improved attachment handling, cancellation, access control, retrieval fallbacks, workspace synchronization, and configuration validation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { Transactional } from '@nestjs-cls/transactional';
|
|
|
|
import { PaginationInput } from '../base';
|
|
import { BaseModel } from './base';
|
|
import type { IgnoredDoc } from './common';
|
|
|
|
@Injectable()
|
|
export class CopilotWorkspaceConfigModel extends BaseModel {
|
|
@Transactional()
|
|
private async listIgnoredDocIds(
|
|
workspaceId: string,
|
|
options?: PaginationInput
|
|
) {
|
|
return await this.db.aiWorkspaceIgnoredDocs.findMany({
|
|
where: { workspaceId },
|
|
select: { docId: true, createdAt: true },
|
|
orderBy: { createdAt: 'desc' },
|
|
skip: options?.offset,
|
|
take: options?.first,
|
|
});
|
|
}
|
|
|
|
@Transactional()
|
|
async updateIgnoredDocs(
|
|
workspaceId: string,
|
|
add: string[] = [],
|
|
remove: string[] = []
|
|
) {
|
|
const removed = new Set(remove);
|
|
const ignored = await this.listIgnoredDocIds(workspaceId).then(
|
|
rows => new Set(rows.map(row => row.docId).filter(id => !removed.has(id)))
|
|
);
|
|
const added = add.filter(id => !ignored.has(id));
|
|
const { count: addedCount } =
|
|
await this.db.aiWorkspaceIgnoredDocs.createMany({
|
|
data: added.map(docId => ({ workspaceId, docId })),
|
|
});
|
|
const { count: removedCount } =
|
|
await this.db.aiWorkspaceIgnoredDocs.deleteMany({
|
|
where: { workspaceId, docId: { in: Array.from(removed) } },
|
|
});
|
|
return addedCount + removedCount;
|
|
}
|
|
|
|
@Transactional()
|
|
async listIgnoredDocs(
|
|
workspaceId: string,
|
|
options?: PaginationInput
|
|
): Promise<IgnoredDoc[]> {
|
|
const rows = await this.listIgnoredDocIds(workspaceId, options);
|
|
const ids = rows.map(row => ({ workspaceId, docId: row.docId }));
|
|
const docs = await this.models.doc.findMetas(ids);
|
|
const docsMap = new Map(
|
|
docs.flatMap(doc =>
|
|
doc ? [[`${doc.workspaceId}-${doc.docId}`, doc] as const] : []
|
|
)
|
|
);
|
|
const authors = await this.models.doc.findAuthors(ids);
|
|
const authorsMap = new Map(
|
|
authors.flatMap(author =>
|
|
author ? [[`${author.workspaceId}-${author.id}`, author] as const] : []
|
|
)
|
|
);
|
|
return rows.map(row => {
|
|
const docMeta = docsMap.get(`${workspaceId}-${row.docId}`);
|
|
const docAuthor = authorsMap.get(`${workspaceId}-${row.docId}`);
|
|
return {
|
|
...row,
|
|
docCreatedAt: docAuthor?.createdAt,
|
|
docUpdatedAt: docAuthor?.updatedAt,
|
|
title: docMeta?.title || undefined,
|
|
createdBy: docAuthor?.createdByUser?.name,
|
|
createdByAvatar: docAuthor?.createdByUser?.avatarUrl || undefined,
|
|
updatedBy: docAuthor?.updatedByUser?.name,
|
|
};
|
|
});
|
|
}
|
|
|
|
@Transactional()
|
|
async countIgnoredDocs(workspaceId: string): Promise<number> {
|
|
return await this.db.aiWorkspaceIgnoredDocs.count({
|
|
where: { workspaceId },
|
|
});
|
|
}
|
|
|
|
@Transactional()
|
|
async checkIgnoredDocs(workspaceId: string, docIds: string[]) {
|
|
const ignored = await this.listIgnoredDocIds(workspaceId).then(
|
|
rows => new Set(rows.map(row => row.docId))
|
|
);
|
|
return docIds.filter(id => ignored.has(id));
|
|
}
|
|
}
|