Files
Lesstime/migrations/Version20260622090000.php
T
Matthieu a18e1f575f
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 1m11s
Pull Request — Quality gate / Frontend (build) (pull_request) Successful in 1m17s
refactor(client-portal) : remove client portal feature entirely
- drop ClientPortal module, ClientTicket entity, ROLE_CLIENT and all couplings (Task, TaskDocument, User, Notification) back to an internal-only model

- migration drops client_ticket / user_allowed_projects / related FK columns and removes leftover external client accounts (would otherwise be promoted to ROLE_USER)

- remove client-portal frontend module, admin tickets tab, user portal section, portal nav item and portal/clientTicket i18n keys

- fix directory nav icon (invalid mdi:contact-multiple-outline -> mdi:card-account-details-outline)

- add 'make sync-permissions' target, wire it into install/db-reset and the prod deploy script
2026-06-22 09:49:44 +02:00

121 lines
7.8 KiB
PHP

<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Remove the client portal entirely (reverses phases 1 & 3).
*
* - Drops notification.related_ticket_id (FK/index/column).
* - Restores task_document to a task-only model: drops the CHECK constraint and
* client_ticket_id, removes orphan client-ticket-only documents, makes task_id
* NOT NULL again.
* - Drops task.client_ticket_id.
* - Drops the user_allowed_projects join table and user.client_id.
* - Drops the client_ticket table.
* - Deletes leftover client accounts (roles contains ROLE_CLIENT): with the portal
* gone every user now resolves to ROLE_USER, so external client accounts MUST be
* removed to avoid silently granting them internal access.
*
* Lowercase SQL columns; "user" table is quoted. down() recreates the schema
* (structure only — deleted client accounts/tickets are not restored).
*/
final class Version20260622090000 extends AbstractMigration
{
public function getDescription(): string
{
return 'Remove client portal: drop client_ticket, related portal columns/links and external client accounts';
}
public function up(Schema $schema): void
{
// --- notification.related_ticket_id (phase 3) ---
$this->addSql('ALTER TABLE notification DROP CONSTRAINT FK_BF5476CA98F144DB');
$this->addSql('DROP INDEX idx_notification_related_ticket');
$this->addSql('ALTER TABLE notification DROP related_ticket_id');
// --- task_document: back to task-only ---
$this->addSql('ALTER TABLE task_document DROP CONSTRAINT chk_task_document_target');
$this->addSql('ALTER TABLE task_document DROP CONSTRAINT FK_98A9603A9B2097DD');
$this->addSql('DROP INDEX IDX_98A9603A9B2097DD');
// Remove documents attached only to a client ticket before re-enforcing NOT NULL.
$this->addSql('DELETE FROM task_document WHERE task_id IS NULL');
$this->addSql('ALTER TABLE task_document DROP client_ticket_id');
$this->addSql('ALTER TABLE task_document ALTER task_id SET NOT NULL');
// --- task.client_ticket_id ---
$this->addSql('ALTER TABLE task DROP CONSTRAINT FK_527EDB259B2097DD');
$this->addSql('DROP INDEX IDX_527EDB259B2097DD');
$this->addSql('ALTER TABLE task DROP client_ticket_id');
// --- user_allowed_projects ---
$this->addSql('ALTER TABLE user_allowed_projects DROP CONSTRAINT FK_B3E0FC97A76ED395');
$this->addSql('ALTER TABLE user_allowed_projects DROP CONSTRAINT FK_B3E0FC97166D1F9C');
$this->addSql('DROP TABLE user_allowed_projects');
// --- user.client_id ---
$this->addSql('ALTER TABLE "user" DROP CONSTRAINT FK_8D93D64919EB6921');
$this->addSql('DROP INDEX IDX_8D93D64919EB6921');
$this->addSql('ALTER TABLE "user" DROP client_id');
// --- client_ticket table ---
$this->addSql('ALTER TABLE client_ticket DROP CONSTRAINT FK_C206E610166D1F9C');
$this->addSql('ALTER TABLE client_ticket DROP CONSTRAINT FK_C206E61079F7D87D');
$this->addSql('ALTER TABLE client_ticket DROP CONSTRAINT FK_C206E610DE12AB56');
$this->addSql('ALTER TABLE client_ticket DROP CONSTRAINT FK_C206E61016FE72E1');
$this->addSql('DROP TABLE client_ticket');
// --- external client accounts ---
$this->addSql('DELETE FROM "user" WHERE roles::text LIKE \'%ROLE_CLIENT%\'');
}
public function down(Schema $schema): void
{
// --- client_ticket table ---
$this->addSql('CREATE TABLE client_ticket (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, number INT NOT NULL, type VARCHAR(16) NOT NULL, title VARCHAR(255) NOT NULL, description TEXT NOT NULL, url VARCHAR(1024) DEFAULT NULL, status VARCHAR(16) NOT NULL, status_comment TEXT DEFAULT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, project_id INT NOT NULL, submitted_by_id INT DEFAULT NULL, created_by INT DEFAULT NULL, updated_by INT DEFAULT NULL, PRIMARY KEY (id))');
$this->addSql('CREATE UNIQUE INDEX uniq_client_ticket_project_number ON client_ticket (project_id, number)');
$this->addSql('CREATE INDEX idx_client_ticket_project ON client_ticket (project_id)');
$this->addSql('CREATE INDEX idx_client_ticket_submitted_by ON client_ticket (submitted_by_id)');
$this->addSql('CREATE INDEX idx_client_ticket_status_project ON client_ticket (status, project_id)');
$this->addSql('CREATE INDEX IDX_C206E610DE12AB56 ON client_ticket (created_by)');
$this->addSql('CREATE INDEX IDX_C206E61016FE72E1 ON client_ticket (updated_by)');
$this->addSql('ALTER TABLE client_ticket ADD CONSTRAINT FK_C206E610166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE');
$this->addSql('ALTER TABLE client_ticket ADD CONSTRAINT FK_C206E61079F7D87D FOREIGN KEY (submitted_by_id) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('ALTER TABLE client_ticket ADD CONSTRAINT FK_C206E610DE12AB56 FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('ALTER TABLE client_ticket ADD CONSTRAINT FK_C206E61016FE72E1 FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE');
// --- user.client_id ---
$this->addSql('ALTER TABLE "user" ADD client_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE "user" ADD CONSTRAINT FK_8D93D64919EB6921 FOREIGN KEY (client_id) REFERENCES client (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('CREATE INDEX IDX_8D93D64919EB6921 ON "user" (client_id)');
// --- user_allowed_projects ---
$this->addSql('CREATE TABLE user_allowed_projects (user_id INT NOT NULL, project_id INT NOT NULL, PRIMARY KEY (user_id, project_id))');
$this->addSql('CREATE INDEX IDX_B3E0FC97A76ED395 ON user_allowed_projects (user_id)');
$this->addSql('CREATE INDEX IDX_B3E0FC97166D1F9C ON user_allowed_projects (project_id)');
$this->addSql('ALTER TABLE user_allowed_projects ADD CONSTRAINT FK_B3E0FC97A76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE CASCADE NOT DEFERRABLE');
$this->addSql('ALTER TABLE user_allowed_projects ADD CONSTRAINT FK_B3E0FC97166D1F9C FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE NOT DEFERRABLE');
// --- task.client_ticket_id ---
$this->addSql('ALTER TABLE task ADD client_ticket_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE task ADD CONSTRAINT FK_527EDB259B2097DD FOREIGN KEY (client_ticket_id) REFERENCES client_ticket (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('CREATE INDEX IDX_527EDB259B2097DD ON task (client_ticket_id)');
// --- task_document generalisation ---
$this->addSql('ALTER TABLE task_document ALTER task_id DROP NOT NULL');
$this->addSql('ALTER TABLE task_document ADD client_ticket_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE task_document ADD CONSTRAINT FK_98A9603A9B2097DD FOREIGN KEY (client_ticket_id) REFERENCES client_ticket (id) ON DELETE CASCADE NOT DEFERRABLE');
$this->addSql('CREATE INDEX IDX_98A9603A9B2097DD ON task_document (client_ticket_id)');
$this->addSql('ALTER TABLE task_document ADD CONSTRAINT chk_task_document_target CHECK (task_id IS NOT NULL OR client_ticket_id IS NOT NULL)');
// --- notification.related_ticket_id ---
$this->addSql('ALTER TABLE notification ADD related_ticket_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE notification ADD CONSTRAINT FK_BF5476CA98F144DB FOREIGN KEY (related_ticket_id) REFERENCES client_ticket (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('CREATE INDEX idx_notification_related_ticket ON notification (related_ticket_id)');
}
}