Skip to content

Commit

Permalink
[TECH] Migrer l'api pour attacher une organisation fille dans src/org…
Browse files Browse the repository at this point in the history
…anizational-entities (PIX-11632)

 #8411
  • Loading branch information
pix-service-auto-merge authored Mar 14, 2024
2 parents 19ede17 + 2b51f48 commit 4cca4e1
Show file tree
Hide file tree
Showing 36 changed files with 137 additions and 92 deletions.
3 changes: 2 additions & 1 deletion api/lib/application/error-manager.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { UnableToAttachChildOrganizationToParentOrganizationError } from '../../src/organizational-entities/domain/errors.js';
import * as DomainErrors from '../domain/errors.js';
import * as errorSerializer from '../infrastructure/serializers/jsonapi/error-serializer.js';
import { HttpErrors } from './http-errors.js';
Expand All @@ -6,7 +7,7 @@ function _mapToHttpError(error) {
if (error instanceof HttpErrors.BaseHttpError) {
return error;
}
if (error instanceof DomainErrors.UnableToAttachChildOrganizationToParentOrganizationError) {
if (error instanceof UnableToAttachChildOrganizationToParentOrganizationError) {
return new HttpErrors.ConflictError(error.message, error.code, error.meta);
}
if (error instanceof DomainErrors.AccountRecoveryDemandExpired) {
Expand Down
26 changes: 0 additions & 26 deletions api/lib/application/organizations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,32 +390,6 @@ const register = async function (server) {
],
},
},
{
method: 'POST',
path: '/api/admin/organizations/{organizationId}/attach-child-organization',
config: {
pre: [
{
method: securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
assign: 'hasAuthorizationToAccessAdminScope',
},
],
validate: {
params: Joi.object({
organizationId: identifiersType.organizationId,
}),
payload: Joi.object({
childOrganizationId: identifiersType.organizationId,
}),
},
handler: organizationController.attachChildOrganization,
tags: ['api', 'admin', 'organizations'],
notes: [
"- **Cette route est restreinte aux utilisateurs authentifiés ayant un rôle SUPER_ADMIN, METIER ou SUPPORT permettant un accès à l'application d'administration de Pix**\n" +
"- Elle permet d'attacher une organisation mère à une organisation fille",
],
},
},
];

