Skip to content

Commit

Permalink
feat: add steps
Browse files Browse the repository at this point in the history
  • Loading branch information
rgomezcasas committed Dec 20, 2023
1 parent c4d2f25 commit 46af271
Show file tree
Hide file tree
Showing 37 changed files with 683 additions and 37 deletions.
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ APP_SECRET=29ac4a5187930cd4b689aa0f3ee7cbc0
#--------------------------------#
# MySql
MOOC_DATABASE_DRIVER=pdo_mysql
MOOC_DATABASE_HOST=codely-php_ddd_skeleton-mooc-mysql
MOOC_DATABASE_PORT=3306
MOOC_DATABASE_HOST=127.0.0.1
MOOC_DATABASE_PORT=3360
MOOC_DATABASE_NAME=mooc
MOOC_DATABASE_USER=root
MOOC_DATABASE_PASSWORD=
Expand Down
100 changes: 65 additions & 35 deletions etc/databases/mooc.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -43,7 +43,7 @@ CREATE TRIGGER after_courses_insert
FOR EACH ROW
BEGIN
INSERT INTO mutations (table_name, operation, new_value, mutation_timestamp)
VALUES ('courses', 'INSERT', JSON_OBJECT('id', new.id, 'name', new.name, 'duration', new.duration), NOW());
VALUES ('courses', 'INSERT', json_object('id', new.id, 'name', new.name, 'duration', new.duration), now());
END;

CREATE TRIGGER after_courses_update
Expand All @@ -54,9 +54,9 @@ BEGIN
INSERT INTO mutations (table_name, operation, old_value, new_value, mutation_timestamp)
VALUES ('courses',
'UPDATE',
JSON_OBJECT('id', old.id, 'name', old.name, 'duration', old.duration),
JSON_OBJECT('id', new.id, 'name', new.name, 'duration', new.duration),
NOW());
json_object('id', old.id, 'name', old.name, 'duration', old.duration),
json_object('id', new.id, 'name', new.name, 'duration', new.duration),
now());
END;

CREATE TRIGGER after_courses_delete
Expand All @@ -65,31 +65,61 @@ CREATE TRIGGER after_courses_delete
FOR EACH ROW
BEGIN
INSERT INTO mutations (table_name, operation, old_value, mutation_timestamp)
VALUES ('courses', 'DELETE', JSON_OBJECT('id', old.id, 'name', old.name, 'duration', old.duration), NOW());
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
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
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;

