# AGENTS.md — Walk The Line Management

## 1. Purpose of this file

This file defines the operating rules for any coding or research agent working on the **Walk The Line Management** application.

It applies to the entire repository unless a more specific `AGENTS.md` is later added in a subdirectory.

The goal is not only to enforce coding conventions. This document defines how an agent must reason about the project, how it must plan changes, how it must protect existing business behavior, and how it must validate work before presenting it as complete.

The application is a long-lived business tool. Treat it as a production system, not as a disposable prototype.

---

## 2. Business context

Walk The Line Management is a Symfony application used to manage an artistic/music project and the operational work around it.

The application includes, among other areas:

- dashboard and operational follow-up;
- task / “À traiter” management;
- sales prospecting and follow-up workflows;
- concerts and dates;
- pricing simulation;
- quotes, invoices and conventions;
- technical sheets and stage plans;
- document management / GED;
- accounting;
- project-specific communications;
- public websites;
- email workflows;
- Google Calendar integration;
- Google Analytics integration;
- project-specific configuration;
- permissions and multi-project access control;
- security controls for authentication and administration.

The application is not a generic Symfony CRUD. Business workflows and usability matter at least as much as technical correctness.

Any implementation must preserve four dimensions at the same time:

1. **security**;
2. **business correctness**;
3. **UX/UI simplicity**;
4. **documentation consistency**.

---

## 3. Scope and authority of an agent

An agent may work on **all areas of the repository**, including:

- Symfony backend;
- Doctrine / database;
- Twig;
- CSS / JavaScript;
- UX/UI;
- integrations;
- security;
- documentation;
- public website code;
- internal tooling;
- configuration code.

### 3.1 Protected artistic media

Artistic media are protected assets.

Without explicit user authorization, an agent must **not modify**:

- images;
- photos;
- videos;
- audio files;
- artistic PDFs or visual assets;
- any other artistic media.

“Modify” includes, but is not limited to:

- cropping;
- compression;
- conversion;
- recoloring;
- retouching;
- replacement;
- regeneration;
- resizing;
- renaming when that would break references or asset intent.

The agent may reference these files, inspect them when useful, and update surrounding code when explicitly requested, but must not alter the media itself unless permission is explicit.

---

## 4. Operating modes: minor change vs major change

The agent must decide whether the requested work is **minor** or **major** before editing.

### 4.1 Minor change

A minor change is a bounded modification whose functional and architectural impact is limited, for example:

- adding a simple field;
- integrating a small API feature using existing patterns;
- fixing a bug;
- adding a small UI action;
- updating a form;
- adding a non-destructive migration;
- adjusting an existing workflow in a limited way;
- improving a single page without changing overall architecture.

For a clear minor change, the agent may proceed autonomously, provided it:

- modifies only what is necessary;
- preserves existing behavior outside scope;
- updates all required documentation;
- performs the expected validation steps;
- reports what changed.

### 4.2 Major change

A change must be treated as major when it includes one or more of the following:

- cross-cutting architecture changes;
- major business workflow changes;
- changes across many modules/pages;
- large database redesigns;
- new foundational dependencies;
- complex external integrations;
- authentication or authorization redesign;
- broad security work;
- broad UX redesign;
- large refactoring;
- restructuring that is difficult to revert;
- a request phrased broadly, such as “improve security”, “redesign the back office”, “simplify the UX”, or “modernize the architecture”.

For major changes, the agent must **not start implementation immediately**.

It must first produce an audit containing:

- current-state observations;
- identified problems;
- risks;
- proposed solution(s);
- trade-offs;
- planned tasks;
- expected impacted files/modules;
- database impact;
- security impact;
- UX/UI impact;
- documentation impact;
- testing/validation plan;
- rollout considerations.

Implementation starts only after the user validates the plan.

### 4.3 Ambiguity rule

If any meaningful ambiguity remains, ask the user.

Do not silently make a business or architectural choice when several valid approaches exist.

When multiple solutions are possible, compare them clearly and ask for a decision when the choice has meaningful consequences.

---

## 5. Change discipline

For a precise request:

- change the **strict minimum necessary**;
- avoid unrelated refactors;
- do not “clean up” surrounding code without a concrete reason;
- preserve behavior that was not explicitly requested to change.

For a broad request, larger modifications may be appropriate, but only after the audit/validation process described above.

A refactor is acceptable when it is necessary to make the requested change maintainable, safe, or comprehensible. When that happens, explain why the refactor is necessary.

---

## 6. Source of truth and documentation hierarchy

Use the following hierarchy when understanding the project:

1. **Current codebase** — actual implemented behavior.
2. **AGENTS.md** — engineering and agent operating rules.
3. **SPECIFICATIONS_FONCTIONNELLES.md** — business and functional reference.
4. **Dashboard user manual** — exhaustive end-user usage reference.
5. **demarrage_rapide.md** — setup and operational quick-start reference.
6. **CHANGELOG.md** — chronological history of versions and changes.
7. **Historical README_WTL_V*.md files** — archive only, not a source of truth.

If documentation contradicts current code, do not assume either is correct. Report the inconsistency and reconcile it as part of the task when relevant.

