Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as sessionRepository from '../infrastructure/repositories/session-repos
import { candidateSerializer } from '../infrastructure/serializers/candidate-serializer.js';
import { sessionSerializer } from '../infrastructure/serializers/session-serializer.js';

async function createSession(request, _h, dependencies = { sessionSerializer, sessionRepository }) {
async function createSession(request, h, dependencies = { sessionSerializer, sessionRepository }) {
const userId = request.auth.credentials.userId;
const certificationCenterId = request.params.certificationCenterId;
const { address, room, date, time, examiner, description } = request.payload.data.attributes;
Expand All @@ -19,6 +19,7 @@ async function createSession(request, _h, dependencies = { sessionSerializer, se
examiner,
description,
});

const session = await dependencies.sessionRepository.get({ id: newSessionId });

return dependencies.sessionSerializer.serialize(session);
Expand All @@ -31,6 +32,10 @@ async function update(request, h, dependencies = { sessionSerializer, sessionRep
await usecases.updateSession({ address, room, date, time, examiner, description, sessionId });
const updatedSession = await dependencies.sessionRepository.get({ id: sessionId });

if (!updatedSession) {
return h.response().code(404);
}

return dependencies.sessionSerializer.serialize(updatedSession);
}

Expand All @@ -45,6 +50,11 @@ async function remove(request, h) {
async function get(request, h, dependencies = { sessionSerializer, sessionRepository }) {
const sessionId = request.params.sessionId;
const session = await dependencies.sessionRepository.get({ id: sessionId });

if (!session) {
return h.response().code(404);
}

return dependencies.sessionSerializer.serialize(session);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import {
CertificationCandidateByPersonalInfoTooManyMatchesError,
CertificationCandidatesError,
NotFoundError,
} from '../../../../shared/domain/errors.js';
import { mailCheck as mailCheckImplementation } from '../../../../shared/mail/infrastructure/services/mail-check.js';
import { CERTIFICATION_CANDIDATES_ERRORS } from '../../../shared/domain/constants/certification-candidates-errors.js';
Expand All @@ -23,6 +24,7 @@ import { CannotEnrollCandidateIndividuallyError } from '../errors.js';
* @param {CertificationCpfCountryRepository} params.certificationCpfCountryRepository
* @param {CertificationCpfCityRepository} params.certificationCpfCityRepository
* @param {EventAdapter} params.eventAdapter
* @throws {NotFoundError} the session does not exist or its access is restricted
*/
export async function addCandidateToSession({
sessionId,
Expand All @@ -40,11 +42,16 @@ export async function addCandidateToSession({
candidate.sessionId = sessionId;
const sessionAuthorization = await sessionAuthorizationAdapter.find({ sessionId });

if (!sessionAuthorization) {
throw new NotFoundError("La session n'existe pas ou son accès est restreint");
}

if (!sessionAuthorization.canEnrollCandidateIndividually) {
throw new CannotEnrollCandidateIndividuallyError();
}

const session = await sessionRepository.get({ id: sessionId });

try {
candidate.validate({ isSco: session.isSco });
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DomainTransaction } from '../../../../shared/domain/DomainTransaction.js';
import { NotFoundError } from '../../../../shared/domain/errors.js';
import { SessionStartedDeletionError } from '../errors.js';

/**
Expand All @@ -10,14 +11,20 @@ import { SessionStartedDeletionError } from '../errors.js';
* @param {object} params
* @param {SessionRepository} params.sessionRepository
* @param {SessionManagementRepository} params.sessionManagementRepository
* @throws {SessionStartedDeletionError} the session has already started
* @throws {NotFoundError} the session does not exist or its access is restricted
*/
const deleteSession = async ({ sessionId, sessionRepository, sessionManagementRepository }) => {
if (!(await sessionManagementRepository.hasNoStartedCertification({ id: sessionId }))) {
throw new SessionStartedDeletionError();
}

await DomainTransaction.execute(async () => {
await sessionRepository.remove({ id: sessionId });
const deletedSession = await sessionRepository.remove({ id: sessionId });

if (!deletedSession) {
throw new NotFoundError("La session n'existe pas ou son accès est restreint");
}
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @typedef {import('./index.js').SessionRepository} SessionRepository
* @typedef {import('./index.js').EventAdapter} EventAdapter
*/
import { ForbiddenAccess } from '../../../../shared/domain/errors.js';
import { ForbiddenAccess, NotFoundError } from '../../../../shared/domain/errors.js';
import { PromiseUtils } from '../../../../shared/infrastructure/utils/promise-utils.js';
import { SUBSCRIPTION_TYPES } from '../../../shared/domain/constants.js';
import { CannotEnrollScoCandidateError, UnknownCountryForStudentEnrolmentError } from '../errors.js';
Expand All @@ -21,6 +21,7 @@ const INSEE_PREFIX_CODE = '99';
* @param {CountryRepository} params.countryRepository
* @param {EventAdapter} params.eventAdapter
* @param {SessionAuthorizationAdapter} params.sessionAuthorizationAdapter
* @throws {NotFoundError} the session does not exist or its access is restricted
*/
export async function enrolStudentsToSession({
sessionId,
Expand All @@ -38,6 +39,11 @@ export async function enrolStudentsToSession({
return;
}
const sessionAuthorization = await sessionAuthorizationAdapter.find({ sessionId });

if (!sessionAuthorization) {
throw new NotFoundError("La session n'existe pas ou son accès est restreint");
}

if (!sessionAuthorization.canEnrollScoCandidate) {
throw new CannotEnrollScoCandidateError();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
* @typedef {import('./index.js').AttendanceSheetPdfUtils} AttendanceSheetPdfUtils
*/

import { NotFoundError } from '../../../../shared/domain/errors.js';

/**
* @param {object} params
* @param {SessionForAttendanceSheetRepository} params.sessionForAttendanceSheetRepository
* @param {AttendanceSheetPdfUtils} params.attendanceSheetPdfUtils
* @throws {NotFoundError} the session does not exist or no candidate is enrolled in it
*/
const getAttendanceSheet = async function ({
sessionId,
Expand All @@ -16,6 +19,10 @@ const getAttendanceSheet = async function ({
}) {
const session = await sessionForAttendanceSheetRepository.getWithCertificationCandidates({ id: sessionId });

if (!session) {
throw new NotFoundError("La session n'existe pas ou aucun candidat n'est inscrit à celle-ci");
}

const { attendanceSheet, fileName } = await attendanceSheetPdfUtils.getAttendanceSheetPdfBuffer({
session,
i18n,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@
* @typedef {import('./index.js').SessionRepository} SessionRepository
* @typedef {import('./index.js').CenterRepository} CenterRepository
*/
import { NotFoundError } from '../../../../shared/domain/errors.js';
import { Candidate } from '../models/Candidate.js';
/**
* @param {object} params
* @param {SessionRepository} params.sessionRepository
* @param {CenterRepository} params.centerRepository
* @throws {NotFoundError} the session does not exist or its access is restricted
*/
export async function getCandidateImportSheetData({ sessionId, sessionRepository, centerRepository }) {
const session = await sessionRepository.get({ id: sessionId });

if (!session) {
throw new NotFoundError("La session n'existe pas ou son accès est restreint");
}

const enrolledCandidates = session.certificationCandidates.sort(Candidate.sortByLastNameAndFirstName);
const center = await centerRepository.getById({ id: session.certificationCenterId });
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
*/

import { DomainTransaction } from '../../../../shared/domain/DomainTransaction.js';
import { CandidateAlreadyLinkedToUserError } from '../../../../shared/domain/errors.js';
import { CandidateAlreadyLinkedToUserError, NotFoundError } from '../../../../shared/domain/errors.js';

/**
* @param {object} params
* @param {CandidateRepository} params.candidateRepository
* @param {SessionRepository} params.sessionRepository
* @param {EventAdapter} params.eventAdapter
* @throws {NotFoundError} the session does not exist or its access is restricted
*/
export async function importCertificationCandidatesFromCandidatesImportSheet({
sessionId,
Expand All @@ -28,11 +29,17 @@ export async function importCertificationCandidatesFromCandidatesImportSheet({
certificationCpfService,
}) {
const sessionAuthorization = await sessionAuthorizationAdapter.find({ sessionId });

if (!sessionAuthorization) {
throw new NotFoundError("La session n'existe pas ou son accès est restreint");
}

if (!sessionAuthorization.canEnrollCandidateViaODS) {
throw new CandidateAlreadyLinkedToUserError('At least one candidate is already linked to a user');
}

const session = await sessionRepository.get({ id: sessionId });

const candidates = await certificationCandidatesOdsService.extractCertificationCandidatesFromCandidatesImportSheet({
i18n,
session,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

// @ts-check
import { DomainTransaction } from '../../../../shared/domain/DomainTransaction.js';
import { CertificationCandidateNotFoundError } from '../../../shared/domain/errors.js';
import { Candidate } from '../../domain/models/Candidate.js';

/**
Expand Down Expand Up @@ -57,8 +56,7 @@ export async function findByUserId({ userId }) {
* @function
* @param {Candidate} candidate
*
* @returns {Promise<void>}
* @throws {CertificationCandidateNotFoundError} Certification candidate not found
* @returns {Promise<object|undefined>} the updated candidate, or undefined when no candidate was found
*/
export async function update(candidate) {
const candidateDataToSave = adaptModelToDb(candidate);
Expand All @@ -71,9 +69,7 @@ export async function update(candidate) {
.update(candidateDataToSave)
.returning('*');

if (!updatedCertificationCandidate) {
throw new CertificationCandidateNotFoundError();
}
return updatedCertificationCandidate;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { DomainTransaction } from '../../../../shared/domain/DomainTransaction.js';
import { NotFoundError } from '../../../../shared/domain/errors.js';
import { CertificationCandidateForAttendanceSheet } from '../../domain/read-models/CertificationCandidateForAttendanceSheet.js';
import { SessionForAttendanceSheet } from '../../domain/read-models/SessionForAttendanceSheet.js';

/**
* @function
* @param {object} params
* @param {number} params.id
* @returns {Promise<SessionForAttendanceSheet>}
* @throws {NotFoundError}
* @returns {Promise<SessionForAttendanceSheet|null>} the session with its candidates, or null when the session does not exist or has no enrolled candidate
*/
export async function getWithCertificationCandidates({ id }) {
const knexConn = DomainTransaction.getConnection();
Expand Down Expand Up @@ -59,7 +57,7 @@ export async function getWithCertificationCandidates({ id }) {
.first();

if (!results || results.certificationCandidates === null) {
throw new NotFoundError("La session n'existe pas ou aucun candidat n'est inscrit à celle-ci");
return null;
}

return _toDomain(results);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { DomainTransaction } from '../../../../shared/domain/DomainTransaction.js';
import { NotFoundError } from '../../../../shared/domain/errors.js';
import { AlgorithmEngineVersion } from '../../../shared/domain/models/AlgorithmEngineVersion.js';
import { Candidate } from '../../domain/models/Candidate.js';
import { SessionEnrolment } from '../../domain/models/SessionEnrolment.js';
Expand All @@ -8,8 +7,7 @@ import { SessionEnrolment } from '../../domain/models/SessionEnrolment.js';
* @function
* @param {object} params
* @param {number} params.id
* @returns {Promise<SessionEnrolment>}
* @throws {NotFoundError}
* @returns {Promise<SessionEnrolment|null>} the session, or null when no session was found
*/
export async function get({ id }) {
const knexConn = DomainTransaction.getConnection();
Expand Down Expand Up @@ -69,8 +67,9 @@ export async function get({ id }) {
.join('certification-centers', 'certification-centers.id', 'sessions.certificationCenterId')
.where('sessions.id', id)
.first();

if (!foundSession) {
throw new NotFoundError("La session n'existe pas ou son accès est restreint");
return null;
}

const certificationCandidates =
Expand Down Expand Up @@ -190,13 +189,17 @@ export async function updateInfo({ id, address, room, examiner, date, time, desc
* @function
* @param {object} params
* @param {number} params.id
* @returns {Promise<void>}
* @throws {NotFoundError}
* @returns {Promise<number|null>} the number of deleted sessions, or null when no session was found
*/
export async function remove({ id }) {
const knexConn = DomainTransaction.getConnection();
await knexConn('invigilator_accesses').where({ sessionId: id }).del();
await knexConn('certification-candidates').where({ sessionId: id }).del();
const nbSessionsDeleted = await knexConn('sessions').where({ id }).del();
if (nbSessionsDeleted === 0) throw new NotFoundError();

if (nbSessionsDeleted === 0) {
return null;
}

return nbSessionsDeleted;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@
*/

import { DomainTransaction } from '../../../../shared/domain/DomainTransaction.js';
import { NotFoundError } from '../../../../shared/domain/errors.js';
import { SessionAlreadyPublishedError } from '../errors.js';

/**
* @param {object} params
* @param {SessionManagementRepository} params.sessionManagementRepository
* @param {FinalizedSessionRepository} params.finalizedSessionRepository
* @throws {SessionAlreadyPublishedError} the session is already published
* @throws {NotFoundError} the finalized session does not exist or its access is restricted
*/
const unfinalizeSession = async function ({ sessionId, sessionManagementRepository, finalizedSessionRepository }) {
if (await sessionManagementRepository.isPublished({ id: sessionId })) {
throw new SessionAlreadyPublishedError();
}

return DomainTransaction.execute(async () => {
await finalizedSessionRepository.remove({ sessionId });
const nbFinalizedSessionsRemoved = await finalizedSessionRepository.remove({ sessionId });

if (!nbFinalizedSessionsRemoved) {
throw new NotFoundError("La session n'existe pas ou son accès est restreint");
}

await sessionManagementRepository.unfinalize({ id: sessionId });
});
};
Expand Down
Loading
Loading