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