### 6.1 Historical README files

Existing `README_WTL_V*.md` files are historical archives.

They must not be used as authoritative current specifications.

Do not delete them automatically. They may be removed later after the important historical information has been consolidated into `CHANGELOG.md` and current documentation.

---

## 7. Documentation requirements

Documentation is part of the feature, not an optional follow-up.

For every meaningful user-visible or operational change, evaluate whether to update:

- `SPECIFICATIONS_FONCTIONNELLES.md`;
- the dashboard user manual;
- `demarrage_rapide.md`;
- `CHANGELOG.md`;
- `AGENTS.md` only when a durable rule, architectural convention, business workflow, or operating principle changes.

### 7.1 Dashboard user manual

The dashboard user manual must be written for a **beginner-level computer user**.

It should be as exhaustive and practical as possible.

Do not assume technical knowledge.

Explain:

- where to click;
- what each action does;
- what happens after the action;
- prerequisites;
- common mistakes;
- configuration procedures when relevant;
- consequences of destructive or sensitive actions.

### 7.2 CHANGELOG.md

Prefer a single `CHANGELOG.md` for version history going forward.

Each meaningful release/change should be added chronologically.

Keep entries factual and useful. Avoid duplicating full specifications.

---

## 8. Technology baseline

### 8.1 Backend

- Symfony 7.4
- PHP 8.4 in local development
- PHP 8.2 currently in production
- MariaDB in local development
- Doctrine ORM / Doctrine Migrations

### 8.2 Compatibility rule

Until production is upgraded, **all code must remain compatible with PHP 8.2**.

Do not use PHP 8.3/8.4-only language features in application code unless the production compatibility rule has explicitly changed.

The local environment may be newer than production; production compatibility takes priority.

### 8.3 Frontend

The existing back-office frontend primarily uses the existing stack, including:

- Bootstrap;
- jQuery;
- DataTables;
- Select2;
- CKEditor where already integrated;
- existing project JavaScript/CSS.

Inspect the current code before assuming a library is available on a given page.

Do not introduce a new frontend framework without a justified need and prior approval if the impact is significant.

---

## 9. Local development environment

Local development is performed with Docker Desktop and Docker Compose.

The main PHP/Symfony service is `web`.

Typical commands:

```bash
docker compose exec web php bin/console doctrine:migrations:migrate
docker compose exec web php bin/console doctrine:schema:validate
docker compose exec web php bin/console cache:clear
docker compose exec web php bin/console cache:warmup
```

Other commands may be used when necessary.

Before inventing custom procedures, inspect the repository and existing Docker configuration.

---

## 10. Doctrine and database rules

Database integrity is a hard requirement.

### 10.1 Migration immutability

A migration that has already been deployed to production, shared with other environments,
or otherwise established as part of the project history is immutable.

**Never modify an established migration.**
If it requires correction, create a new additive migration.

A migration newly created in the current unmerged feature branch may still be corrected
during implementation and validation, provided that:

- it has never been deployed to production;
- it has not become part of a shared/stable migration history;
- the local test database is restored or rolled back to a known pre-migration state before retesting;
- the final migration is validated from the real pre-change schema state.

Do not accumulate corrective migrations merely to compensate for errors in migrations that
have never been released.

### 10.2 New schema changes

Any Doctrine mapping change that requires a database schema change must include a Doctrine migration.

Do not use `doctrine:schema:update --force` as a deployment strategy.

### 10.3 Schema alignment

After any mapping/schema change, verify that Doctrine and the database are aligned.

Expected validation sequence:

```bash
docker compose exec web php bin/console doctrine:migrations:migrate
docker compose exec web php bin/console doctrine:schema:validate
docker compose exec web php bin/console doctrine:schema:update --dump-sql
```

`doctrine:schema:update --dump-sql` should produce no unexpected schema drift.

Then clear/warm the cache when appropriate:

```bash
docker compose exec web php bin/console cache:clear
docker compose exec web php bin/console cache:warmup
```

### 10.4 Migration safety

By default, migrations must be **non-destructive**.

Do not:

- drop columns;
- drop tables;
- truncate data;
- silently rewrite historical records;
- perform irreversible destructive transformations;

unless explicitly requested or explicitly approved after a prior audit.

When adding new required fields, preserve historical behavior with a safe migration/backfill strategy.

### 10.5 Production-grade migration requirement

Every migration must be deployable automatically in production.

The normal production deployment must be able to execute:

```bash
php bin/console doctrine:migrations:migrate --no-interaction
```

without :

- manual SQL before the migration;
- manual SQL between migrations;
- manual schema corrections after the migration;
- doctrine:schema:update --force;
- manually marking migrations as executed;
- manual renaming of indexes or foreign keys.

A migration is not considered valid merely because the final local schema can be repaired
manually into the expected state.

The migration itself must produce the expected schema and data state.

### 10.6 Migration preconditions and partial-DDL safety

MariaDB/MySQL schema operations may perform implicit commits.

Therefore, a failed migration can leave the database partially modified even when Doctrine
does not record the migration as executed.

For any migration containing data-dependent constraints or uniqueness rules:

