diff --git a/etc/databases/mooc.sql b/etc/databases/mooc.sql
index a999ef78..1a094f82 100644
--- a/etc/databases/mooc.sql
+++ b/etc/databases/mooc.sql
@@ -4,35 +4,35 @@
-- Generic tables
-CREATE TABLE `mutations` (
- `id` BIGINT AUTO_INCREMENT PRIMARY KEY,
- `table_name` VARCHAR(255) NOT NULL,
- `operation` ENUM ('INSERT', 'UPDATE', 'DELETE') NOT NULL,
- `old_value` JSON NULL,
- `new_value` JSON NULL,
- `mutation_timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+CREATE TABLE mutations (
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
+ table_name VARCHAR(255) NOT NULL,
+ operation ENUM ('INSERT', 'UPDATE', 'DELETE') NOT NULL,
+ old_value JSON NULL,
+ new_value JSON NULL,
+ mutation_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
-CREATE TABLE `domain_events` (
- `id` CHAR(36) NOT NULL,
- `aggregate_id` CHAR(36) NOT NULL,
- `name` VARCHAR(255) NOT NULL,
- `body` JSON NOT NULL,
- `occurred_on` TIMESTAMP NOT NULL,
- PRIMARY KEY (`id`)
+CREATE TABLE domain_events (
+ id CHAR(36) NOT NULL,
+ aggregate_id CHAR(36) NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ body JSON NOT NULL,
+ occurred_on TIMESTAMP NOT NULL,
+ PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
-- Aggregates tables
-CREATE TABLE `courses` (
- `id` CHAR(36) NOT NULL,
- `name` VARCHAR(255) NOT NULL,
- `duration` VARCHAR(255) NOT NULL,
- PRIMARY KEY (`id`)
+CREATE TABLE courses (
+ id CHAR(36) NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ duration VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
@@ -68,28 +68,62 @@ BEGIN
VALUES ('courses', 'DELETE', JSON_OBJECT('id', old.id, 'name', old.name, 'duration', old.duration), NOW());
END;
-CREATE TABLE `courses_counter` (
- `id` CHAR(36) NOT NULL,
- `total` INT NOT NULL,
- `existing_courses` JSON NOT NULL,
- PRIMARY KEY (`id`)
+CREATE TABLE courses_counter (
+ id CHAR(36) NOT NULL,
+ total INT NOT NULL,
+ existing_courses JSON NOT NULL,
+ PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
-INSERT INTO `courses_counter`
+INSERT INTO courses_counter (id, total, existing_courses)
VALUES ("cdf26d7d-3deb-4e8c-9f73-4ac085a8d6f3", 0, "[]");
+CREATE TABLE steps (
+ id CHAR(36) NOT NULL,
+ title VARCHAR(255) NOT NULL,
+ duration INT NOT NULL,
+ type VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+CREATE TABLE steps_video (
+ id CHAR(36) NOT NULL,
+ url VARCHAR(255) NOT NULL,
+ FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+CREATE TABLE steps_exercise (
+ id CHAR(36) NOT NULL,
+ content VARCHAR(255) NOT NULL,
+ FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+CREATE TABLE steps_quiz (
+ id CHAR(36) NOT NULL,
+ questions TEXT NOT NULL,
+ FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
/* -------------------------
BACKOFFICE CONTEXT
---------------------------- */
-CREATE TABLE `backoffice_courses` (
- `id` CHAR(36) NOT NULL,
- `name` VARCHAR(255) NOT NULL,
- `duration` VARCHAR(255) NOT NULL,
- PRIMARY KEY (`id`)
+CREATE TABLE backoffice_courses (
+ id CHAR(36) NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ duration VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
diff --git a/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php b/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php
new file mode 100644
index 00000000..34c30189
--- /dev/null
+++ b/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php
@@ -0,0 +1,14 @@
+questions = $questions;
+ }
+}
diff --git a/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php b/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php
new file mode 100644
index 00000000..15717259
--- /dev/null
+++ b/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php
@@ -0,0 +1,22 @@
+question . '----' . implode('****', $this->answers);
+ }
+}
diff --git a/src/Mooc/Steps/Domain/Step.php b/src/Mooc/Steps/Domain/Step.php
new file mode 100644
index 00000000..b59277cd
--- /dev/null
+++ b/src/Mooc/Steps/Domain/Step.php
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml
new file mode 100644
index 00000000..09e493da
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml
new file mode 100644
index 00000000..4b116a56
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php
new file mode 100644
index 00000000..677fee74
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php
@@ -0,0 +1,40 @@
+ $question->toString(), $value),
+ $platform
+ );
+ }
+
+ public function convertToPHPValue($value, AbstractPlatform $platform): array
+ {
+ $scalars = parent::convertToPHPValue($value, $platform);
+
+ return map(fn (string $value): QuizStepQuestion => QuizStepQuestion::fromString($value), $scalars);
+ }
+}
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml
new file mode 100644
index 00000000..229add0c
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml
new file mode 100644
index 00000000..c1307953
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php
new file mode 100644
index 00000000..47b97966
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml
new file mode 100644
index 00000000..5302800f
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml
new file mode 100644
index 00000000..a4141ba8
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php b/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php
new file mode 100644
index 00000000..45a1151d
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php
@@ -0,0 +1,28 @@
+persist($step);
+ }
+
+ public function search(StepId $id): ?Step
+ {
+ return $this->repository(Step::class)->find($id);
+ }
+
+ public function delete(Step $step): void
+ {
+ $this->remove($step);
+ }
+}
diff --git a/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php b/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php
new file mode 100644
index 00000000..eac56c22
--- /dev/null
+++ b/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php
@@ -0,0 +1,16 @@
+ QuizStepQuestionMother::create()
+ ) : $questions;
+
+ return new QuizStep(
+ $id ?? StepIdMother::create(),
+ $title ?? StepTitleMother::create(),
+ $duration ?? StepDurationMother::create(),
+ ...$stepQuestions
+ );
+ }
+}
diff --git a/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php b/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php
new file mode 100644
index 00000000..04fcd800
--- /dev/null
+++ b/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php
@@ -0,0 +1,20 @@
+ WordMother::create())
+ );
+ }
+}
diff --git a/tests/Mooc/Steps/Domain/StepDurationMother.php b/tests/Mooc/Steps/Domain/StepDurationMother.php
new file mode 100644
index 00000000..73ce6842
--- /dev/null
+++ b/tests/Mooc/Steps/Domain/StepDurationMother.php
@@ -0,0 +1,16 @@
+repository()->save($step);
+ }
+
+ /**
+ * @test
+ * @dataProvider steps
+ */
+ public function it_should_search_an_existing_step(Step $step): void
+ {
+ $this->repository()->save($step);
+
+ $this->assertEquals($step, $this->repository()->search($step->id));
+ }
+
+ /**
+ * @test
+ * @dataProvider steps
+ */
+ public function it_should_delete_an_existing_step(Step $step): void
+ {
+ $this->repository()->save($step);
+ $this->repository()->delete($step);
+
+ $this->assertNull($this->repository()->search($step->id));
+ }
+
+ public function steps(): array
+ {
+ return [
+ 'video' => [VideoStepMother::create()],
+ 'exercise' => [ExerciseStepMother::create()],
+ 'quiz' => [QuizStepMother::create()],
+ ];
+ }
+}
diff --git a/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php b/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php
new file mode 100644
index 00000000..8d0eb52c
--- /dev/null
+++ b/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php
@@ -0,0 +1,16 @@
+service(StepRepository::class);
+ }
+}