feat : add collaborators ManyToMany on Task entity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-04-09 09:53:53 +02:00
parent 916f4ae101
commit e41caa9cfe

View File

@@ -38,7 +38,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
denormalizationContext: ['groups' => ['task:write']],
order: ['id' => 'DESC'],
)]
#[ApiFilter(SearchFilter::class, properties: ['project' => 'exact', 'group' => 'exact', 'assignee' => 'exact', 'priority' => 'exact', 'effort' => 'exact', 'tags' => 'exact', 'status' => 'exact'])]
#[ApiFilter(SearchFilter::class, properties: ['project' => 'exact', 'group' => 'exact', 'assignee' => 'exact', 'collaborators' => 'exact', 'priority' => 'exact', 'effort' => 'exact', 'tags' => 'exact', 'status' => 'exact'])]
#[ApiFilter(DateFilter::class, properties: ['scheduledStart', 'scheduledEnd', 'deadline'])]
#[ApiFilter(BooleanFilter::class, properties: ['archived', 'syncToCalendar'])]
#[ApiFilter(OrderFilter::class, properties: ['scheduledStart', 'deadline'])]
@@ -85,6 +85,16 @@ class Task
#[Groups(['task:read', 'task:write'])]
private ?User $assignee = null;
/** @var Collection<int, User> */
#[ORM\ManyToMany(targetEntity: User::class)]
#[ORM\JoinTable(
name: 'task_collaborator',
joinColumns: [new ORM\JoinColumn(name: 'task_id', referencedColumnName: 'id', onDelete: 'CASCADE')],
inverseJoinColumns: [new ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', onDelete: 'CASCADE')],
)]
#[Groups(['task:read', 'task:write'])]
private Collection $collaborators;
#[ORM\ManyToOne(targetEntity: TaskGroup::class)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
#[Groups(['task:read', 'task:write'])]
@@ -152,8 +162,9 @@ class Task
public function __construct()
{
$this->tags = new ArrayCollection();
$this->documents = new ArrayCollection();
$this->tags = new ArrayCollection();
$this->documents = new ArrayCollection();
$this->collaborators = new ArrayCollection();
}
public function getId(): ?int
@@ -245,6 +256,28 @@ class Task
return $this;
}
/** @return Collection<int, User> */
public function getCollaborators(): Collection
{
return $this->collaborators;
}
public function addCollaborator(User $user): static
{
if (!$this->collaborators->contains($user)) {
$this->collaborators->add($user);
}
return $this;
}
public function removeCollaborator(User $user): static
{
$this->collaborators->removeElement($user);
return $this;
}
public function getGroup(): ?TaskGroup
{
return $this->group;
@@ -434,4 +467,15 @@ class Task
;
}
}
#[Assert\Callback]
public function validateCollaborators(ExecutionContextInterface $context): void
{
if (null !== $this->assignee && $this->collaborators->contains($this->assignee)) {
$context->buildViolation('The assignee cannot also be a collaborator.')
->atPath('collaborators')
->addViolation()
;
}
}
}