feat : add Task entities, repositories and migration

Add Task, TaskStatus, TaskEffort, TaskPriority, TaskType, TaskGroup
entities with Doctrine mappings and API Platform CRUD operations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 23:38:39 +01:00
parent b240dc6fc4
commit 1d50e5dcb3
13 changed files with 792 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260309221052 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE task (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, title VARCHAR(255) NOT NULL, description TEXT DEFAULT NULL, status_id INT DEFAULT NULL, effort_id INT DEFAULT NULL, priority_id INT DEFAULT NULL, assignee_id INT DEFAULT NULL, group_id INT DEFAULT NULL, project_id INT NOT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE INDEX IDX_527EDB256BF700BD ON task (status_id)');
$this->addSql('CREATE INDEX IDX_527EDB259F2256F ON task (effort_id)');
$this->addSql('CREATE INDEX IDX_527EDB25497B19F9 ON task (priority_id)');
$this->addSql('CREATE INDEX IDX_527EDB2559EC7D60 ON task (assignee_id)');
$this->addSql('CREATE INDEX IDX_527EDB25FE54D947 ON task (group_id)');
$this->addSql('CREATE INDEX IDX_527EDB25166D1F9C ON task (project_id)');
$this->addSql('CREATE TABLE task_task_type (task_id INT NOT NULL, task_type_id INT NOT NULL, PRIMARY KEY (task_id, task_type_id))');
$this->addSql('CREATE INDEX IDX_80470E038DB60186 ON task_task_type (task_id)');
$this->addSql('CREATE INDEX IDX_80470E03DAADA679 ON task_task_type (task_type_id)');
$this->addSql('CREATE TABLE task_effort (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(50) NOT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE TABLE task_group (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, title VARCHAR(255) NOT NULL, description TEXT DEFAULT NULL, color VARCHAR(7) NOT NULL, project_id INT NOT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE INDEX IDX_AA645FE5166D1F9C ON task_group (project_id)');
$this->addSql('CREATE TABLE task_priority (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(255) NOT NULL, color VARCHAR(7) NOT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE TABLE task_status (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(255) NOT NULL, color VARCHAR(7) NOT NULL, position INT NOT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE TABLE task_type (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(255) NOT NULL, color VARCHAR(7) NOT NULL, PRIMARY KEY (id))');
$this->addSql('ALTER TABLE task ADD CONSTRAINT FK_527EDB256BF700BD FOREIGN KEY (status_id) REFERENCES task_status (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('ALTER TABLE task ADD CONSTRAINT FK_527EDB259F2256F FOREIGN KEY (effort_id) REFERENCES task_effort (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('ALTER TABLE task ADD CONSTRAINT FK_527EDB25497B19F9 FOREIGN KEY (priority_id) REFERENCES task_priority (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('ALTER TABLE task ADD CONSTRAINT FK_527EDB2559EC7D60 FOREIGN KEY (assignee_id) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('ALTER TABLE task ADD CONSTRAINT FK_527EDB25FE54D947 FOREIGN KEY (group_id) REFERENCES task_group (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('ALTER TABLE task ADD CONSTRAINT FK_527EDB25166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE');
$this->addSql('ALTER TABLE task_task_type ADD CONSTRAINT FK_80470E038DB60186 FOREIGN KEY (task_id) REFERENCES task (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE task_task_type ADD CONSTRAINT FK_80470E03DAADA679 FOREIGN KEY (task_type_id) REFERENCES task_type (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE task_group ADD CONSTRAINT FK_AA645FE5166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE task DROP CONSTRAINT FK_527EDB256BF700BD');
$this->addSql('ALTER TABLE task DROP CONSTRAINT FK_527EDB259F2256F');
$this->addSql('ALTER TABLE task DROP CONSTRAINT FK_527EDB25497B19F9');
$this->addSql('ALTER TABLE task DROP CONSTRAINT FK_527EDB2559EC7D60');
$this->addSql('ALTER TABLE task DROP CONSTRAINT FK_527EDB25FE54D947');
$this->addSql('ALTER TABLE task DROP CONSTRAINT FK_527EDB25166D1F9C');
$this->addSql('ALTER TABLE task_task_type DROP CONSTRAINT FK_80470E038DB60186');
$this->addSql('ALTER TABLE task_task_type DROP CONSTRAINT FK_80470E03DAADA679');
$this->addSql('ALTER TABLE task_group DROP CONSTRAINT FK_AA645FE5166D1F9C');
$this->addSql('DROP TABLE task');
$this->addSql('DROP TABLE task_task_type');
$this->addSql('DROP TABLE task_effort');
$this->addSql('DROP TABLE task_group');
$this->addSql('DROP TABLE task_priority');
$this->addSql('DROP TABLE task_status');
$this->addSql('DROP TABLE task_type');
}
}

214
src/Entity/Task.php Normal file
View File

@@ -0,0 +1,214 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Repository\TaskRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Patch(security: "is_granted('ROLE_ADMIN')"),
new Delete(security: "is_granted('ROLE_ADMIN')"),
],
normalizationContext: ['groups' => ['task:read']],
denormalizationContext: ['groups' => ['task:write']],
order: ['id' => 'DESC'],
)]
#[ApiFilter(SearchFilter::class, properties: ['project' => 'exact', 'group' => 'exact'])]
#[ORM\Entity(repositoryClass: TaskRepository::class)]
class Task
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['task:read'])]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['task:read', 'task:write'])]
private ?string $title = null;
#[ORM\Column(type: 'text', nullable: true)]
#[Groups(['task:read', 'task:write'])]
private ?string $description = null;
#[ORM\ManyToOne(targetEntity: TaskStatus::class)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
#[Groups(['task:read', 'task:write'])]
private ?TaskStatus $status = null;
#[ORM\ManyToOne(targetEntity: TaskEffort::class)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
#[Groups(['task:read', 'task:write'])]
private ?TaskEffort $effort = null;
#[ORM\ManyToOne(targetEntity: TaskPriority::class)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
#[Groups(['task:read', 'task:write'])]
private ?TaskPriority $priority = null;
#[ORM\ManyToOne(targetEntity: User::class)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
#[Groups(['task:read', 'task:write'])]
private ?User $assignee = null;
#[ORM\ManyToOne(targetEntity: TaskGroup::class)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
#[Groups(['task:read', 'task:write'])]
private ?TaskGroup $group = null;
#[ORM\ManyToOne(targetEntity: Project::class)]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
#[Groups(['task:read', 'task:write'])]
private ?Project $project = null;
/** @var Collection<int, TaskType> */
#[ORM\ManyToMany(targetEntity: TaskType::class)]
#[ORM\JoinTable(name: 'task_task_type')]
#[Groups(['task:read', 'task:write'])]
private Collection $types;
public function __construct()
{
$this->types = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
public function getStatus(): ?TaskStatus
{
return $this->status;
}
public function setStatus(?TaskStatus $status): static
{
$this->status = $status;
return $this;
}
public function getEffort(): ?TaskEffort
{
return $this->effort;
}
public function setEffort(?TaskEffort $effort): static
{
$this->effort = $effort;
return $this;
}
public function getPriority(): ?TaskPriority
{
return $this->priority;
}
public function setPriority(?TaskPriority $priority): static
{
$this->priority = $priority;
return $this;
}
public function getAssignee(): ?User
{
return $this->assignee;
}
public function setAssignee(?User $assignee): static
{
$this->assignee = $assignee;
return $this;
}
public function getGroup(): ?TaskGroup
{
return $this->group;
}
public function setGroup(?TaskGroup $group): static
{
$this->group = $group;
return $this;
}
public function getProject(): ?Project
{
return $this->project;
}
public function setProject(?Project $project): static
{
$this->project = $project;
return $this;
}
/** @return Collection<int, TaskType> */
public function getTypes(): Collection
{
return $this->types;
}
public function addType(TaskType $type): static
{
if (!$this->types->contains($type)) {
$this->types->add($type);
}
return $this;
}
public function removeType(TaskType $type): static
{
$this->types->removeElement($type);
return $this;
}
}