- perform all data-integrity prechecks before the first DDL statement;
- abort before changing the schema when human arbitration is required;
- ensure that the precheck exactly matches the database constraint that will be created;
- do not perform several schema changes first and only discover incompatible historical data later;
- design the migration so failure occurs as early as possible and before irreversible or implicitly committed DDL.

Examples include:

- duplicate rows before creating a unique index;
- several active records before enforcing one-active-record invariants;
- incompatible null values before adding NOT NULL constraints;
- invalid foreign-key references before strengthening referential integrity.

### 10.7 Foreign keys, indexes and legacy schema names

Do not assume that an existing database constraint or index has the name currently generated
by Doctrine.

Legacy databases may contain:

- custom constraint names;
- historical Doctrine-generated names;
- renamed indexes;
- database-specific names;
- malformed or non-standard legacy identifiers.

Before altering an existing foreign key or index:

- inspect the actual database schema;
- compare it with Doctrine metadata;
- avoid hard-coding a historical constraint name unless its stability is guaranteed;
- avoid changing an existing foreign key merely to normalize its name when no business or
  integrity requirement requires that change;
- prefer preserving a valid legacy constraint when the mapping can safely remain compatible.

When a migration must alter an existing constraint, it must handle the real supported
production schema without requiring manual intervention.

### 10.8 Doctrine schema-name alignment

New migrations must create indexes, foreign keys, column definitions and defaults in the form
expected by the current Doctrine metadata whenever reasonably possible.

After implementing a migration, compare the resulting schema with:

```bash
php bin/console doctrine:schema:validate
php bin/console doctrine:schema:update --dump-sql
```

A migration should not knowingly create:

- an index that Doctrine immediately wants to rename;
- a redundant index that Doctrine immediately wants to drop;
- obsolete DBAL type comments;
- different defaults/nullability from the entity mapping;
- a foreign-key action different from the mapping.

**doctrine:schema:update --dump-sql** must be empty after all migrations relevant to the current
code have been executed.

### 10.9 Clean migration-chain validation

For a significant migration set, validating migrations one by one on an already-modified
development database is not sufficient.

Before considering the migration set production-ready, perform a clean-chain test from a
database representing the real pre-change production state, preferably using a recent
production-like copy with representative data.

The validation must consist of running the complete pending migration chain without manual SQL
intervention:

```bash
php bin/console doctrine:migrations:migrate --no-interaction
php bin/console doctrine:schema:validate
php bin/console doctrine:schema:update --dump-sql
php bin/console doctrine:migrations:status
```

**doctrine:migrations:status** must be empty after all migrations relevant to the current
code have been executed.

Expected result:

- every pending migration succeeds in sequence;
- no manual database intervention is required;
- Doctrine mapping is valid;
- database schema is synchronized;
- doctrine:schema:update --dump-sql reports nothing to update;
- no migrations remain pending.

When migrations contain data-integrity prechecks, the test database should contain
representative historical data rather than only an empty/fresh schema.

### 10.10 Diagnostic commands for migration and schema issues

When a migration or schema validation fails, prefer inspecting the real database state before
making assumptions or modifying migration code.

Useful commands include:

#### Migration status

```bash
docker compose exec web php bin/console doctrine:migrations:status
```

Use this to confirm:

- current executed migration;
- next pending migration;
- number of pending migrations;
- whether a failed migration was recorded as executed.

Do not assume that a failed migration left the database unchanged. MariaDB/MySQL DDL may have
been partially committed even when Doctrine still reports the migration as pending.

**Doctrine schema comparison**

```bash
docker compose exec web php bin/console doctrine:schema:validate
docker compose exec web php bin/console doctrine:schema:update --dump-sql
```

Use these commands to identify:

- schema drift;
- unexpected index names;
- unexpected foreign-key actions;
- nullability/default differences;
- obsolete DBAL comments;
- redundant or missing indexes.

Never use **doctrine:schema:update** --force as a repair strategy.

**SQL syntax / PHP syntax checks**

```bash
docker compose exec web php -l migrations/VersionXXXXXXXXXXXXXX.php
```

Run this on any migration modified during implementation.

**Inspecting the actual MariaDB schema**

