diff --git a/backend/ebios_rm/migrations/0007_ebiosrmstudy_meta.py b/backend/ebios_rm/migrations/0007_ebiosrmstudy_meta.py new file mode 100644 index 000000000..5a22e4c5b --- /dev/null +++ b/backend/ebios_rm/migrations/0007_ebiosrmstudy_meta.py @@ -0,0 +1,66 @@ +# Generated by Django 5.1.4 on 2024-12-18 01:25 + +import core.validators +import ebios_rm.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("ebios_rm", "0006_alter_attackpath_stakeholders"), + ] + + operations = [ + migrations.AddField( + model_name="ebiosrmstudy", + name="meta", + field=models.JSONField( + default=ebios_rm.models.get_initial_meta, + validators=[ + core.validators.JSONSchemaInstanceValidator( + { + "$id": "https://ciso-assistant.com/schemas/ebiosrmstudy/meta.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Metadata of the EBIOS RM Study", + "properties": { + "workshops": { + "description": "A list of workshops, each containing steps", + "items": { + "additionalProperties": False, + "properties": { + "steps": { + "description": "The list of steps in the workshop", + "items": { + "additionalProperties": False, + "properties": { + "status": { + "description": "The current status of the step", + "enum": [ + "to_do", + "in_progress", + "done", + ], + "type": "string", + } + }, + "required": ["status"], + "type": "object", + }, + "type": "array", + } + }, + "required": ["steps"], + "type": "object", + }, + "type": "array", + } + }, + "title": "Metadata", + "type": "object", + } + ) + ], + verbose_name="Metadata", + ), + ), + ] diff --git a/backend/ebios_rm/models.py b/backend/ebios_rm/models.py index b7c8a7081..ff68102b8 100644 --- a/backend/ebios_rm/models.py +++ b/backend/ebios_rm/models.py @@ -1,7 +1,8 @@ from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.utils.translation import gettext_lazy as _ -from core.base_models import AbstractBaseModel, NameDescriptionMixin, ETADueDateMixin + +from core.base_models import AbstractBaseModel, ETADueDateMixin, NameDescriptionMixin from core.models import ( AppliedControl, Asset, @@ -10,10 +11,42 @@ RiskMatrix, Threat, ) +from core.validators import ( + JSONSchemaInstanceValidator, +) from iam.models import FolderMixin, User from tprm.models import Entity import json +INITIAL_META = { + "workshops": [ + { + "steps": [ + {"status": "to_do"}, + {"status": "to_do"}, + {"status": "to_do"}, + {"status": "to_do"}, + ] + }, + {"steps": [{"status": "to_do"}, {"status": "to_do"}, {"status": "to_do"}]}, + {"steps": [{"status": "to_do"}, {"status": "to_do"}, {"status": "to_do"}]}, + {"steps": [{"status": "to_do"}, {"status": "to_do"}]}, + { + "steps": [ + {"status": "to_do"}, + {"status": "to_do"}, + {"status": "to_do"}, + {"status": "to_do"}, + {"status": "to_do"}, + ] + }, + ] +} + + +def get_initial_meta(): + return INITIAL_META + class EbiosRMStudy(NameDescriptionMixin, ETADueDateMixin, FolderMixin): class Status(models.TextChoices): @@ -23,6 +56,43 @@ class Status(models.TextChoices): DONE = "done", _("Done") DEPRECATED = "deprecated", _("Deprecated") + META_JSONSCHEMA = { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ciso-assistant.com/schemas/ebiosrmstudy/meta.schema.json", + "title": "Metadata", + "description": "Metadata of the EBIOS RM Study", + "type": "object", + "properties": { + "workshops": { + "type": "array", + "description": "A list of workshops, each containing steps", + "items": { + "type": "object", + "properties": { + "steps": { + "type": "array", + "description": "The list of steps in the workshop", + "items": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "The current status of the step", + "enum": ["to_do", "in_progress", "done"], + }, + }, + "required": ["status"], + "additionalProperties": False, + }, + }, + }, + "required": ["steps"], + "additionalProperties": False, + }, + } + }, + } + risk_matrix = models.ForeignKey( RiskMatrix, on_delete=models.PROTECT, @@ -89,6 +159,12 @@ class Status(models.TextChoices): ) observation = models.TextField(null=True, blank=True, verbose_name=_("Observation")) + meta = models.JSONField( + default=get_initial_meta, + verbose_name=_("Metadata"), + validators=[JSONSchemaInstanceValidator(META_JSONSCHEMA)], + ) + class Meta: verbose_name = _("Ebios RM Study") verbose_name_plural = _("Ebios RM Studies") @@ -98,6 +174,17 @@ class Meta: def parsed_matrix(self): return self.risk_matrix.parse_json_translated() + def update_workshop_step_status(self, workshop: int, step: int, new_status: str): + if workshop < 1 or workshop > 5: + raise ValueError("Workshop must be between 1 and 5") + if step < 1 or step > len(self.meta["workshops"][workshop - 1]["steps"]): + raise ValueError( + f"Worshop {workshop} has only {len(self.meta['workshops'][workshop - 1]['steps'])} steps" + ) + status = new_status + self.meta["workshops"][workshop - 1]["steps"][step - 1]["status"] = status + return self.save() + class FearedEvent(NameDescriptionMixin, FolderMixin): ebios_rm_study = models.ForeignKey( diff --git a/backend/ebios_rm/views.py b/backend/ebios_rm/views.py index 5c9515d04..e84d997eb 100644 --- a/backend/ebios_rm/views.py +++ b/backend/ebios_rm/views.py @@ -10,6 +10,7 @@ AttackPath, OperationalScenario, ) +from .serializers import EbiosRMStudyReadSerializer from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from rest_framework.decorators import action @@ -66,6 +67,22 @@ def likelihood(self, request, pk): choices = undefined | _choices return Response(choices) + @action( + detail=True, + methods=["patch"], + name="Update workshop step status", + url_path="workshop/(?P[1-5])/step/(?P[1-5])", + ) + def update_workshop_step_status(self, request, pk, workshop, step): + ebios_rm_study: EbiosRMStudy = self.get_object() + workshop = int(workshop) + step = int(step) + # NOTE: For now, just set it as done. Will allow undoing this later. + ebios_rm_study.update_workshop_step_status( + workshop, step, new_status=request.data.get("status", "in_progress") + ) + return Response(EbiosRMStudyReadSerializer(ebios_rm_study).data) + class FearedEventViewSet(BaseModelViewSet): model = FearedEvent diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 30c486f51..54979b80b 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -1007,5 +1007,7 @@ "operatingModesDescription": "Operating modes description", "noStakeholders": "No stakeholders", "errorAssetGraphMustNotContainCycles": "The asset graph must not contain cycles.", - "addStakeholder": "Add stakeholder" + "addStakeholder": "Add stakeholder", + "markAsDone": "Mark as done", + "markAsInProgress": "Mark as in progress" } diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.server.ts index ad26bedfc..f28ed8334 100644 --- a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.server.ts +++ b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.server.ts @@ -4,9 +4,10 @@ import { getModelInfo } from '$lib/utils/crud'; import { modelSchema } from '$lib/utils/schemas'; import type { ModelInfo } from '$lib/utils/types'; import { type Actions } from '@sveltejs/kit'; -import { superValidate } from 'sveltekit-superforms'; +import { fail, superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import type { PageServerLoad } from './$types'; +import { z } from 'zod'; export const load: PageServerLoad = async ({ params, fetch }) => { const URLModel = 'ebios-rm'; @@ -39,5 +40,38 @@ export const actions: Actions = { action: 'create', redirectToWrittenObject: true }); + }, + changeStepState: async (event) => { + const formData = await event.request.formData(); + if (!formData) { + return fail(400, { form: null }); + } + + const schema = z.object({ + workshop: z.number(), + step: z.number(), + status: z.string() + }); + + const form = await superValidate(formData, zod(schema)); + + const workshop = formData.get('workshop'); + const step = formData.get('step'); + + const requestInitOptions: RequestInit = { + method: 'PATCH', + body: JSON.stringify(form.data) + }; + + const endpoint = `${BASE_API_URL}/ebios-rm/studies/${event.params.id}/workshop/${workshop}/step/${step}/`; + const res = await event.fetch(endpoint, requestInitOptions); + + if (!res.ok) { + const response = await res.text(); + console.error(response); + return fail(400, { form }); + } + + return { success: true, form }; } }; diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.svelte index 6525cac63..02b635659 100644 --- a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.svelte +++ b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/+page.svelte @@ -20,63 +20,61 @@ $: breadcrumbObject.set(data.data); - const riskAnalysisCreated: boolean = data.data.risk_assessments.length > 0; - - const dummydata = { + const workshopsData = { ws1: [ { title: safeTranslate(m.ebiosWs1_1()), - status: 'done', - href: `${$page.url.pathname}/workshop-one/ebios-rm-study?activity=one&next=${$page.url.pathname}` + status: data.data.meta.workshops[0].steps[0].status, + href: `${$page.url.pathname}/workshop-1/ebios-rm-study?activity=one&next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs1_2()), - status: 'done', - href: `${$page.url.pathname}/workshop-one/ebios-rm-study?activity=two&next=${$page.url.pathname}` + status: data.data.meta.workshops[0].steps[1].status, + href: `${$page.url.pathname}/workshop-1/ebios-rm-study?activity=two&next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs1_3()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-one/feared-events?next=${$page.url.pathname}` + status: data.data.meta.workshops[0].steps[2].status, + href: `${$page.url.pathname}/workshop-1/feared-events?next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs1_4()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-one/baseline?next=${$page.url.pathname}` + status: data.data.meta.workshops[0].steps[3].status, + href: `${$page.url.pathname}/workshop-1/baseline?next=${$page.url.pathname}` } ], ws2: [ { title: safeTranslate(m.ebiosWs2_1()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-two/ro-to?activity=one&next=${$page.url.pathname}` + status: data.data.meta.workshops[1].steps[0].status, + href: `${$page.url.pathname}/workshop-2/ro-to?activity=one&next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs2_2()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-two/ro-to?activity=two&next=${$page.url.pathname}` + status: data.data.meta.workshops[1].steps[1].status, + href: `${$page.url.pathname}/workshop-2/ro-to?activity=two&next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs2_3()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-two/ro-to?activity=three&next=${$page.url.pathname}` + status: data.data.meta.workshops[1].steps[2].status, + href: `${$page.url.pathname}/workshop-2/ro-to?activity=three&next=${$page.url.pathname}` } ], ws3: [ { title: safeTranslate(m.ebiosWs3_1()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-three/ecosystem?activity=one&next=${$page.url.pathname}` + status: data.data.meta.workshops[2].steps[0].status, + href: `${$page.url.pathname}/workshop-3/ecosystem?activity=one&next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs3_2()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-three/strategic-scenarios?next=${$page.url.pathname}` + status: data.data.meta.workshops[2].steps[1].status, + href: `${$page.url.pathname}/workshop-3/strategic-scenarios?next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs3_3()), - status: 'done', - href: `${$page.url.pathname}/workshop-three/ecosystem?activity=three&next=${$page.url.pathname}` + status: data.data.meta.workshops[2].steps[2].status, + href: `${$page.url.pathname}/workshop-3/ecosystem?activity=three&next=${$page.url.pathname}` } ], ws4: [ @@ -94,28 +92,28 @@ ws5: [ { title: safeTranslate(m.ebiosWs5_1()), - status: riskAnalysisCreated ? 'done' : 'to_do', + status: data.data.meta.workshops[4].steps[0].status, href: '#' }, { title: safeTranslate(m.ebiosWs5_2()), - status: 'done', - href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}` + status: data.data.meta.workshops[4].steps[1].status, + href: `${$page.url.pathname}/workshop-5/risk-analyses?next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs5_3()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}` + status: data.data.meta.workshops[4].steps[2].status, + href: `${$page.url.pathname}/workshop-5/risk-analyses?next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs5_4()), - status: 'to_do', - href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}` + status: data.data.meta.workshops[4].steps[3].status, + href: `${$page.url.pathname}/workshop-5/risk-analyses?next=${$page.url.pathname}` }, { title: safeTranslate(m.ebiosWs5_5()), - status: 'done', - href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}` + status: data.data.meta.workshops[4].steps[4].status, + href: `${$page.url.pathname}/workshop-5/risk-analyses?next=${$page.url.pathname}` } ] }; @@ -160,15 +158,20 @@
- - - - + + + +
@@ -183,6 +186,6 @@
- +
diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/Tile.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/Tile.svelte index e21cee13d..26708b953 100644 --- a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/Tile.svelte +++ b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/Tile.svelte @@ -1,24 +1,33 @@
{title}
-
- {#if status == 'to_do'} +
+ {#if workshopStatus == 'to_do'} - {:else if status == 'in_progress'} + {:else if workshopStatus == 'in_progress'} - {:else if status == 'done'} + {:else if workshopStatus == 'done'} {/if}
@@ -28,39 +37,64 @@
    {#each meta as step, i} - {#if step.status == 'done'} -
  1. - {#if createRiskAnalysis && i == 0} - - {:else} - +
  2. + {#if createRiskAnalysis && i == 0} + + {:else} + + {#if step.status == 'done'} - + -

    {m.activity()} {i + 1}

    -

    {step.title}

    -
    - {/if} -
  3. - {:else} -
  4. - {#if createRiskAnalysis && i == 0} - - {:else} - + {:else} - + -

    {m.activity()} {i + 1}

    -

    {step.title}

    -
    - {/if} -
  5. - {/if} + {/if} +

    {m.activity()} {i + 1}

    +

    {step.title}

    + + {/if} + +
    +
    { + return async () => { + if (step.status !== 'done') step.status = 'done'; + else step.status = 'in_progress'; + }; + }} + > + + + {#if step.status === 'done'} + + + {:else} + + + {/if} +
    +
    + {/each}
diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/baseline/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/baseline/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/baseline/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/baseline/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/baseline/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/baseline/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/baseline/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/baseline/+page.svelte diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/ebios-rm-study/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/ebios-rm-study/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/ebios-rm-study/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/ebios-rm-study/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/ebios-rm-study/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/ebios-rm-study/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/ebios-rm-study/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/ebios-rm-study/+page.svelte diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/ebios-rm-study/edit/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/ebios-rm-study/edit/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/ebios-rm-study/edit/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/ebios-rm-study/edit/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/ebios-rm-study/edit/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/ebios-rm-study/edit/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/ebios-rm-study/edit/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/ebios-rm-study/edit/+page.svelte diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/feared-events/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/feared-events/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/feared-events/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/feared-events/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/feared-events/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/feared-events/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-one/feared-events/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-1/feared-events/+page.svelte diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-two/ro-to/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-2/ro-to/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-two/ro-to/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-2/ro-to/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-two/ro-to/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-2/ro-to/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-two/ro-to/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-2/ro-to/+page.svelte diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-three/ecosystem/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-3/ecosystem/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-three/ecosystem/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-3/ecosystem/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-three/ecosystem/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-3/ecosystem/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-three/ecosystem/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-3/ecosystem/+page.svelte diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-three/strategic-scenarios/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-3/strategic-scenarios/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-three/strategic-scenarios/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-3/strategic-scenarios/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-three/strategic-scenarios/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-3/strategic-scenarios/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-three/strategic-scenarios/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-3/strategic-scenarios/+page.svelte diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-four/operational-scenario/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-4/operational-scenario/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-four/operational-scenario/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-4/operational-scenario/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-four/operational-scenario/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-4/operational-scenario/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-four/operational-scenario/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-4/operational-scenario/+page.svelte diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.server.ts b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-5/risk-analyses/+page.server.ts similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.server.ts rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-5/risk-analyses/+page.server.ts diff --git a/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.svelte b/frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-5/risk-analyses/+page.svelte similarity index 100% rename from frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-five/risk-analyses/+page.svelte rename to frontend/src/routes/(app)/(internal)/ebios-rm/[id=uuid]/workshop-5/risk-analyses/+page.svelte