CREATE TABLE steps_video (
id CHAR(36) NOT NULL,
url VARCHAR(255) NOT NULL
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;

CREATE TABLE steps_exercise (
id CHAR(36) NOT NULL,
content VARCHAR(255) NOT NULL
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;

CREATE TABLE steps_quiz (
id CHAR(36) NOT NULL,
questions TEXT NOT NULL
) 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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Application\Create;

use CodelyTv\Shared\Domain\Bus\Command\CommandHandler;

final readonly class CreateVideoStepCommandHandler implements CommandHandler
{
public function __construct(private VideoStepCreator $creator) {}
}
12 changes: 12 additions & 0 deletions src/Mooc/Steps/Application/Create/VideoStepCreator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Application\Create;

use CodelyTv\Mooc\Steps\Domain\StepRepository;

final readonly class VideoStepCreator
{
public function __construct(private StepRepository $repository) {}
}
22 changes: 22 additions & 0 deletions src/Mooc/Steps/Domain/Exercise/ExerciseStep.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain\Exercise;

use CodelyTv\Mooc\Steps\Domain\Step;
use CodelyTv\Mooc\Steps\Domain\StepDuration;
use CodelyTv\Mooc\Steps\Domain\StepId;
use CodelyTv\Mooc\Steps\Domain\StepTitle;

final class ExerciseStep extends Step
{
public function __construct(
StepId $id,
StepTitle $title,
StepDuration $duration,
private readonly ExerciseStepContent $content
) {
parent::__construct($id, $title, $duration);
}
}
9 changes: 9 additions & 0 deletions src/Mooc/Steps/Domain/Exercise/ExerciseStepContent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain\Exercise;

use CodelyTv\Shared\Domain\ValueObject\StringValueObject;

final class ExerciseStepContent extends StringValueObject {}
27 changes: 27 additions & 0 deletions src/Mooc/Steps/Domain/Quiz/QuizStep.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain\Quiz;

use CodelyTv\Mooc\Steps\Domain\Step;
use CodelyTv\Mooc\Steps\Domain\StepDuration;
use CodelyTv\Mooc\Steps\Domain\StepId;
use CodelyTv\Mooc\Steps\Domain\StepTitle;

final class QuizStep extends Step
{
/** @var QuizStepQuestion[] */
private array $questions;

public function __construct(
StepId $id,
StepTitle $title,
StepDuration $duration,
QuizStepQuestion ...$questions
) {
parent::__construct($id, $title, $duration);

$this->questions = $questions;
}
}
22 changes: 22 additions & 0 deletions src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain\Quiz;

final readonly class QuizStepQuestion
{
public function __construct(private string $question, private array $answers) {}

public static function fromString(string $value): self
{
[$question, $answers] = explode('----', $value);

return new self($question, explode('****', $answers));
}

public function toString(): string
{
return $this->question . '----' . implode('****', $this->answers);
}
}
16 changes: 16 additions & 0 deletions src/Mooc/Steps/Domain/Step.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain;

use CodelyTv\Shared\Domain\Aggregate\AggregateRoot;

abstract class Step extends AggregateRoot
{
public function __construct(
public readonly StepId $id,
private readonly StepTitle $title,
private readonly StepDuration $duration
) {}
}
9 changes: 9 additions & 0 deletions src/Mooc/Steps/Domain/StepDuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain;

use CodelyTv\Shared\Domain\ValueObject\IntValueObject;

final class StepDuration extends IntValueObject {}
9 changes: 9 additions & 0 deletions src/Mooc/Steps/Domain/StepId.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain;

use CodelyTv\Shared\Domain\ValueObject\Uuid;

final class StepId extends Uuid {}
12 changes: 12 additions & 0 deletions src/Mooc/Steps/Domain/StepRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain;

interface StepRepository
{
public function save(Step $step): void;

public function search(StepId $id): ?Step;
}
9 changes: 9 additions & 0 deletions src/Mooc/Steps/Domain/StepTitle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain;

use CodelyTv\Shared\Domain\ValueObject\StringValueObject;

final class StepTitle extends StringValueObject {}
22 changes: 22 additions & 0 deletions src/Mooc/Steps/Domain/Video/VideoStep.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain\Video;

use CodelyTv\Mooc\Steps\Domain\Step;
use CodelyTv\Mooc\Steps\Domain\StepDuration;
use CodelyTv\Mooc\Steps\Domain\StepId;
use CodelyTv\Mooc\Steps\Domain\StepTitle;

final class VideoStep extends Step
{
public function __construct(
StepId $id,
StepTitle $title,
StepDuration $duration,
private readonly VideoStepUrl $url
) {
parent::__construct($id, $title, $duration);
}
}
9 changes: 9 additions & 0 deletions src/Mooc/Steps/Domain/Video/VideoStepUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace CodelyTv\Mooc\Steps\Domain\Video;

use CodelyTv\Shared\Domain\ValueObject\StringValueObject;

final class VideoStepUrl extends StringValueObject {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

<entity name="CodelyTv\Mooc\Steps\Domain\Exercise\ExerciseStep" table="steps_exercise">
<embedded name="content" class="CodelyTv\Mooc\Steps\Domain\Exercise\ExerciseStepContent" use-column-prefix="false" />
</entity>
</doctrine-mapping>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

<embeddable name="CodelyTv\Mooc\Steps\Domain\Exercise\ExerciseStepContent">
<field name="value" type="string" column="content" />
</embeddable>
</doctrine-mapping>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

<entity name="CodelyTv\Mooc\Steps\Domain\Quiz\QuizStep" table="steps_quiz">
<field name="questions" type="quiz_step_questions" column="questions" />
</entity>
</doctrine-mapping>
Loading

0 comments on commit 46af271

Please sign in to comment.