added some token usage, has errors
This commit is contained in:
parent
d2e3063094
commit
f3d0659c39
|
|
@ -1,9 +1,11 @@
|
|||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Answer } from './entity/answer.entity';
|
||||
import { CreateAnswerDto } from './dto/create-answer.dto';
|
||||
import { UpdateAnswerDto } from './dto/update-answer.dto';
|
||||
import { CreateAttachmentDto } from '../attachment/dto/create_attachment.dto';
|
||||
import { Attachment } from '../attachment/entity/attachment.entity';
|
||||
|
||||
@Injectable()
|
||||
export class AnswerService {
|
||||
|
|
@ -12,13 +14,15 @@ export class AnswerService {
|
|||
private readonly answerRepository: Repository<Answer>,
|
||||
) {}
|
||||
|
||||
async create(data: CreateAnswerDto): Promise<Answer> {
|
||||
try {
|
||||
const answer = this.answerRepository.create({ ...data });
|
||||
return await this.answerRepository.save(answer);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create answer: ${error.message}`);
|
||||
async create(data: CreateAnswerDto, token: any): Promise<Answer> {
|
||||
if (!token || !token.sub) {
|
||||
throw new InternalServerErrorException('Failed to extract sub from token');
|
||||
}
|
||||
const answer = this.answerRepository.create({
|
||||
...data,
|
||||
participantId: token.sub, // token.sub is userId, but we want participantId ?!
|
||||
});
|
||||
return await this.answerRepository.save(answer);
|
||||
}
|
||||
|
||||
async findAll( page = 1, limit = 10 ): Promise<{
|
||||
|
|
|
|||
|
|
@ -14,47 +14,17 @@ export class AttachmentService {
|
|||
private readonly attachmentRepository: Repository<Attachment>,
|
||||
) {}
|
||||
|
||||
async create(data: CreateAttachmentDto): Promise<Attachment> {
|
||||
try {
|
||||
// Here we send a sample request, in final implementation, there'll be no need for that, we'll get the decoded token
|
||||
const authResponse = await axios.post(
|
||||
'https://auth.didvan.com/realms/didvan/protocol/openid-connect/token',
|
||||
new URLSearchParams({
|
||||
client_id: 'didvan-app',
|
||||
username: 'bob',
|
||||
password: 'developer_password',
|
||||
grant_type: 'password',
|
||||
}),
|
||||
{
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// Decode the access token to extract the 'sub' claim
|
||||
const token = authResponse.data.access_token;
|
||||
const decodedToken: any = decode(token);
|
||||
if (!decodedToken || !decodedToken.sub) {
|
||||
throw new InternalServerErrorException('Failed to decode token or extract sub');
|
||||
}
|
||||
|
||||
|
||||
// Create the attachment with ownerId set to sub
|
||||
const attachment = this.attachmentRepository.create({
|
||||
...data,
|
||||
ownerId: decodedToken.sub, // Set ownerId to the token's sub
|
||||
metadata: data.metadata
|
||||
? { entries: data.metadata.entries }
|
||||
: { entries: [] },
|
||||
status: data.status || 'active',
|
||||
});
|
||||
|
||||
// Save the attachment to the database
|
||||
return await this.attachmentRepository.save(attachment);
|
||||
} catch (error) {
|
||||
throw new InternalServerErrorException(`Failed to create attachment: ${error.message}`);
|
||||
async create(data: CreateAttachmentDto, token: any): Promise<Attachment> {
|
||||
// Extract sub from decoded token
|
||||
if (!token || !token.sub) {
|
||||
throw new InternalServerErrorException('Failed to extract sub from token');
|
||||
}
|
||||
// Create the attachment with ownerId set to token.sub
|
||||
const attachment = this.attachmentRepository.create({
|
||||
...data,
|
||||
ownerId: token.sub, // Set ownerId to the token's sub
|
||||
});
|
||||
return await this.attachmentRepository.save(attachment);
|
||||
}
|
||||
|
||||
async findAll(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export class FormResultController {
|
|||
}
|
||||
|
||||
@Get(':id')
|
||||
async findOne(
|
||||
async findOne( // just gets the data in database
|
||||
@Param('id', new ParseUUIDPipe()) id: string,
|
||||
): Promise<FormResult | null> {
|
||||
return this.formResultService.findById(id);
|
||||
|
|
@ -44,10 +44,10 @@ export class FormResultController {
|
|||
return this.formResultService.remove(id);
|
||||
}
|
||||
|
||||
// @Get('form/:formId/statistics')
|
||||
// async getFormStatistics(
|
||||
// @Param('formId', new ParseUUIDPipe()) formId: string,
|
||||
// ): Promise<FormResult> {
|
||||
// return this.formResultService.getFormStatistics(formId);
|
||||
// }
|
||||
@Get(':id/refresh')
|
||||
async getFormStatistics( // updates data in database and then returns
|
||||
@Param('formId', new ParseUUIDPipe()) formId: string,
|
||||
): Promise<FormResult> {
|
||||
return this.formResultService.getFormStatistics(formId);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { FormResult } from './entity/formResult.entity';
|
||||
import { CreateFormResultDto } from './dto/create-formResult.dto';
|
||||
import { UpdateFormResultDto } from './dto/update-formResult.dto';
|
||||
import { Answer } from 'src/answer/entity/answer.entity';
|
||||
import { Question } from '../question/entity/question.entity';
|
||||
import { Form } from '../form/entity/form.entity';
|
||||
import { FormSection } from '../formSection/entity/formSection.entity';
|
||||
import { FormPage } from '../formPage/entity/formPage.entity';
|
||||
import { Repository, In } from 'typeorm';
|
||||
|
||||
@Injectable()
|
||||
export class FormResultService {
|
||||
|
|
@ -19,6 +21,15 @@ export class FormResultService {
|
|||
private readonly questionRepository: Repository<Question>,
|
||||
@InjectRepository(Answer)
|
||||
private readonly answerRepository: Repository<Answer>,
|
||||
@InjectRepository(Form)
|
||||
@InjectRepository(FormPage)
|
||||
private readonly formPageRepository: Repository<FormPage>,
|
||||
@InjectRepository(FormSection)
|
||||
private readonly formSectionRepository: Repository<FormSection>,
|
||||
@InjectRepository(Question)
|
||||
@InjectRepository(Answer)
|
||||
@InjectRepository(FormResult)
|
||||
private readonly formResultRepository: Repository<FormResult>,
|
||||
) {}
|
||||
|
||||
async create(data: CreateFormResultDto): Promise<FormResult> {
|
||||
|
|
@ -94,90 +105,73 @@ export class FormResultService {
|
|||
throw new NotFoundException(`FormResult with ID "${id}" not found`);
|
||||
}
|
||||
}
|
||||
//
|
||||
// async getFormStatistics(formId: string): Promise<FormResult> {
|
||||
// // 1. Find the Form entity
|
||||
// const form = await this.formRepository.findOne({ where: { id: formId } });
|
||||
// if (!form) {
|
||||
// throw new NotFoundException(`Form with ID "${formId}" not found`);
|
||||
// }
|
||||
//
|
||||
// // 2. Compute numQuestions
|
||||
// const numQuestions = await this.questionRepository.count({
|
||||
// where: {
|
||||
// formSection: {
|
||||
// formPage: {
|
||||
// form: { id: formId },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
//
|
||||
// // 3. Compute numParticipants
|
||||
// const numParticipantsResult = await this.answerRepository
|
||||
// .createQueryBuilder('answer')
|
||||
// .select('COUNT(DISTINCT answer.participantId)', 'count')
|
||||
// .innerJoin('answer.question', 'question')
|
||||
// .innerJoin('question.formSection', 'formSection')
|
||||
// .innerJoin('formSection.formPage', 'formPage')
|
||||
// .where('formPage.formId = :formId', { formId })
|
||||
// .getRawOne();
|
||||
// const numParticipants = numParticipantsResult ? Number(numParticipantsResult.count) : 0;
|
||||
//
|
||||
// // 4. Compute numAnswers
|
||||
// const numAnswers = await this.answerRepository.count({
|
||||
// where: {
|
||||
// question: {
|
||||
// formSection: {
|
||||
// formPage: {
|
||||
// form: { id: formId },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
//
|
||||
// // 5. Compute numCompleteParticipants
|
||||
// const subQuery = this.answerRepository
|
||||
// .createQueryBuilder('answer')
|
||||
// .select('answer.participantId')
|
||||
// .innerJoin('answer.question', 'question')
|
||||
// .innerJoin('question.formSection', 'formSection')
|
||||
// .innerJoin('formSection.formPage', 'formPage')
|
||||
// .where('formPage.formId = :formId', { formId })
|
||||
// .groupBy('answer.participantId')
|
||||
// .having('COUNT(DISTINCT answer.questionId) = :numQuestions', { numQuestions });
|
||||
//
|
||||
// const numCompleteParticipantsResult = await this.answerRepository.manager
|
||||
// .createQueryBuilder()
|
||||
// .select('COUNT(*)', 'count')
|
||||
// .from(`(${subQuery.getQuery()})`, 'subquery')
|
||||
// .setParameters(subQuery.getParameters())
|
||||
// .getRawOne();
|
||||
// const numCompleteParticipants = numCompleteParticipantsResult ? Number(numCompleteParticipantsResult.count) : 0;
|
||||
//
|
||||
// // 6. Find or create FormResult for the Form
|
||||
// let formResult = await this.formResultRepo.findOne({ where: { form: { id: formId } }, relations: ['form'] });
|
||||
// if (!formResult) {
|
||||
// formResult = this.formResultRepo.create({
|
||||
// form, // Link to the Form entity
|
||||
// numQuestions,
|
||||
// numParticipants,
|
||||
// numAnswers,
|
||||
// numComplete: numCompleteParticipants,
|
||||
// opinions: [], // Initialize as empty or compute if needed
|
||||
// status: 'active',
|
||||
// });
|
||||
// } else {
|
||||
// formResult.numQuestions = numQuestions;
|
||||
// formResult.numParticipants = numParticipants;
|
||||
// formResult.numAnswers = numAnswers;
|
||||
// formResult.numComplete = numCompleteParticipants;
|
||||
// // Preserve existing opinions or update if needed
|
||||
// }
|
||||
//
|
||||
// // 7. Save and return the FormResult
|
||||
// return await this.formResultRepo.save(formResult);
|
||||
// }
|
||||
|
||||
async getFormStatistics(formId: string): Promise<FormResult> {
|
||||
// 1. Find the Form entity
|
||||
const form = await this.formRepository.findOne({ where: { id: formId } });
|
||||
if (!form) {
|
||||
throw new NotFoundException(`Form with ID "${formId}" not found`);
|
||||
}
|
||||
|
||||
// 2. Compute numQuestions
|
||||
const pageIds = form.pageIds || [];
|
||||
const formPages = await this.formPageRepository.find({ where: { id: In(pageIds) } });
|
||||
const formSectionIds = formPages.flatMap(page => page.formSectionIds || []);
|
||||
const formSections = await this.formSectionRepository.find({ where: { id: In(formSectionIds) } });
|
||||
const questionIds = formSections.flatMap(section => section.questionIds || []);
|
||||
const numQuestions = questionIds.length;
|
||||
|
||||
// 3. Compute numParticipants (distinct participantId from answers)
|
||||
const numParticipantsResult = await this.answerRepository
|
||||
.createQueryBuilder('answer')
|
||||
.select('COUNT(DISTINCT answer.participantId)', 'count')
|
||||
.where('answer.questionId IN (:...questionIds)', { questionIds: questionIds.length ? questionIds : ['none'] }) // Handle empty questionIds
|
||||
.getRawOne();
|
||||
const numParticipants = numParticipantsResult ? Number(numParticipantsResult.count) : 0;
|
||||
|
||||
// 4. Compute numAnswers
|
||||
const numAnswers = await this.answerRepository.count({
|
||||
where: { questionId: In(questionIds.length ? questionIds : ['none']) }, // Handle empty questionIds
|
||||
});
|
||||
|
||||
// 5. Compute numCompleteParticipants (participants who answered all questions)
|
||||
const subQuery = this.answerRepository
|
||||
.createQueryBuilder('answer')
|
||||
.select('answer.participantId')
|
||||
.where('answer.questionId IN (:...questionIds)', { questionIds: questionIds.length ? questionIds : ['none'] }) // Handle empty questionIds
|
||||
.groupBy('answer.participantId')
|
||||
.having('COUNT(DISTINCT answer.questionId) = :numQuestions', { numQuestions: numQuestions || 1 }); // Avoid division by zero
|
||||
|
||||
const numCompleteParticipantsResult = await this.answerRepository.manager
|
||||
.createQueryBuilder()
|
||||
.select('COUNT(*)', 'count')
|
||||
.from(`(${subQuery.getQuery()})`, 'subquery')
|
||||
.setParameters(subQuery.getParameters())
|
||||
.getRawOne();
|
||||
const numCompleteParticipants = numCompleteParticipantsResult ? Number(numCompleteParticipantsResult.count) : 0;
|
||||
|
||||
// 6. Find or create FormResult for the Form
|
||||
let formResult = await this.formResultRepository.findOne({ where: { formId } });
|
||||
if (!formResult) {
|
||||
formResult = this.formResultRepository.create({
|
||||
formId, // Link to Form via formId
|
||||
numQuestions,
|
||||
numParticipants,
|
||||
numAnswers,
|
||||
numComplete: numCompleteParticipants,
|
||||
opinions: [], // Initialize as empty or compute if needed
|
||||
status: 'active',
|
||||
});
|
||||
} else {
|
||||
formResult.numQuestions = numQuestions;
|
||||
formResult.numParticipants = numParticipants;
|
||||
formResult.numAnswers = numAnswers;
|
||||
formResult.numComplete = numCompleteParticipants;
|
||||
// Preserve existing opinions or update if needed
|
||||
}
|
||||
|
||||
// 7. Save and return the FormResult
|
||||
return await this.formResultRepository.save(formResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue