clients page

This commit is contained in:
Dimitar765 committed 2024-10-29 06:47:15 +01:00
1 parent 3d2b0a5d6d
commit 1a7f2afd79
20 files changed
+458 -402

No files matched your search

@@ -4,22 +4,21 @@ import {
Post,
Body,
Param,
Delete,
Put,
UseInterceptors,
UploadedFile,
ParseIntPipe,
UseGuards,
Request,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { AdminService } from './admin.service';
import { CreateDocumentDto } from '../dto/create-document.dto';
//import { CreateDocumentDto } from '../dto/create-document.dto';
import { UpdateDocumentDto } from '../dto/update-document.dto';
import { AdminGuard } from '../auth/admin.guard';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { CreateUserDto } from '../dto/create-user.dto';
import { S3Service } from 'src/s3/s3.service';
import { PrismaService } from 'src/prisma/prisma.service';
@Controller('admin')
@UseGuards(JwtAuthGuard, AdminGuard)
@@ -27,27 +26,9 @@ export class AdminController {
constructor(
private readonly adminService: AdminService,
private readonly s3Service: S3Service,
private readonly prisma: PrismaService,
) {}
@Post('documents')
@UseInterceptors(FileInterceptor('file'))
createDocument(
@Body() createDocumentDto: CreateDocumentDto,
@UploadedFile() file: Express.Multer.File,
) {
return this.adminService.createDocument(createDocumentDto, file);
}
// @Post('document')
// @UseInterceptors(FileInterceptor('file'))
// async createDocument(
// @Body() createDocumentDto: CreateDocumentDto,
// @UploadedFile() file: Express.Multer.File,
// ) {
// // The actual file upload is handled by the FileInterceptor
// // We just need to pass the file to the service
// return this.adminService.createDocument(createDocumentDto, file);
// }
@Get('documents')
getAllDocuments() {
return this.adminService.getAllDocuments();
@@ -63,16 +44,27 @@ export class AdminController {
return this.adminService.updateDocument(id, updateDocumentDto, file);
}
@Delete('documents/:id')
async deleteDocument(@Param('id') id: string) {
await this.adminService.deleteDocument(+id);
return { message: 'Document deleted successfully' };
}
@Get('users')
getAllUsers() {
return this.adminService.getAllUsers();
}
@Post('test-document')
async testDocumentCreation() {
try {
const document = await this.prisma.document.create({
data: {
title: 'Test Document',
s3Key: 'test-key',
status: 'completed',
sharedWithId: 2, // ID of 'pero' user
},
});
return document;
} catch (error) {
console.error('Test document creation error:', error);
throw error;
}
}
@Post('users')
async createUser(@Body() createUserDto: CreateUserDto) {
@@ -82,9 +74,9 @@ export class AdminController {
@Post('documents/:id/share')
async shareDocument(
@Param('id') id: string,
@Body() { userIds }: { userIds: number[] },
@Body() { userId }: { userId: number },
) {
return this.adminService.shareDocument(+id, userIds);
return this.adminService.shareDocument(+id, userId);
}
@Put('documents/:id/status')
@@ -95,25 +87,33 @@ export class AdminController {
return this.adminService.updateDocumentStatus(+id, status);
}
// async uploadDocument(
// @UploadedFile() file: Express.Multer.File,
// @Body('title') title: string,
// @Request() req,
// ) {
// return this.adminService.uploadDocument(file, title, req.user.userId);
// }
@Post('documents')
@UseInterceptors(FileInterceptor('file'))
async uploadDocument(
@UploadedFile() file: Express.Multer.File,
@Body('title') title: string,
@Body('description') description: number[],
@Request() req,
@Body('sharedWith') sharedWithId: string,
) {
return this.adminService.uploadDocument(
file,
console.log('Received upload request:', {
fileExists: !!file,
fileSize: file?.size,
title,
req.user.userId,
description,
);
sharedWithId,
});
try {
const document = await this.adminService.uploadDocument(
file,
title,
Number(sharedWithId),
);
console.log('Document created:', document);
return document;
} catch (error) {
console.error('Upload error:', error);
throw error;
}
}
@Get('test-s3-connection')
async testS3Connection() {
+110 -252
View File
@@ -1,7 +1,7 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { S3Service } from '../s3/s3.service';
import { CreateDocumentDto } from '../dto/create-document.dto';
//import { CreateDocumentDto } from '../dto/create-document.dto';
import { UpdateDocumentDto } from '../dto/update-document.dto';
import { CreateUserDto } from '../dto/create-user.dto';
import * as bcrypt from 'bcrypt';
@@ -13,113 +13,89 @@ export class AdminService {
private s3Service: S3Service,
) {}
// async createDocument(
// createDocumentDto: CreateDocumentDto,
// file: Express.Multer.File,
// ) {
// const { title, content, clientEmail } = createDocumentDto;
// console.log('Received createDocumentDto:', createDocumentDto);
// let author;
// if (clientEmail) {
// author = await this.prisma.user.findUnique({
// where: { email: clientEmail },
// });
// if (!author) {
// throw new NotFoundException(`User with email ${clientEmail} not found`);
// }
// }
// const s3Key = await this.s3Service.uploadFile(file, 'documents');
// return this.prisma.document.create({
// data: {
// title,
// content,
// s3Key,
// ...(author && { author: { connect: { id: author.id } } }),
// },
// });
// }
async createDocument(
createDocumentDto: CreateDocumentDto,
async uploadDocument(
file: Express.Multer.File,
title: string,
sharedWithId: number,
) {
const { title, content, clientEmail } = createDocumentDto;
console.log('Received createDocumentDto:', createDocumentDto);
let authorId: number;
if (clientEmail) {
const author = await this.prisma.user.findUnique({
where: { email: clientEmail },
try {
// First verify the user exists
console.log('Verifying user:', sharedWithId);
const user = await this.prisma.user.findUnique({
where: { id: sharedWithId },
});
if (!author) {
throw new NotFoundException(`User with email ${clientEmail} not found`);
if (!user) {
throw new NotFoundException(`User with ID ${sharedWithId} not found`);
}
authorId = author.id;
} else {
// If no clientEmail is provided, we'll use a default admin user
// You should replace this with an appropriate default user ID
const defaultAdmin = await this.prisma.user.findFirst({
where: { isAdmin: true },
});
if (!defaultAdmin) {
throw new NotFoundException('No default admin user found');
}
authorId = defaultAdmin.id;
}
const s3Key = await this.s3Service.uploadFile(file, 'documents');
console.log('Found user:', user);
return this.prisma.document.create({
data: {
// Upload file to S3
console.log('Uploading file to S3...');
const s3Key = await this.s3Service.uploadFile(file, 'documents');
console.log('File uploaded to S3:', s3Key);
console.log('Creating document record with data:', {
title,
content,
s3Key,
author: { connect: { id: authorId } },
},
});
}
sharedWithId,
});
// async getAllDocuments() {
// return this.prisma.document.findMany({
// include: {
// sharedWith: {
// select: {
// id: true,
// name: true,
// email: true,
// },
// },
// },
// });
// }
const document = await this.prisma.document.create({
data: {
title,
s3Key,
status: 'completed',
sharedWithId,
},
include: {
sharedWith: {
select: {
id: true,
name: true,
email: true,
},
},
},
});
console.log('Created document:', document);
return document;
} catch (error) {
console.error('Error in uploadDocument:', error);
if (error.code === 'P2002') {
console.error('Unique constraint violation');
}
if (error.code === 'P2003') {
console.error('Foreign key constraint violation');
}
throw error;
}
}
async getAllDocuments() {
return this.prisma.document.findMany({
include: {
author: {
select: {
id: true,
name: true,
email: true,
try {
const documents = await this.prisma.document.findMany({
include: {
sharedWith: {
select: {
id: true,
name: true,
email: true,
},
},
},
sharedWith: {
select: {
id: true,
name: true,
email: true,
},
orderBy: {
createdAt: 'desc',
},
},
orderBy: {
createdAt: 'desc',
},
});
});
console.log('Retrieved documents with shared users:', documents);
return documents;
} catch (error) {
console.error('Error fetching documents:', error);
throw error;
}
}
async updateDocument(
@@ -149,57 +125,6 @@ export class AdminService {
},
});
}
async uploadDocument(
file: Express.Multer.File,
title: string,
userId: number,
sharedWith: number[],
) {
let s3Key;
try {
s3Key = await this.s3Service.uploadFile(file, 'documents');
// Log the sharedWith array to verify the data
console.log('Sharing document with users:', sharedWith);
const document = await this.prisma.document.create({
data: {
title,
authorId: userId,
s3Key,
status: 'completed',
sharedWith: {
connect: sharedWith.map((id) => ({ id })),
},
},
include: {
sharedWith: true, // Include this to verify the relation was created
},
});
console.log('Created document:', document);
return document;
} catch (error) {
console.error('Error in uploadDocument:', error);
throw error;
}
}
async deleteDocument(id: number) {
const document = await this.prisma.document.findUnique({
where: { id },
select: { s3Key: true },
});
if (document?.s3Key) {
await this.s3Service.deleteFile(document.s3Key);
}
return this.prisma.document.delete({ where: { id } });
}
async getAllUsers() {
return this.prisma.user.findMany();
}
async createUser(createUserDto: CreateUserDto) {
const hashedPassword = await bcrypt.hash(createUserDto.password, 10);
@@ -211,25 +136,22 @@ export class AdminService {
});
}
async shareDocument(documentId: number, userIds: number[]) {
const document = await this.prisma.document.update({
async shareDocument(documentId: number, userId: number) {
return this.prisma.document.update({
where: { id: documentId },
data: {
sharedWithId: userId,
},
include: {
sharedWith: {
connect: userIds.map((id: number) => ({ id })),
select: {
id: true,
name: true,
email: true,
},
},
},
});
// Create notifications for shared users
await this.prisma.notification.createMany({
data: userIds.map((userId: number) => ({
userId,
message: `A new document "${document.title}" has been shared with you.`,
})),
});
return document;
}
async updateDocumentStatus(documentId: number, status: string) {
@@ -239,100 +161,6 @@ export class AdminService {
});
}
// async uploadDocument(
// file: Express.Multer.File,
// title: string,
// userId: number,
// ) {
// try {
// // First create document with pending status
// const document = await this.prisma.document.create({
// data: {
// title,
// authorId: userId,
// status: 'pending',
// s3Key: '', // Temporary empty key
// },
// });
// // Update status to uploading
// await this.prisma.document.update({
// where: { id: document.id },
// data: { status: 'uploading' },
// });
// // Upload to S3
// const s3Key = await this.s3Service.uploadFile(file, 'documents');
// // Update document with s3Key and completed status
// return this.prisma.document.update({
// where: { id: document.id },
// data: {
// s3Key,
// status: 'completed',
// },
// });
// } catch (error) {
// // If anything fails, update status to failed
// const document = await this.prisma.document.findFirst({
// where: { title, authorId: userId },
// });
// if (document) {
// await this.prisma.document.update({
// where: { id: document.id },
// data: { status: 'failed' },
// });
// }
// throw error;
// }
// }
// problem whith upload status writing to db, i will fix it later
// async uploadDocument(
// file: Express.Multer.File,
// title: string,
// userId: number,
// sharedWith: number[],
// ) {
// let s3Key;
// try {
// // First upload to S3
// s3Key = await this.s3Service.uploadFile(file, 'documents');
// // Then create document with completed status and s3Key
// const document = await this.prisma.document.create({
// data: {
// title,
// authorId: userId,
// s3Key,
// status: 'completed', // Set status to completed immediately after successful upload
// sharedWith: {
// connect: sharedWith.map((id: number) => ({ id })),
// },
// },
// });
// return document;
// } catch (error) {
// // Create document with failed status if upload fails
// if (title && userId) {
// await this.prisma.document.create({
// data: {
// title,
// authorId: userId,
// s3Key: s3Key || '',
// status: 'failed',
// sharedWith: {
// connect: sharedWith.map((id: number) => ({ id })),
// },
// },
// });
// }
// throw error;
// }
// }
async getDocumentUrl(documentId: number) {
const document = await this.prisma.document.findUnique({
where: { id: documentId },
@@ -342,4 +170,34 @@ export class AdminService {
}
return this.s3Service.getFileUrl(document.s3Key);
}
async getUserWithDocuments(userId: number) {
return this.prisma.user.findUnique({
where: { id: userId },
select: {
id: true,
name: true,
email: true,
sharedDocuments: true,
},
});
}
async getAllUsers() {
try {
const users = await this.prisma.user.findMany({
select: {
id: true,
name: true,
email: true,
isAdmin: true,
sharedDocuments: true,
},
});
console.log('All users:', users);
return users;
} catch (error) {
console.error('Error fetching users:', error);
throw error;
}
}
}
+2 -1
View File
@@ -13,6 +13,7 @@ import { PrismaService } from './prisma/prisma.service';
import { PrismaModule } from './prisma/prisma.module';
import { ConfigModule } from '@nestjs/config';
import { AuthController } from './auth/auth.controller';
import { DocumentsController } from './documents/documents.controller';
@Module({
imports: [
@@ -32,7 +33,7 @@ import { AuthController } from './auth/auth.controller';
S3Module,
PrismaModule,
],
controllers: [AppController, AuthController],
controllers: [AppController, AuthController, DocumentsController],
providers: [
AppService,
UploadService,
@@ -10,6 +10,6 @@ export class ClientController {
@Get('documents')
async getClientDocuments(@User() user) {
return this.clientService.getClientDocuments(user.id);
return this.clientService.getDocuments(user.id);
}
}
@@ -5,10 +5,26 @@ import { PrismaService } from '../prisma/prisma.service';
export class ClientService {
constructor(private prisma: PrismaService) {}
async getClientDocuments(userId: string) {
// async getClientDocuments(userId: string) {
// return this.prisma.document.findMany({
// where: {
// authorId: Number(userId),
// },
// });
// }
async getDocuments(userId: string) {
return this.prisma.document.findMany({
where: {
authorId: Number(userId),
sharedWithId: Number(userId),
},
include: {
sharedWith: {
select: {
id: true,
name: true,
email: true,
},
},
},
});
}
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DocumentsController } from './documents.controller';
describe('DocumentsController', () => {
let controller: DocumentsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [DocumentsController],
}).compile();
controller = module.get<DocumentsController>(DocumentsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
@@ -0,0 +1,12 @@
import { Controller, Get, Param } from '@nestjs/common';
import { DocumentsService } from './documents.service';
@Controller('documents')
export class DocumentsController {
constructor(private readonly documentsService: DocumentsService) {}
@Get('shared/:userId')
async getSharedDocuments(@Param('userId') userId: string) {
console.log('userId', userId);
return this.documentsService.getClientDocuments(parseInt(userId));
}
}
@@ -1,14 +1,33 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { Document } from '@prisma/client';
//import { Document } from '@prisma/client';
@Injectable()
export class DocumentsService {
constructor(private readonly prisma: PrismaService) {}
async findAllForClient(clientId: number): Promise<Document[]> {
async getClientDocuments(clientId: number) {
// return this.prisma.document.findMany({
// where: {
// sharedWithId: clientId,
// },
// include: {
// sharedWith: {
// select: {
// id: true,
// name: true,
// email: true,
// },
// },
// },
// });
return this.prisma.document.findMany({
where: { authorId: clientId },
where: {
sharedWithId: clientId,
},
orderBy: {
createdAt: 'desc',
},
});
}
}