|
|
@@ -11,9 +11,9 @@ import { I18nService } from '../i18n/i18n.service';
|
|
|
|
|
|
@Injectable()
|
|
|
export class NoteService {
|
|
|
- // Directory will be created dynamically per tenant
|
|
|
- private getScreenshotsDir(tenantId: string) {
|
|
|
- return path.join(process.cwd(), 'uploads', tenantId, 'notes-screenshots');
|
|
|
+ // Directory will be created dynamically per user
|
|
|
+ private getScreenshotsDir(userId: string) {
|
|
|
+ return path.join(process.cwd(), 'uploads', 'notes-screenshots', userId);
|
|
|
}
|
|
|
|
|
|
constructor(
|
|
|
@@ -23,8 +23,8 @@ export class NoteService {
|
|
|
private readonly i18nService: I18nService,
|
|
|
) {}
|
|
|
|
|
|
- private async ensureScreenshotsDir(tenantId: string) {
|
|
|
- const dir = this.getScreenshotsDir(tenantId);
|
|
|
+ private async ensureScreenshotsDir(userId: string) {
|
|
|
+ const dir = this.getScreenshotsDir(userId);
|
|
|
try {
|
|
|
await fs.access(dir);
|
|
|
} catch {
|
|
|
@@ -34,7 +34,6 @@ export class NoteService {
|
|
|
|
|
|
async create(
|
|
|
userId: string,
|
|
|
- tenantId: string,
|
|
|
data: Partial<Note>,
|
|
|
): Promise<Note> {
|
|
|
// Handle empty strings for foreign keys
|
|
|
@@ -48,27 +47,22 @@ export class NoteService {
|
|
|
const note = this.noteRepository.create({
|
|
|
...data,
|
|
|
userId,
|
|
|
- tenantId,
|
|
|
});
|
|
|
return this.noteRepository.save(note);
|
|
|
}
|
|
|
|
|
|
async findAll(
|
|
|
userId: string,
|
|
|
- tenantId: string,
|
|
|
isAdmin: boolean,
|
|
|
groupId?: string,
|
|
|
categoryId?: string,
|
|
|
): Promise<Note[]> {
|
|
|
const query = this.noteRepository
|
|
|
.createQueryBuilder('note')
|
|
|
- .leftJoinAndSelect('note.user', 'user')
|
|
|
- .where('note.tenantId = :tenantId', { tenantId })
|
|
|
- .select(['note', 'user.id', 'user.username'])
|
|
|
- .orderBy('note.updatedAt', 'DESC');
|
|
|
+ .leftJoinAndSelect('note.user', 'user');
|
|
|
|
|
|
if (!isAdmin) {
|
|
|
- query.andWhere('note.userId = :userId', { userId });
|
|
|
+ query.where('note.userId = :userId', { userId });
|
|
|
}
|
|
|
|
|
|
if (groupId) {
|
|
|
@@ -84,19 +78,18 @@ export class NoteService {
|
|
|
|
|
|
async findOne(
|
|
|
userId: string,
|
|
|
- tenantId: string,
|
|
|
id: string,
|
|
|
isAdmin: boolean,
|
|
|
): Promise<Note> {
|
|
|
let note;
|
|
|
if (isAdmin) {
|
|
|
note = await this.noteRepository.findOne({
|
|
|
- where: { id, tenantId },
|
|
|
+ where: { id },
|
|
|
relations: ['user'],
|
|
|
});
|
|
|
} else {
|
|
|
note = await this.noteRepository.findOne({
|
|
|
- where: { id, userId, tenantId },
|
|
|
+ where: { id, userId },
|
|
|
relations: ['user'],
|
|
|
});
|
|
|
}
|
|
|
@@ -111,12 +104,11 @@ export class NoteService {
|
|
|
|
|
|
async update(
|
|
|
userId: string,
|
|
|
- tenantId: string,
|
|
|
id: string,
|
|
|
data: Partial<Note>,
|
|
|
isAdmin: boolean,
|
|
|
): Promise<Note> {
|
|
|
- const note = await this.findOne(userId, tenantId, id, isAdmin);
|
|
|
+ const note = await this.findOne(userId, id, isAdmin);
|
|
|
// Remove protected fields
|
|
|
delete (data as any).id;
|
|
|
delete (data as any).userId;
|
|
|
@@ -136,10 +128,10 @@ export class NoteService {
|
|
|
|
|
|
async createFromPDFSelection(
|
|
|
userId: string,
|
|
|
- tenantId: string,
|
|
|
fileId: string,
|
|
|
screenshot: Express.Multer.File,
|
|
|
groupId?: string,
|
|
|
+ categoryId?: string,
|
|
|
pageNumber?: number,
|
|
|
): Promise<Note> {
|
|
|
// If groupId is provided, verify that the group exists
|
|
|
@@ -149,7 +141,7 @@ export class NoteService {
|
|
|
const groupRepo =
|
|
|
this.noteRepository.manager.getRepository(KnowledgeGroup);
|
|
|
const group = await groupRepo.findOne({
|
|
|
- where: { id: groupId, tenantId },
|
|
|
+ where: { id: groupId },
|
|
|
});
|
|
|
|
|
|
if (!group) {
|
|
|
@@ -164,11 +156,15 @@ export class NoteService {
|
|
|
console.log(`User ${userId} attempting to add note to group ${groupId}`);
|
|
|
}
|
|
|
|
|
|
+ if (categoryId === '') {
|
|
|
+ categoryId = null as any;
|
|
|
+ }
|
|
|
+
|
|
|
// Save screenshot to disk
|
|
|
- await this.ensureScreenshotsDir(tenantId);
|
|
|
+ await this.ensureScreenshotsDir(userId);
|
|
|
const filename = `${uuidv4()}-${Date.now()}.png`;
|
|
|
const screenshotPath = path.join(
|
|
|
- this.getScreenshotsDir(tenantId),
|
|
|
+ this.getScreenshotsDir(userId),
|
|
|
filename,
|
|
|
);
|
|
|
await fs.writeFile(screenshotPath, screenshot.buffer);
|
|
|
@@ -188,14 +184,14 @@ export class NoteService {
|
|
|
const note = this.noteRepository.create({
|
|
|
userId,
|
|
|
groupId: groupId || (null as any),
|
|
|
+ categoryId: categoryId || (null as any),
|
|
|
title: this.i18nService.formatMessage('pdfNoteTitle', {
|
|
|
date: new Date().toLocaleString(),
|
|
|
}),
|
|
|
content: extractedText || this.i18nService.getMessage('noTextExtracted'),
|
|
|
- screenshotPath: `${tenantId}/notes-screenshots/${filename}`,
|
|
|
+ screenshotPath: `notes-screenshots/${userId}/${filename}`,
|
|
|
sourceFileId: fileId,
|
|
|
sourcePageNumber: pageNumber,
|
|
|
- tenantId,
|
|
|
});
|
|
|
|
|
|
return this.noteRepository.save(note);
|
|
|
@@ -203,15 +199,14 @@ export class NoteService {
|
|
|
|
|
|
async remove(
|
|
|
userId: string,
|
|
|
- tenantId: string,
|
|
|
id: string,
|
|
|
isAdmin: boolean,
|
|
|
): Promise<void> {
|
|
|
let result;
|
|
|
if (isAdmin) {
|
|
|
- result = await this.noteRepository.delete({ id, tenantId });
|
|
|
+ result = await this.noteRepository.delete({ id });
|
|
|
} else {
|
|
|
- result = await this.noteRepository.delete({ id, userId, tenantId });
|
|
|
+ result = await this.noteRepository.delete({ id, userId });
|
|
|
}
|
|
|
|
|
|
if (result.affected === 0) {
|