58
src/Entity/TaskEffort.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Repository\TaskEffortRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Patch(security: "is_granted('ROLE_ADMIN')"),
new Delete(security: "is_granted('ROLE_ADMIN')"),
],
normalizationContext: ['groups' => ['task_effort:read']],
denormalizationContext: ['groups' => ['task_effort:write']],
order: ['label' => 'ASC'],
)]
#[ORM\Entity(repositoryClass: TaskEffortRepository::class)]
class TaskEffort
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['task_effort:read', 'task:read'])]
private ?int $id = null;
#[ORM\Column(length: 50)]
#[Groups(['task_effort:read', 'task_effort:write', 'task:read'])]
private ?string $label = null;
public function getId(): ?int
{
return $this->id;
}
public function getLabel(): ?string
{
return $this->label;
}
public function setLabel(string $label): static
{
$this->label = $label;
return $this;
}
}

110
src/Entity/TaskGroup.php Normal file
View File

@@ -0,0 +1,110 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Repository\TaskGroupRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Patch(security: "is_granted('ROLE_ADMIN')"),
new Delete(security: "is_granted('ROLE_ADMIN')"),
],
normalizationContext: ['groups' => ['task_group:read']],
denormalizationContext: ['groups' => ['task_group:write']],
order: ['title' => 'ASC'],
)]
#[ApiFilter(SearchFilter::class, properties: ['project' => 'exact'])]
#[ORM\Entity(repositoryClass: TaskGroupRepository::class)]
class TaskGroup
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['task_group:read', 'task:read'])]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['task_group:read', 'task_group:write', 'task:read'])]
private ?string $title = null;
#[ORM\Column(type: 'text', nullable: true)]
#[Groups(['task_group:read', 'task_group:write'])]
private ?string $description = null;
#[ORM\Column(length: 7)]
#[Groups(['task_group:read', 'task_group:write', 'task:read'])]
private ?string $color = '#222783';
#[ORM\ManyToOne(targetEntity: Project::class)]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
#[Groups(['task_group:read', 'task_group:write'])]
private ?Project $project = null;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
public function getColor(): ?string
{
return $this->color;
}
public function setColor(string $color): static
{
$this->color = $color;
return $this;
}
public function getProject(): ?Project
{
return $this->project;
}
public function setProject(?Project $project): static
{
$this->project = $project;
return $this;
}
}