const orgaRoutes = [
Expand Down
10 changes: 0 additions & 10 deletions api/lib/application/organizations/organization-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,6 @@ const getOrganizationMemberIdentities = async function (
return dependencies.organizationMemberIdentitySerializer.serialize(members);
};

const attachChildOrganization = async function (request, h) {
const { childOrganizationId } = request.payload;
const { organizationId: parentOrganizationId } = request.params;

await usecases.attachChildOrganizationToOrganization({ childOrganizationId, parentOrganizationId });

return h.response().code(204);
};

const attachTargetProfiles = async function (request, h) {
const targetProfileIds = request.payload['target-profile-ids'];
const organizationId = request.params.id;
Expand Down Expand Up @@ -206,7 +197,6 @@ const findChildrenOrganizationsForAdmin = async function (

const organizationController = {
archiveOrganization,
attachChildOrganization,
attachTargetProfiles,
cancelOrganizationInvitation,
create,
Expand Down
13 changes: 0 additions & 13 deletions api/lib/domain/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -917,18 +917,6 @@ class TooManyRows extends DomainError {
}
}

class UnableToAttachChildOrganizationToParentOrganizationError extends DomainError {
constructor({
code = 'UNABLE_TO_ATTACH_CHILD_ORGANIZATION_TO_PARENT_ORGANIZATION',
message = 'Unable to attach child organization to parent organization',
meta,
} = {}) {
super(message);
this.code = code;
this.meta = meta;
}
}

class OidcMissingFieldsError extends DomainError {
constructor(
message = 'Mandatory information returned by the identify provider about the user is missing.',
Expand Down Expand Up @@ -1203,7 +1191,6 @@ export {
TargetProfileCannotBeCreated,
TargetProfileInvalidError,
TooManyRows,
UnableToAttachChildOrganizationToParentOrganizationError,
UncancellableCertificationCenterInvitationError,
UncancellableOrganizationInvitationError,
UnexpectedUserAccountError,
Expand Down
4 changes: 2 additions & 2 deletions api/lib/domain/models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { TrainingTriggerTube } from '../../../src/devcomp/domain/models/Training
import { Answer } from '../../../src/evaluation/domain/models/Answer.js';
import { CompetenceEvaluation } from '../../../src/evaluation/domain/models/CompetenceEvaluation.js';
import { Progression } from '../../../src/evaluation/domain/models/Progression.js';
import { DataProtectionOfficer } from '../../../src/organizational-entities/domain/models/DataProtectionOfficer.js';
import { OrganizationForAdmin } from '../../../src/organizational-entities/domain/models/OrganizationForAdmin.js';
import { CampaignCreator } from '../../../src/prescription/campaign/domain/models/CampaignCreator.js';
import { CampaignForArchiving } from '../../../src/prescription/campaign/domain/models/CampaignForArchiving.js';
import { CampaignForCreation } from '../../../src/prescription/campaign/domain/models/CampaignForCreation.js';
Expand Down Expand Up @@ -75,7 +77,6 @@ import { ComplementaryCertificationScoringWithComplementaryReferential } from '.
import { ComplementaryCertificationScoringWithoutComplementaryReferential } from './ComplementaryCertificationScoringWithoutComplementaryReferential.js';
import { Correction } from './Correction.js';
import { Course } from './Course.js';
import { DataProtectionOfficer } from './DataProtectionOfficer.js';
import { Division } from './Division.js';
import { EmailingAttempt } from './EmailingAttempt.js';
import { EmailModificationDemand } from './EmailModificationDemand.js';
Expand All @@ -95,7 +96,6 @@ import { OrganizationInvitation } from './OrganizationInvitation.js';
import { OrganizationInvitedUser } from './OrganizationInvitedUser.js';
import { OrganizationLearner } from './OrganizationLearner.js';
import { OrganizationMemberIdentity } from './OrganizationMemberIdentity.js';
import { OrganizationForAdmin } from './organizations-administration/OrganizationForAdmin.js';
import { OrganizationsToAttachToTargetProfile } from './OrganizationsToAttachToTargetProfile.js';
import { OrganizationTag } from './OrganizationTag.js';
import { ParticipantResultsShared } from './ParticipantResultsShared.js';
Expand Down
2 changes: 1 addition & 1 deletion api/lib/domain/usecases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import * as competenceEvaluationRepository from '../../../src/evaluation/infrast
import * as stageAcquisitionRepository from '../../../src/evaluation/infrastructure/repositories/stage-acquisition-repository.js';
import * as stageCollectionForTargetProfileRepository from '../../../src/evaluation/infrastructure/repositories/stage-collection-repository.js';
import * as stageRepository from '../../../src/evaluation/infrastructure/repositories/stage-repository.js';
import * as organizationForAdminRepository from '../../../src/organizational-entities/infrastructure/repositories/organization-for-admin-repository.js';
import * as campaignManagementRepository from '../../../src/prescription/campaign/infrastructure/repositories/campaign-management-repository.js';
import * as campaignParticipationBCRepository from '../../../src/prescription/campaign-participation/infrastructure/repositories/campaign-participation-repository.js';
import * as supOrganizationLearnerRepository from '../../../src/prescription/learner-management/infrastructure/repositories/sup-organization-learner-repository.js';
Expand Down Expand Up @@ -130,7 +131,6 @@ import * as juryCertificationSummaryRepository from '../../infrastructure/reposi
import * as knowledgeElementRepository from '../../infrastructure/repositories/knowledge-element-repository.js';
import * as learningContentRepository from '../../infrastructure/repositories/learning-content-repository.js';
import * as membershipRepository from '../../infrastructure/repositories/membership-repository.js';
import * as organizationForAdminRepository from '../../infrastructure/repositories/organization-for-admin-repository.js';
import * as organizationInvitationRepository from '../../infrastructure/repositories/organization-invitation-repository.js';
import * as organizationInvitedUserRepository from '../../infrastructure/repositories/organization-invited-user-repository.js';
import * as organizationLearnerRepository from '../../infrastructure/repositories/organization-learner-repository.js';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { knex } from '../../../db/knex-database-connection.js';
import { DataProtectionOfficer } from '../../domain/models/DataProtectionOfficer.js';
import { DataProtectionOfficer } from '../../../src/organizational-entities/domain/models/DataProtectionOfficer.js';
import { DomainTransaction } from '../DomainTransaction.js';

const DATA_PROTECTION_OFFICERS_TABLE_NAME = 'data-protection-officers';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Serializer } from 'jsonapi-serializer';
import _ from 'lodash';

import { OrganizationForAdmin } from '../../../../domain/models/organizations-administration/OrganizationForAdmin.js';
import { OrganizationForAdmin } from '../../../../../src/organizational-entities/domain/models/OrganizationForAdmin.js';

const serialize = function (organizations, meta) {
return new Serializer('organizations', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import _ from 'lodash';
import { disconnect } from '../../db/knex-database-connection.js';
import { updateOrganizationIdentityProviderForCampaigns } from '../../lib/domain/usecases/update-organization-identity-provider-for-campaigns.js';
import { DomainTransaction } from '../../lib/infrastructure/DomainTransaction.js';
import * as organizationForAdminRepository from '../../lib/infrastructure/repositories/organization-for-admin-repository.js';
import * as organizationForAdminRepository from '../../src/organizational-entities/infrastructure/repositories/organization-for-admin-repository.js';
import { checkCsvHeader, parseCsvWithHeader } from '../helpers/csvHelpers.js';

const modulePath = fileURLToPath(import.meta.url);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import _ from 'lodash';
import { disconnect } from '../../db/knex-database-connection.js';
import { updateOrganizationProvinceCode } from '../../lib/domain/usecases/organizations-administration/update-organization-province-code.js';
import { DomainTransaction } from '../../lib/infrastructure/DomainTransaction.js';
import * as organizationForAdminRepository from '../../lib/infrastructure/repositories/organization-for-admin-repository.js';
import * as organizationForAdminRepository from '../../src/organizational-entities/infrastructure/repositories/organization-for-admin-repository.js';
import { checkCsvHeader, parseCsvWithHeader } from '../helpers/csvHelpers.js';

const modulePath = fileURLToPath(import.meta.url);
Expand Down
2 changes: 2 additions & 0 deletions api/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { scoringRoutes } from './src/certification/scoring/routes.js';
import { certificationSessionRoutes } from './src/certification/session/routes.js';
import { devcompRoutes } from './src/devcomp/routes.js';
import { evaluationRoutes } from './src/evaluation/routes.js';
import { organizationalEntitiesRoutes } from './src/organizational-entities/application/routes.js';
import { campaignRoutes } from './src/prescription/campaign/routes.js';
import { campaignParticipationsRoutes } from './src/prescription/campaign-participation/routes.js';
import { learnerManagementRoutes } from './src/prescription/learner-management/routes.js';
Expand Down Expand Up @@ -143,6 +144,7 @@ const setupRoutesAndPlugins = async function (server) {
plugins,
routes,
authenticationRoutes,
organizationalEntitiesRoutes,
sharedRoutes,
evaluationRoutes,
flashCertificationRoutes,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { usecases } from '../domain/usecases/index.js';

const attachChildOrganization = async function (request, h) {
const { childOrganizationId } = request.payload;
const { organizationId: parentOrganizationId } = request.params;

await usecases.attachChildOrganizationToOrganization({ childOrganizationId, parentOrganizationId });

return h.response().code(204);
};

export const organizationController = {
attachChildOrganization,
};
41 changes: 41 additions & 0 deletions api/src/organizational-entities/application/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Joi from 'joi';

import { securityPreHandlers } from '../../shared/application/security-pre-handlers.js';
import { identifiersType } from '../../shared/domain/types/identifiers-type.js';
import { organizationController } from './organization-controller.js';

const register = async function (server) {
server.route([
{
method: 'POST',
path: '/api/admin/organizations/{organizationId}/attach-child-organization',
config: {
pre: [
{
method: securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
assign: 'hasAuthorizationToAccessAdminScope',
},
],
validate: {
params: Joi.object({
organizationId: identifiersType.organizationId,
}),
payload: Joi.object({
childOrganizationId: identifiersType.organizationId,
}),
},
handler: organizationController.attachChildOrganization,
tags: ['api', 'admin', 'organizational-entities', 'organizations'],
notes: [
"- **Cette route est restreinte aux utilisateurs authentifiés ayant un rôle SUPER_ADMIN, METIER ou SUPPORT permettant un accès à l'application d'administration de Pix**\n" +
"- Elle permet d'attacher une organisation mère à une organisation fille",
],
},
},
]);
};

const name = 'organizational-entities-api';
const organizationalEntitiesRoutes = [{ register, name }];

export { organizationalEntitiesRoutes };
15 changes: 15 additions & 0 deletions api/src/organizational-entities/domain/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DomainError } from '../../../lib/domain/errors.js';

class UnableToAttachChildOrganizationToParentOrganizationError extends DomainError {
constructor({
code = 'UNABLE_TO_ATTACH_CHILD_ORGANIZATION_TO_PARENT_ORGANIZATION',
message = 'Unable to attach child organization to parent organization',
meta,
} = {}) {
super(message);
this.code = code;
this.meta = meta;
}
}

export { UnableToAttachChildOrganizationToParentOrganizationError };
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import differenceBy from 'lodash/differenceBy.js';

import { ORGANIZATION_FEATURE } from '../../../../src/shared/domain/constants.js';
import { DataProtectionOfficer } from '../DataProtectionOfficer.js';
import { ORGANIZATION_FEATURE } from '../../../shared/domain/constants.js';
import { DataProtectionOfficer } from './DataProtectionOfficer.js';

const CREDIT_DEFAULT_VALUE = 0;

Expand Down
20 changes: 20 additions & 0 deletions api/src/organizational-entities/domain/usecases/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

import { injectDependencies } from '../../../shared/infrastructure/utils/dependency-injection.js';
import { importNamedExportsFromDirectory } from '../../../shared/infrastructure/utils/import-named-exports-from-directory.js';
import * as organizationForAdminRepository from '../../infrastructure/repositories/organization-for-admin-repository.js';

const path = dirname(fileURLToPath(import.meta.url));

const dependencies = {
organizationForAdminRepository,
};

const usecasesWithoutInjectedDependencies = {
...(await importNamedExportsFromDirectory({ path: join(path, './'), ignoredFileNames: ['index.js'] })),
};

const usecases = injectDependencies(usecasesWithoutInjectedDependencies, dependencies);

export { usecases };
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import _ from 'lodash';

import { knex } from '../../../db/knex-database-connection.js';
import { MissingAttributesError, NotFoundError } from '../../domain/errors.js';
import { OrganizationInvitation } from '../../domain/models/OrganizationInvitation.js';
import { OrganizationForAdmin } from '../../domain/models/organizations-administration/OrganizationForAdmin.js';
import { Tag } from '../../domain/models/Tag.js';
import { DomainTransaction } from '../DomainTransaction.js';
import { knex } from '../../../../db/knex-database-connection.js';
import { MissingAttributesError, NotFoundError } from '../../../../lib/domain/errors.js';
import { OrganizationInvitation } from '../../../../lib/domain/models/OrganizationInvitation.js';
import { Tag } from '../../../../lib/domain/models/Tag.js';
import { DomainTransaction } from '../../../../lib/infrastructure/DomainTransaction.js';
import { OrganizationForAdmin } from '../../domain/models/OrganizationForAdmin.js';

const ORGANIZATIONS_TABLE_NAME = 'organizations';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { OrganizationForAdmin } from '../../../../lib/domain/models/organizations-administration/OrganizationForAdmin.js';
import { createOrganization } from '../../../../lib/domain/usecases/create-organization.js';
import * as organizationCreationValidator from '../../../../lib/domain/validators/organization-creation-validator.js';
import * as dataProtectionOfficerRepository from '../../../../lib/infrastructure/repositories/data-protection-officer-repository.js';
import * as organizationForAdminRepository from '../../../../lib/infrastructure/repositories/organization-for-admin-repository.js';
import { OrganizationForAdmin } from '../../../../src/organizational-entities/domain/models/OrganizationForAdmin.js';
import * as organizationForAdminRepository from '../../../../src/organizational-entities/infrastructure/repositories/organization-for-admin-repository.js';
import * as schoolRepository from '../../../../src/school/infrastructure/repositories/school-repository.js';
import { databaseBuilder, expect } from '../../../test-helper.js';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DataProtectionOfficer } from '../../../../lib/domain/models/DataProtectionOfficer.js';
import { updateCertificationCenterDataProtectionOfficerInformation } from '../../../../lib/domain/usecases/update-certification-center-data-protection-officer-information.js';
import * as dataProtectionOfficerRepository from '../../../../lib/infrastructure/repositories/data-protection-officer-repository.js';
import { DataProtectionOfficer } from '../../../../src/organizational-entities/domain/models/DataProtectionOfficer.js';
import { databaseBuilder, expect } from '../../../test-helper.js';

describe('Integration | UseCases | update-certification-center-data-protection-officer-information', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DataProtectionOfficer } from '../../../../lib/domain/models/DataProtectionOfficer.js';
import { updateOrganizationDataProtectionOfficerInformation } from '../../../../lib/domain/usecases/update-organization-data-protection-officer-information.js';
import * as dataProtectionOfficerRepository from '../../../../lib/infrastructure/repositories/data-protection-officer-repository.js';
import { DataProtectionOfficer } from '../../../../src/organizational-entities/domain/models/DataProtectionOfficer.js';
import { databaseBuilder, expect } from '../../../test-helper.js';

describe('Integration | UseCases | update-organization-data-protection-officer-information', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DataProtectionOfficer } from '../../../../lib/domain/models/DataProtectionOfficer.js';
import * as dataProtectionOfficerRepository from '../../../../lib/infrastructure/repositories/data-protection-officer-repository.js';
import { DataProtectionOfficer } from '../../../../src/organizational-entities/domain/models/DataProtectionOfficer.js';
import { databaseBuilder, expect, knex } from '../../../test-helper.js';

describe('Integration | Repository | data-protection-officer', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { PIX_ADMIN } from '../../../../src/authorization/domain/constants.js';
import { PIX_ADMIN } from '../../../src/authorization/domain/constants.js';
import {
createServer,
databaseBuilder,
expect,
generateValidRequestAuthorizationHeader,
knex,
} from '../../../test-helper.js';
} from '../../test-helper.js';

const { ROLES } = PIX_ADMIN;

Expand Down
Loading

0 comments on commit 4cca4e1

Please sign in to comment.