**doctrine:query:sql** may execute **SELECT**/**SHOW** statements without displaying their result
depending on the installed Doctrine/DBAL tooling.

When exact schema inspection is required, bootstrap Symfony explicitly and query the DBAL
connection:
```bash
docker compose exec web php -r '
require "vendor/autoload.php";

(new Symfony\Component\Dotenv\Dotenv())->bootEnv(".env");

$kernel = new App\Kernel(
    $_SERVER["APP_ENV"] ?? "dev",
    (bool) ($_SERVER["APP_DEBUG"] ?? true)
);
$kernel->boot();

$c = $kernel->getContainer()->get("doctrine")->getConnection();

print_r($c->fetchAllAssociative("SHOW CREATE TABLE table_name"));
'
```

Loading Dotenv explicitly is required here because a raw **php -r** execution does not go through
the normal Symfony console bootstrap and therefore may not automatically load **.env** /
**.env.local.**

**Inspecting columns**
```bash
docker compose exec web php -r '
require "vendor/autoload.php";
(new Symfony\Component\Dotenv\Dotenv())->bootEnv(".env");

$kernel = new App\Kernel(
    $_SERVER["APP_ENV"] ?? "dev",
    (bool) ($_SERVER["APP_DEBUG"] ?? true)
);
$kernel->boot();

$c = $kernel->getContainer()->get("doctrine")->getConnection();

print_r($c->fetchAllAssociative("
    SELECT
        COLUMN_NAME,
        COLUMN_TYPE,
        IS_NULLABLE,
        COLUMN_DEFAULT,
        COLUMN_COMMENT
    FROM information_schema.COLUMNS
    WHERE TABLE_SCHEMA = DATABASE()
      AND TABLE_NAME = '\''table_name'\''
    ORDER BY ORDINAL_POSITION
"));
'
```
**Inspecting indexes**
```bash
 docker compose exec web php -r '
require "vendor/autoload.php";
(new Symfony\Component\Dotenv\Dotenv())->bootEnv(".env");

$kernel = new App\Kernel(
    $_SERVER["APP_ENV"] ?? "dev",
    (bool) ($_SERVER["APP_DEBUG"] ?? true)
);
$kernel->boot();

$c = $kernel->getContainer()->get("doctrine")->getConnection();

print_r($c->fetchAllAssociative("
    SELECT
        INDEX_NAME,
        NON_UNIQUE,
        GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) AS indexed_columns
    FROM information_schema.STATISTICS
    WHERE TABLE_SCHEMA = DATABASE()
      AND TABLE_NAME = '\''table_name'\''
    GROUP BY INDEX_NAME, NON_UNIQUE
    ORDER BY INDEX_NAME
"));
'
```
**Inspecting foreign keys**
```bash
docker compose exec web php -r '
require "vendor/autoload.php";
(new Symfony\Component\Dotenv\Dotenv())->bootEnv(".env");

$kernel = new App\Kernel(
    $_SERVER["APP_ENV"] ?? "dev",
    (bool) ($_SERVER["APP_DEBUG"] ?? true)
);
$kernel->boot();

$c = $kernel->getContainer()->get("doctrine")->getConnection();

print_r($c->fetchAllAssociative("SHOW CREATE TABLE table_name"));
'
```

**information_schema** is still useful for semantic inspection:
```bash
 SELECT
    CONSTRAINT_NAME,
    DELETE_RULE
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = DATABASE()
  AND TABLE_NAME = 'table_name';
```

However, legacy databases may contain malformed or non-standard constraint identifiers.
**information_schema** or DBAL may normalize or replace invalid bytes when displaying them.

When a legacy foreign-key name looks suspicious, do not blindly copy the displayed name into
a migration.

**Hex inspection of suspicious identifiers**

When a constraint name contains unusual or corrupted characters, inspect its raw bytes:
```bash
   SELECT
    CONSTRAINT_NAME,
    HEX(CONSTRAINT_NAME) AS constraint_hex,
    LENGTH(CONSTRAINT_NAME) AS byte_length,
    CHAR_LENGTH(CONSTRAINT_NAME) AS char_length,
    DELETE_RULE
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = DATABASE()
  AND TABLE_NAME = 'table_name';
```

This is a diagnostic tool only.

Do not build production migration logic around malformed historical identifiers unless there
is no safer alternative.

**Executing one migration during development**

When isolating a newly-created, not-yet-released migration:
```bash
docker compose exec web php bin/console doctrine:migrations:execute \
DoctrineMigrations\\VersionXXXXXXXXXXXXXX --up
```

and when safe and supported by its **down() implementation:**
```bash
docker compose exec web php bin/console doctrine:migrations:execute \
DoctrineMigrations\\VersionXXXXXXXXXXXXXX --down
```

This is useful for development validation only.

The final production-readiness test must still execute the complete pending migration chain
from the real pre-change schema state using:

```bash
docker compose exec web php bin/console doctrine:migrations:migrate --no-interaction
```

**Diagnostic commands are development tools, not deployment steps.** Any manual SQL used to inspect or restore a local test database must never become part of the normal production deployment procedure.

---

## 11. Multi-project architecture

The application is multi-project by design.

This is a permanent architectural rule.

Any new feature that can logically vary per artistic project must be designed as **project-aware from the beginning**.

Do not hard-code a global configuration when the concept belongs to a project.

Always consider:

- project ownership;
- project access rights;
- project-specific configuration;
- project-specific documents;
- project-specific external integrations;
- project-specific public website behavior;
- cross-project isolation.

---

## 12. Authorization and project isolation

Existing authorization must be respected.

Current roles include:

- `ROLE_ADMIN`;
- `ROLE_PRESSE`;
- `ROLE_USER`;
- super-admin behavior where already implemented.

Users only have access to projects for which they are authorized.

An identifier, URL, GED code, form value or Doctrine relation is never an authorization. The same project and permission policy must be enforced for lists, details, direct URLs, downloads, codes, attachments, modals, wizards and public endpoints. A non-super-admin account with back-office permissions must have at least one authorized project; autonomous press access remains separate.

### 12.1 IDOR protection

Never trust an entity ID from the URL, form, JavaScript request, or client-side state.

Every operation that loads or modifies a project-scoped entity must verify that the current user is authorized for the entity’s project.

Changing an ID in a request must never allow access to another project’s data.

This rule applies to:

- views;
- edits;
- deletes;
- downloads;
- exports;
- API-style endpoints;
- AJAX requests;
- document access;
- generated files;
- business actions.

---

## 13. Security principles

Security is a first-class requirement for every task.

The application manages personal and business data. Every modification must include a quick security review of the change being introduced.

At minimum, consider:

- authorization;
- IDOR;
- CSRF;
- XSS;
- SQL/injection risks;
- command injection;
- file upload risks;
- unsafe redirects;
- secrets exposure;
- sensitive log output;
- external API handling;
- personal data exposure;
- session/authentication impact;
- privilege escalation.

Do not turn a small unrelated task into a full security rewrite. Scope security work to the requested change unless the request itself is broad.

### 13.1 Secrets

Never commit secrets.

Do not place secrets in:

- source code;
- Twig templates;
- JavaScript;
- fixtures;
- documentation examples containing real values;
- logs;
- Git history.

The project uses `.env.local` for environment-specific values, while some project-specific credentials/configuration are stored in the database and protected.

When secrets are stored in the database, reuse the existing encryption/protection mechanism whenever possible.

Do not invent a parallel secret-storage system without a strong reason.

---

## 14. Symfony/PHP implementation style

### 14.1 Maintainability first

Favor code that is easy to understand and maintain.

A larger but well-structured change is acceptable when it is genuinely necessary to keep the codebase maintainable.

### 14.2 Typing

Use strict and explicit typing as much as reasonably possible.

Prefer typed:

- parameters;
- return values;
- properties;
- DTOs/value objects where useful.

Exceptions are acceptable when framework inheritance, polymorphism, legacy integration, or technical constraints require flexibility.

### 14.3 Services

Reusable business logic should generally live in services.

Controllers should remain reasonably thin.

External integrations should be isolated in one or more dedicated services.

### 14.4 Traits

Traits are acceptable when they represent a coherent reusable cross-cutting behavior.

Do not use traits merely to split a large class into fragments.

### 14.5 Existing mechanisms first

Before introducing a new abstraction, inspect whether the project already contains a suitable mechanism.

Prefer adapting existing patterns when this can be done without causing regressions or excessive complexity.

---

## 15. External APIs and libraries

External integrations must be isolated as much as possible behind dedicated service classes.

Examples include:

- Google Calendar;
- Google Analytics;
- SMTP/email integration;
- CAPTCHA;
- any future third-party API.

### 15.1 Failure isolation

An external failure should not break unrelated areas of the application.

When reasonable:

- catch integration-specific failures;
- display a clear local error message;
- keep unrelated dashboard/page content available;
- log useful diagnostics without exposing secrets;
- use timeouts and defensive error handling.

### 15.2 Dependencies

Do not add a Composer or frontend dependency casually.

A new dependency must:

- solve a real need;
- provide clear value over existing/native capabilities;
- be actively maintained;
- have a trustworthy ecosystem;
- be compatible with the project;
- not introduce disproportionate security or maintenance risk.

Any `composer require` must be justified.

Prefer Symfony/PHP/native browser capabilities when they are sufficient.

---

## 16. UX/UI principles

The back office must be usable by a **novice computer user**.

This is a core product requirement.

Any new or modified workflow should aim to make the correct action obvious without requiring technical knowledge.

### 16.1 Design goals

Favor:

- clear vocabulary;
- a clearly visible primary action;
- minimal unnecessary navigation;
- fewer clicks where possible;
- relevant information shown at the moment it is needed;
- contextual actions;
- sensible defaults;
- strong feedback after actions;
- prevention of mistakes before they happen;
- confirmation dialogs only for genuinely risky/destructive operations;
- wizard flows when a task contains several successive decisions;
- modals/drawers/quick actions when they genuinely reduce navigation burden;
- avoiding full-page reloads where a simpler interaction is safe and maintainable;
- consistency with existing UI patterns.

### 16.2 Device compatibility

Every new or modified UI must be designed to work properly on:

- **desktop / PC**;
- **tablet**;
- **mobile**.

This means more than adding a generic responsive breakpoint.

The feature must remain functionally usable on each device category:

- controls must remain reachable;
- forms must remain operable;
- tables/lists must have a usable mobile strategy;
- dialogs must fit the viewport;
- buttons/touch targets must be usable;
- information hierarchy must remain understandable;
- horizontal overflow must be intentionally managed;
- workflows must not depend on hover;
- no essential action may become inaccessible on smaller screens.

When a desktop interaction does not translate well to mobile, design a dedicated mobile interaction rather than forcing the desktop layout to shrink.

### 16.3 Accessibility

Long-term goal: maximize compliance with **RGAA** and **WCAG**.

The current application may not yet fully comply, but all new work should move in that direction.

Consider:

- contrast;
- labels;
- focus states;
- keyboard navigation;
- semantic HTML;
- accessible names;
- ARIA only when useful;
- touch target size;
- error messaging;
- non-color-only information.

Do not knowingly introduce avoidable accessibility regressions.

---

## 17. Public websites

Public websites are a protected area from a product/design perspective.

Do not modify public-site templates, design, content, responsive behavior, SEO structure, or visual identity unless:

- the user explicitly requests a public-site change; or
- a very minor public-site adjustment is directly required by the requested feature and is clearly safe.

If the required public-site impact is more than minor, stop and ask for approval.

### 17.1 Public design preservation

When public-site changes are authorized, preserve:

- existing visual identity;
- validated responsive behavior;
- photographic framing rules;
- focal-point handling;
- content hierarchy;
- photographer credits;
- existing SEO behavior unless improvement is intentional.

### 17.2 Artistic media

Do not alter public artistic media without explicit authorization. See the protected media rule above.

---

## 18. SEO

SEO remains an important product requirement.

Public-site work should preserve or improve:

- page titles;
- meta descriptions;
- canonical URLs;
- sitemap behavior;
- robots directives;
- semantic HTML;
- structured data;
- page performance;
- stable public URLs.

Do not change an existing public URL without considering redirects and SEO consequences.

Avoid accidental indexation of private/admin content.

---

## 19. Privacy, cookies and analytics

Non-essential tracking must respect the existing consent mechanism.

Do not silently enable new analytics/tracking scripts before consent when consent is required.

Withdrawing Analytics consent must take effect on the current page: stop new collection, update the provider consent state and remove accessible analytics cookies when reasonably possible. Reacceptance must not duplicate script initialization or automatic page views.

Any new tracker must be reviewed for:

- consent requirements;
- privacy policy impact;
- cookie behavior;
- CSP impact;
- project-specific configuration;
- documentation requirements.

---

## 20. GED / document management

The GED uses project-aware document visibility/scope concepts.

Existing document concepts include visibility such as:

- public;
- presse;
- admin;
- GLOBAL/project-scoped behavior.

Some workflows intentionally use whitelists of document categories rather than exposing all documents everywhere.

For example, prospecting attachments are intentionally constrained to relevant categories.

Do not broaden document visibility or attachment eligibility without understanding the business/security implications.

Always verify:

- project scope;
- user permissions;
- document visibility flags;
- whether a document is global or project-specific;
- whether the target workflow uses an explicit whitelist.

---

## 21. Prospecting workflow

Prospecting is a structured workflow and must not be treated as a free-form status field.

Current business stages include concepts such as:

- creation;
- first contact;
- follow-up 1;
- follow-up 2;
- proposal sent;
- commercial agreement obtained;
- exact date scheduled;
- commercial refusal before agreement;
- cancellation after confirmation and explicit reprogramming;
- completed cycle;
- next action;
- assigned responsible person;
- concert realization / archived date synchronization where implemented.

The workflow also includes automated side effects such as email-related status updates and date synchronization.

When changing prospecting behavior:

- inspect the current entity/status implementation;
- inspect all transitions and side effects;
- inspect automatic updates;
- inspect reporting/dashboard use;
- inspect email workflows;
- inspect concert/date linkage;
- update both `SPECIFICATIONS_FONCTIONNELLES.md` and this workflow section if durable business behavior changes.

Prospection statuses are addressed by stable unique technical codes, never by their translated labels. Commercial agreement and exact scheduling are distinct milestones. A status change triggered by an e-mail must be monotonic and must not leave a terminal state implicitly.

For one project and one venue, only one active prospection may exist. `FUTURE_RECONTACT` remains active; refusal, cancellation after confirmation, completion and not-relevant are terminal for this invariant.

A concert date may have at most one complete representation feedback record. Its project scope is derived exclusively from the linked `ConcertDate`, never from a client-supplied project identifier. The database relation must remain unique and `ON DELETE RESTRICT`: deleting a date, its prospection or a parent venue whose cascade would remove the date must be blocked with an explicit application message while feedback exists. Creation metadata is immutable; edits update only the last-update metadata. Physical feedback deletion remains super-admin only. Questionnaire answers are optional and must remain `NULL` when omitted; the linked concert date and automatic context snapshots remain required.

Do not rename or reinterpret statuses casually.

---

## 22. Email workflows

Email behavior may affect business status and history.

When modifying email functionality:

- reuse project templates where applicable;
- preserve template variables;
- preserve attachment rules;
- preserve project scope;
- preserve prospecting status synchronization;
- log/send history when the existing design requires it;
- prevent accidental real sending from development workflows unless explicitly requested.

If a true dev-safe mail strategy is missing and becomes relevant, propose it rather than silently sending production emails.

---

## 23. PDF generation

The project contains a `SimplePdfService`-style internal PDF generation mechanism rather than relying on assumptions about browser rendering.

Before changing PDF output:

- inspect the actual current service and rendering code;
- do not assume CSS/HTML behavior matches a normal browser;
- validate output visually when practical;
- preserve proportions and asset handling;
- consider print dimensions and page breaks;
- avoid introducing external PDF libraries unless there is a justified need.

---

## 24. Accounting

Accounting data requires additional care.

Accounting is association-wide, but project ownership still applies to detailed records. A non-super-admin may only see invoices, payments, movements, attachments and other nominative rows for authorized projects; association-level rows without a project remain shared. A global accounting permission never grants indirect access to a foreign project's details.

A quote can produce at most one invoice and can have at most one active convention. These invariants require application-level transactional protection and database uniqueness when supported.

### 24.1 Deletion

Accounting deletion is restricted to super-admin behavior where currently implemented.

Do not weaken this restriction.

### 24.2 Calculations

Financial calculations must be as precise as possible.

Avoid floating-point shortcuts that can introduce monetary errors.

Use appropriate numeric/decimal handling based on the existing model.

Do not silently alter historical accounting values.

---

## 25. Performance

Performance should be considered in every non-trivial change.

Watch for:

- Doctrine N+1 queries;
- unbounded lists;
- missing pagination;
- unnecessary loading of document/blob contents;
- repeated external API calls;
- repeated expensive calculations;
- avoidable full-page reloads;
- excessive client-side payloads;
- unnecessary database writes.

Use caching when justified, but do not add cache complexity without a clear benefit.

---

## 26. Error handling

Prefer local, understandable failure handling over global failure.

If a secondary integration fails, the rest of the page should remain usable when reasonably possible.

Errors should:

- explain what failed;
- avoid exposing internals or secrets;
- provide enough information for troubleshooting;
- be logged appropriately;
- not silently corrupt business state.

A recoverable integration error should not become a generic HTTP 500 if it can be isolated safely.

---

## 27. Language and terminology

### 27.1 Code language

Use English for:

- class names;
- method names;
- property names;
- technical identifiers;
- new service names;
- internal code structures.

### 27.2 UI language

User-facing UI remains in **French**.

### 27.3 Comments

Avoid unnecessary comments.

Write comments only when they explain:

- non-obvious business rules;
- security constraints;
- technical workarounds;
- important architectural reasoning.

Do not write comments that merely restate obvious code.

### 27.4 Business terminology

Preserve current terminology unless an improvement is explicitly proposed and validated.

Examples include:

- Prospection;
- À traiter;
- Date réalisée;
- Aide à la prospection;
- Presse;
- Fiche technique;
- Convention;
- existing status labels and project terminology.

If terminology changes, update all affected UI, links, documentation, help text, workflows, and references consistently.

---

## 28. Tests and validation strategy

The project currently has no established automated test suite.

Do not turn an unrelated small task into a large testing-framework project.

For major work, explicitly assess what automated tests would be valuable.

A dedicated PHPUnit/testing strategy may be introduced later as its own project-wide improvement.

### 28.1 Required validation today

Depending on the change, use an appropriate subset of:

- `php -l` on modified PHP files;
- Symfony console validation;
- Doctrine migration execution;
- `doctrine:schema:validate`;
- `doctrine:schema:update --dump-sql`;
- cache clear/warmup;
- route inspection;
- Twig rendering checks;
- manual browser validation;
- responsive validation on desktop/tablet/mobile;
- security review;
- workflow regression review.

Do not claim a check was performed unless it was actually performed.

---

## 29. Regression prevention

Every change must be reviewed for regressions in adjacent workflows.

Do not only test the line of code that changed.

Examples:

- a prospecting change may affect emails, statuses, dashboard counts, dates and history;
- a document change may affect permissions, attachments and public visibility;
- a project-setting change may affect every project;
- a public-date change may affect homepage, dates page, archives and structured data;
- a Doctrine change may affect migrations, forms, serialization, repositories and templates.

Unless regression is explicitly requested, preserving existing behavior is mandatory.

---

## 30. Git workflow

The user retains control of pushes and merges.

### 30.1 Never push

The agent must **never push to a remote**.

### 30.2 Never merge into main/master

The agent must **never perform the final merge** into `main`/`master`.

### 30.3 Minor changes

For minor work:

- work directly on the current `main`/`master` branch if that is the user’s current workflow;
- do not commit unless the user explicitly asks;
- leave changes ready for user review/commit.

### 30.4 Major changes

For major work, after the audit/plan has been validated:

- create a dedicated branch;
- make logical, incremental commits;
- keep commits focused and reviewable;
- do not push;
- do not merge;
- let the user review and perform the final merge.

### 30.5 Safety

Never use destructive Git operations casually.

Do not:

- `git reset --hard`;
- force-push;
- rewrite shared history;
- discard unrelated user changes;
- overwrite local work not created by the agent.

Inspect `git status` and `git diff` before finalizing work.

---

## 31. Generated files and ignored paths

Respect the existing `.gitignore`.

Do not add generated/cache/vendor files that are intentionally ignored.

Examples may include:

- `var/cache`;
- `var/log`;
- `vendor`;
- `node_modules`;
- temporary exports;
- generated local artifacts.

Inspect `.gitignore` rather than assuming the complete list.

---

## 32. Production boundaries

The agent does **not** operate production.

The user handles production deployment and production changes.

The agent may provide commands and deployment notes, but must not perform production actions.

### 32.1 Current production deployment pattern

Typical user-run production flow:

```bash
git pull
php bin/console doctrine:migrations:migrate   # when migrations exist
runuser -u www-data -- env APP_ENV=prod php bin/console cache:clear
runuser -u www-data -- env APP_ENV=prod php bin/console cache:warmup
```

Additional commands may be required when dependencies or autoloading change, for example Composer install/update or dump-autoload. State them explicitly when relevant.

### 32.2 Production changes forbidden to the agent

Do not directly perform:

- production migrations;
- server configuration changes;
- Apache changes;
- PHP configuration changes;
- DNS changes;
- SMTP changes;
- service restarts;
- secret rotation;
- production cache operations;
- production data deletion.

Provide instructions only.

---

## 33. Logging and debugging

In development, useful sources include:

- Symfony logs in `var/log`;
- Apache logs;
- relevant application logs;
- database errors when provided.

The user may provide filtered excerpts.

Do not log:

- passwords;
- API private keys;
- SMTP credentials;
- full sensitive tokens;
- unnecessary personal data.

---

## 34. Public/internal configuration and secret handling

Project-level integrations such as SMTP, Analytics, Calendar, CAPTCHA and similar settings may be stored in the database using existing secure patterns.

When extending these areas:

- reuse the current encryption/protection mechanism;
- keep settings project-scoped when appropriate;
- do not expose secrets in Twig/HTML;
- do not print secrets in logs;
- do not add secret values to documentation;
- ensure configuration errors do not break unrelated pages.

---

## 35. Definition of done

A task is not complete merely because the requested screen appears to work.

Depending on scope, “done” means the agent has considered and, where applicable, completed:

- requested functionality;
- business correctness;
- authorization and project isolation;
- security impact;
- UX/UI quality;
- desktop compatibility;
- tablet compatibility;
- mobile compatibility;
- accessibility impact;
- Doctrine mapping;
- additive migration(s);
- schema validation;
- cache validation;
- regression checks;
- external-integration error handling;
- documentation updates;
- CHANGELOG update;
- final diff review;
- concise but sufficient delivery summary;
- - migration chain validated from the real pre-change schema state when significant migrations exist;
- no manual production SQL required for normal deployment.

Do not claim completion if a required validation step could not be performed. State the limitation clearly.

---

## 36. Final report expectations

The final report must be proportional to the size of the change.

### Small change

Keep the summary short:

- what changed;
- files/areas impacted;
- whether a migration is required;
- validation performed;
- any manual check required.

### Major change

Provide a detailed report covering:

- implemented plan;
- architecture changes;
- business behavior;
- database changes;
- security decisions;
- UX/UI decisions;
- documentation changes;
- commands/checks run;
- known limitations;
- manual verification still recommended;
- branch/commit summary when relevant.

When in doubt, prefer too much useful information over too little.

---

## 37. Decision priority and conflicts

Typical priority order is:

1. data integrity;
2. security;
3. business correctness;
4. non-regression;
5. UX simplicity;
6. maintainability;
7. performance;
8. aesthetics.

This is not an automatic conflict resolver.

If two important goals conflict in a meaningful way, stop and discuss the trade-off with the user rather than choosing silently.

---

## 38. Non-negotiable rules

The following rules are mandatory:

- Do not modify protected artistic media without explicit authorization.
- Do not modify existing migrations.
- Do not use destructive migrations by default.
- Keep Doctrine mapping and database schema aligned.
- Preserve project isolation and authorization.
- Protect against IDOR.
- Treat security as part of every change.
- Keep new features multi-project aware.
- Do not make major changes without audit + user validation.
- Ask when ambiguity remains.
- Do not refactor unrelated code during a precise task.
- Do not silently change public websites beyond minor directly-required adjustments.
- Preserve SEO on public changes.
- Reuse existing mechanisms before inventing parallel ones.
- Do not add unmaintained/unjustified dependencies.
- Keep application code compatible with the current production PHP baseline (currently PHP 8.2).
- Design UI for desktop, tablet and mobile as real usable targets.
- Move new UI toward RGAA/WCAG compliance.
- Update documentation when behavior changes.
- Do not push or merge.
- Do not operate production.
- Never claim tests/checks were run if they were not.

---

## 39. Practical pre-flight checklist

Before editing:

1. Read this file.
2. Inspect `git status`.
3. Identify whether the task is minor or major.
4. If major, stop after audit/plan and wait for approval.
5. Identify affected projects/modules/workflows.
6. Check existing patterns before introducing new ones.
7. Identify authorization/security implications.
8. Identify documentation impact.
9. Identify public-site/media impact.
10. Identify database/migration impact.

Before declaring completion:

1. Review the full diff.
2. Confirm no unrelated changes were introduced.
3. Validate PHP/Twig/config syntax where relevant.
4. Run Doctrine migration/schema checks where relevant.
5. Clear/warm cache where relevant.
6. Review permissions and project isolation.
7. Review regression risks.
8. Check desktop/tablet/mobile UX for UI work.
9. Update documentation and CHANGELOG where required.
10. Summarize exactly what was done and what remains to be manually validated.
11. If migrations exist, verify that all data-dependent preconditions run before DDL.
12. For a significant migration chain, validate the complete chain from a clean pre-change database.
13. Confirm that production deployment requires no manual SQL/schema repair.
