From 45b1da60856f3458c8f62a05fc838fe8f3e85c75 Mon Sep 17 00:00:00 2001 From: jgetu Date: Thu, 23 Oct 2025 18:31:42 +0200 Subject: [PATCH] =?UTF-8?q?init=20:=20scripts=20BD=20+=20entit=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 +- _baseScripts/create user.sql | 3 + _baseScripts/structure.sql | 40 ++++++++ src/Entity/AssistantIa.php | 128 ++++++++++++++++++++++++ src/Entity/ContribIa.php | 186 +++++++++++++++++++++++++++++++++++ src/Entity/Contribution.php | 171 ++++++++++++++++++++++++++++++++ src/Entity/Membre.php | 121 +++++++++++++++++++++++ src/Entity/Projet.php | 167 +++++++++++++++++++++++++++++++ 8 files changed, 817 insertions(+), 1 deletion(-) create mode 100644 _baseScripts/create user.sql create mode 100644 _baseScripts/structure.sql create mode 100644 src/Entity/AssistantIa.php create mode 100644 src/Entity/ContribIa.php create mode 100644 src/Entity/Contribution.php create mode 100644 src/Entity/Membre.php create mode 100644 src/Entity/Projet.php diff --git a/.env b/.env index 9fdb8fa..dffaa90 100644 --- a/.env +++ b/.env @@ -32,7 +32,7 @@ DEFAULT_URI=http://localhost # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4" -DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" +# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" ###< doctrine/doctrine-bundle ### ###> symfony/messenger ### diff --git a/_baseScripts/create user.sql b/_baseScripts/create user.sql new file mode 100644 index 0000000..a9a0650 --- /dev/null +++ b/_baseScripts/create user.sql @@ -0,0 +1,3 @@ +create user 'appcontrib'@'%' identified by 'abc123'; +grant all on contribV2.* to 'appcontrib'@'%'; +flush privileges; diff --git a/_baseScripts/structure.sql b/_baseScripts/structure.sql new file mode 100644 index 0000000..639af80 --- /dev/null +++ b/_baseScripts/structure.sql @@ -0,0 +1,40 @@ +create table membre( + id int auto_increment primary key, + nom varchar(50) not null, + prenom varchar(50) not null, + email varchar(100) not null unique +); + +create table projet( + id int auto_increment primary key, + nom varchar(50) not null, + commentaire text, + date_lancement date, + date_cloture date, + statut varchar(20) not null +); + +create table contribution( + id int auto_increment primary key, + membre_id int not null references membre(id), + projet_id int not null references projet(id), + date_contribution date not null, + commentaire text, + duree int default 0 +); + +create table assistant_ia( + id int auto_increment primary key, + nom varchar(50) not null +); + +create table contrib_ia( + id int auto_increment primary key, + assistant_ia_id int not null references assistant_ia(id), + contribution_id int not null references contribution(id), + evaluation_pertinence int check (evaluation_pertinence >= 1 and evaluation_pertinence <= 5), + evaluation_temps int check (evaluation_temps >= 1 and evaluation_temps <= 5), + commentaire text +); + + diff --git a/src/Entity/AssistantIa.php b/src/Entity/AssistantIa.php new file mode 100644 index 0000000..c94fc5c --- /dev/null +++ b/src/Entity/AssistantIa.php @@ -0,0 +1,128 @@ +contribIas = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getNom(): ?string + { + return $this->nom; + } + + public function setNom(string $nom): static + { + $this->nom = $nom; + + return $this; + } + + /** + * @return Collection + */ + public function getContribIas(): Collection + { + return $this->contribIas; + } + + public function addContribIa(ContribIa $contribIa): static + { + if (!$this->contribIas->contains($contribIa)) { + $this->contribIas->add($contribIa); + $contribIa->setAssistantIa($this); + } + + return $this; + } + + public function removeContribIa(ContribIa $contribIa): static + { + if ($this->contribIas->removeElement($contribIa)) { + // set the owning side to null (unless already changed) + if ($contribIa->getAssistantIa() === $this) { + $contribIa->setAssistantIa(null); + } + } + + return $this; + } + + /** + * Calcule la moyenne des évaluations de pertinence + */ + public function getMoyennePertinence(): ?float + { + $total = 0; + $count = 0; + + foreach ($this->contribIas as $contribIa) { + if ($contribIa->getEvaluationPertinence() !== null) { + $total += $contribIa->getEvaluationPertinence(); + $count++; + } + } + + return $count > 0 ? round($total / $count, 2) : null; + } + + /** + * Calcule la moyenne des évaluations de temps + */ + public function getMoyenneTemps(): ?float + { + $total = 0; + $count = 0; + + foreach ($this->contribIas as $contribIa) { + if ($contribIa->getEvaluationTemps() !== null) { + $total += $contribIa->getEvaluationTemps(); + $count++; + } + } + + return $count > 0 ? round($total / $count, 2) : null; + } + + /** + * Retourne le nombre total de contributions IA + */ + public function getNombreContributions(): int + { + return $this->contribIas->count(); + } + + public function __toString(): string + { + return $this->nom ?? ''; + } +} \ No newline at end of file diff --git a/src/Entity/ContribIa.php b/src/Entity/ContribIa.php new file mode 100644 index 0000000..18999d8 --- /dev/null +++ b/src/Entity/ContribIa.php @@ -0,0 +1,186 @@ += 1 AND evaluation_pertinence <= 5' + ), + new ORM\CheckConstraint( + name: 'check_evaluation_temps', + expression: 'evaluation_temps >= 1 AND evaluation_temps <= 5' + ), +])] +class ContribIa +{ + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + #[ORM\ManyToOne(targetEntity: AssistantIa::class, inversedBy: 'contribIas')] + #[ORM\JoinColumn(nullable: false)] + #[Assert\NotNull(message: 'L\'assistant IA est obligatoire.')] + private ?AssistantIa $assistantIa = null; + + #[ORM\ManyToOne(targetEntity: Contribution::class, inversedBy: 'contribIas')] + #[ORM\JoinColumn(nullable: false)] + #[Assert\NotNull(message: 'La contribution est obligatoire.')] + private ?Contribution $contribution = null; + + #[ORM\Column(type: 'integer', nullable: true)] + #[Assert\Range( + min: 1, + max: 5, + notInRangeMessage: 'L\'évaluation de pertinence doit être comprise entre {{ min }} et {{ max }}.' + )] + private ?int $evaluationPertinence = null; + + #[ORM\Column(type: 'integer', nullable: true)] + #[Assert\Range( + min: 1, + max: 5, + notInRangeMessage: 'L\'évaluation de temps doit être comprise entre {{ min }} et {{ max }}.' + )] + private ?int $evaluationTemps = null; + + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $commentaire = null; + + public function getId(): ?int + { + return $this->id; + } + + public function getAssistantIa(): ?AssistantIa + { + return $this->assistantIa; + } + + public function setAssistantIa(?AssistantIa $assistantIa): static + { + $this->assistantIa = $assistantIa; + + return $this; + } + + public function getContribution(): ?Contribution + { + return $this->contribution; + } + + public function setContribution(?Contribution $contribution): static + { + $this->contribution = $contribution; + + return $this; + } + + public function getEvaluationPertinence(): ?int + { + return $this->evaluationPertinence; + } + + public function setEvaluationPertinence(?int $evaluationPertinence): static + { + $this->evaluationPertinence = $evaluationPertinence; + + return $this; + } + + public function getEvaluationTemps(): ?int + { + return $this->evaluationTemps; + } + + public function setEvaluationTemps(?int $evaluationTemps): static + { + $this->evaluationTemps = $evaluationTemps; + + return $this; + } + + public function getCommentaire(): ?string + { + return $this->commentaire; + } + + public function setCommentaire(?string $commentaire): static + { + $this->commentaire = $commentaire; + + return $this; + } + + /** + * Retourne la moyenne des deux évaluations + */ + public function getMoyenneEvaluation(): ?float + { + if ($this->evaluationPertinence === null && $this->evaluationTemps === null) { + return null; + } + + $count = 0; + $total = 0; + + if ($this->evaluationPertinence !== null) { + $total += $this->evaluationPertinence; + $count++; + } + + if ($this->evaluationTemps !== null) { + $total += $this->evaluationTemps; + $count++; + } + + return round($total / $count, 2); + } + + /** + * Retourne un libellé pour l'évaluation de pertinence + */ + public function getLibellePertinence(): string + { + return match ($this->evaluationPertinence) { + 1 => 'Très faible', + 2 => 'Faible', + 3 => 'Moyen', + 4 => 'Bon', + 5 => 'Excellent', + default => 'Non évalué', + }; + } + + /** + * Retourne un libellé pour l'évaluation de temps + */ + public function getLibelleTemps(): string + { + return match ($this->evaluationTemps) { + 1 => 'Très lent', + 2 => 'Lent', + 3 => 'Moyen', + 4 => 'Rapide', + 5 => 'Très rapide', + default => 'Non évalué', + }; + } + + public function __toString(): string + { + return sprintf( + 'IA: %s - Contribution: %s', + $this->assistantIa ? $this->assistantIa->getNom() : '', + $this->contribution ? $this->contribution->__toString() : '' + ); + } +} \ No newline at end of file diff --git a/src/Entity/Contribution.php b/src/Entity/Contribution.php new file mode 100644 index 0000000..43ea563 --- /dev/null +++ b/src/Entity/Contribution.php @@ -0,0 +1,171 @@ + 0])] + #[Assert\PositiveOrZero(message: 'La durée doit être positive ou nulle.')] + private ?int $duree = 0; + + #[ORM\OneToMany(targetEntity: ContribIa::class, mappedBy: 'contribution', cascade: ['persist', 'remove'], orphanRemoval: true)] + private Collection $contribIas; + + public function __construct() + { + $this->contribIas = new ArrayCollection(); + $this->dateContribution = new \DateTime(); + $this->duree = 0; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getMembre(): ?Membre + { + return $this->membre; + } + + public function setMembre(?Membre $membre): static + { + $this->membre = $membre; + + return $this; + } + + public function getProjet(): ?Projet + { + return $this->projet; + } + + public function setProjet(?Projet $projet): static + { + $this->projet = $projet; + + return $this; + } + + public function getDateContribution(): ?\DateTimeInterface + { + return $this->dateContribution; + } + + public function setDateContribution(\DateTimeInterface $dateContribution): static + { + $this->dateContribution = $dateContribution; + + return $this; + } + + public function getCommentaire(): ?string + { + return $this->commentaire; + } + + public function setCommentaire(?string $commentaire): static + { + $this->commentaire = $commentaire; + + return $this; + } + + public function getDuree(): ?int + { + return $this->duree; + } + + public function setDuree(int $duree): static + { + $this->duree = $duree; + + return $this; + } + + /** + * @return Collection + */ + public function getContribIas(): Collection + { + return $this->contribIas; + } + + public function addContribIa(ContribIa $contribIa): static + { + if (!$this->contribIas->contains($contribIa)) { + $this->contribIas->add($contribIa); + $contribIa->setContribution($this); + } + + return $this; + } + + public function removeContribIa(ContribIa $contribIa): static + { + if ($this->contribIas->removeElement($contribIa)) { + // set the owning side to null (unless already changed) + if ($contribIa->getContribution() === $this) { + $contribIa->setContribution(null); + } + } + + return $this; + } + + /** + * Retourne la durée formatée en heures et minutes + */ + public function getDureeFormatee(): string + { + $heures = floor($this->duree / 60); + $minutes = $this->duree % 60; + + if ($heures > 0) { + return sprintf('%dh%02d', $heures, $minutes); + } + + return sprintf('%d min', $minutes); + } + + public function __toString(): string + { + return sprintf( + '%s - %s (%s)', + $this->membre ? $this->membre->__toString() : '', + $this->projet ? $this->projet->getNom() : '', + $this->dateContribution ? $this->dateContribution->format('d/m/Y') : '' + ); + } +} \ No newline at end of file diff --git a/src/Entity/Membre.php b/src/Entity/Membre.php new file mode 100644 index 0000000..a8d20c1 --- /dev/null +++ b/src/Entity/Membre.php @@ -0,0 +1,121 @@ +contributions = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getNom(): ?string + { + return $this->nom; + } + + public function setNom(string $nom): static + { + $this->nom = $nom; + + return $this; + } + + public function getPrenom(): ?string + { + return $this->prenom; + } + + public function setPrenom(string $prenom): static + { + $this->prenom = $prenom; + + return $this; + } + + public function getEmail(): ?string + { + return $this->email; + } + + public function setEmail(string $email): static + { + $this->email = $email; + + return $this; + } + + /** + * @return Collection + */ + public function getContributions(): Collection + { + return $this->contributions; + } + + public function addContribution(Contribution $contribution): static + { + if (!$this->contributions->contains($contribution)) { + $this->contributions->add($contribution); + $contribution->setMembre($this); + } + + return $this; + } + + public function removeContribution(Contribution $contribution): static + { + if ($this->contributions->removeElement($contribution)) { + // set the owning side to null (unless already changed) + if ($contribution->getMembre() === $this) { + $contribution->setMembre(null); + } + } + + return $this; + } + + public function __toString(): string + { + return $this->prenom . ' ' . $this->nom; + } +} \ No newline at end of file diff --git a/src/Entity/Projet.php b/src/Entity/Projet.php new file mode 100644 index 0000000..0670b65 --- /dev/null +++ b/src/Entity/Projet.php @@ -0,0 +1,167 @@ +contributions = new ArrayCollection(); + $this->statut = self::STATUT_EN_ATTENTE; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getNom(): ?string + { + return $this->nom; + } + + public function setNom(string $nom): static + { + $this->nom = $nom; + + return $this; + } + + public function getCommentaire(): ?string + { + return $this->commentaire; + } + + public function setCommentaire(?string $commentaire): static + { + $this->commentaire = $commentaire; + + return $this; + } + + public function getDateLancement(): ?\DateTimeInterface + { + return $this->dateLancement; + } + + public function setDateLancement(?\DateTimeInterface $dateLancement): static + { + $this->dateLancement = $dateLancement; + + return $this; + } + + public function getDateCloture(): ?\DateTimeInterface + { + return $this->dateCloture; + } + + public function setDateCloture(?\DateTimeInterface $dateCloture): static + { + $this->dateCloture = $dateCloture; + + return $this; + } + + public function getStatut(): ?string + { + return $this->statut; + } + + public function setStatut(string $statut): static + { + $this->statut = $statut; + + return $this; + } + + /** + * @return Collection + */ + public function getContributions(): Collection + { + return $this->contributions; + } + + public function addContribution(Contribution $contribution): static + { + if (!$this->contributions->contains($contribution)) { + $this->contributions->add($contribution); + $contribution->setProjet($this); + } + + return $this; + } + + public function removeContribution(Contribution $contribution): static + { + if ($this->contributions->removeElement($contribution)) { + // set the owning side to null (unless already changed) + if ($contribution->getProjet() === $this) { + $contribution->setProjet(null); + } + } + + return $this; + } + + public function __toString(): string + { + return $this->nom ?? ''; + } + + public static function getStatutChoices(): array + { + return [ + 'En attente' => self::STATUT_EN_ATTENTE, + 'En cours' => self::STATUT_EN_COURS, + 'Terminé' => self::STATUT_TERMINE, + 'Annulé' => self::STATUT_ANNULE, + ]; + } +} \ No newline at end of file