View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Repository\TaskPriorityRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Patch(security: "is_granted('ROLE_ADMIN')"),
new Delete(security: "is_granted('ROLE_ADMIN')"),
],
normalizationContext: ['groups' => ['task_priority:read']],
denormalizationContext: ['groups' => ['task_priority:write']],
order: ['label' => 'ASC'],
)]
#[ORM\Entity(repositoryClass: TaskPriorityRepository::class)]
class TaskPriority
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['task_priority:read', 'task:read'])]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['task_priority:read', 'task_priority:write', 'task:read'])]
private ?string $label = null;
#[ORM\Column(length: 7)]
#[Groups(['task_priority:read', 'task_priority:write', 'task:read'])]
private ?string $color = '#222783';
public function getId(): ?int
{
return $this->id;
}
public function getLabel(): ?string
{
return $this->label;
}
public function setLabel(string $label): static
{
$this->label = $label;
return $this;
}
public function getColor(): ?string
{
return $this->color;
}
public function setColor(string $color): static
{
$this->color = $color;
return $this;
}
}

90
src/Entity/TaskStatus.php Normal file
View File

@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Repository\TaskStatusRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Patch(security: "is_granted('ROLE_ADMIN')"),
new Delete(security: "is_granted('ROLE_ADMIN')"),
],
normalizationContext: ['groups' => ['task_status:read']],
denormalizationContext: ['groups' => ['task_status:write']],
order: ['position' => 'ASC'],
)]
#[ORM\Entity(repositoryClass: TaskStatusRepository::class)]
class TaskStatus
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['task_status:read', 'task:read'])]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['task_status:read', 'task_status:write', 'task:read'])]
private ?string $label = null;
#[ORM\Column(length: 7)]
#[Groups(['task_status:read', 'task_status:write', 'task:read'])]
private ?string $color = '#222783';
#[ORM\Column]
#[Groups(['task_status:read', 'task_status:write', 'task:read'])]
private ?int $position = 0;
public function getId(): ?int
{
return $this->id;
}
public function getLabel(): ?string
{
return $this->label;
}
public function setLabel(string $label): static
{
$this->label = $label;
return $this;
}
public function getColor(): ?string
{
return $this->color;
}
public function setColor(string $color): static
{
$this->color = $color;
return $this;
}
public function getPosition(): ?int
{
return $this->position;
}
public function setPosition(int $position): static
{
$this->position = $position;
return $this;
}
}

74
src/Entity/TaskType.php Normal file
View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\Repository\TaskTypeRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
new Post(security: "is_granted('ROLE_ADMIN')"),
new Patch(security: "is_granted('ROLE_ADMIN')"),
new Delete(security: "is_granted('ROLE_ADMIN')"),
],
normalizationContext: ['groups' => ['task_type:read']],
denormalizationContext: ['groups' => ['task_type:write']],
order: ['label' => 'ASC'],
)]
#[ORM\Entity(repositoryClass: TaskTypeRepository::class)]
class TaskType
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['task_type:read', 'task:read'])]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['task_type:read', 'task_type:write', 'task:read'])]
private ?string $label = null;
#[ORM\Column(length: 7)]
#[Groups(['task_type:read', 'task_type:write', 'task:read'])]
private ?string $color = '#222783';
public function getId(): ?int
{
return $this->id;
}
public function getLabel(): ?string
{
return $this->label;
}
public function setLabel(string $label): static
{
$this->label = $label;
return $this;
}
public function getColor(): ?string
{
return $this->color;
}
public function setColor(string $color): static
{
$this->color = $color;
return $this;
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\TaskEffort;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
class TaskEffortRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, TaskEffort::class);
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\TaskGroup;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
class TaskGroupRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, TaskGroup::class);
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\TaskPriority;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
class TaskPriorityRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, TaskPriority::class);
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\Task;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
class TaskRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Task::class);
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\TaskStatus;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
class TaskStatusRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, TaskStatus::class);
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\TaskType;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
class TaskTypeRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, TaskType::class);
}
}