When a task transitions to a final status, archives the current task and creates
a new occurrence with recalculated dates. Adds TaskStatusRepository::findFirstNonFinal()
to assign the initial status to the new task.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Handles Patch (persist + sync + recurrence check) and Delete (remove + cleanup Zimbra events).
Updates TaskNumberProcessor to sync newly created tasks to calendar.
Wires TaskCalendarProcessor as processor for Patch/Delete on Task entity.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds taskCount virtual field on Project entity, delete button in ProjectDrawer
(visible only when taskCount === 0), and a reusable ConfirmDeleteProjectModal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Assert\Choice on ClientTicket type and status with typed constants
- Add Assert\Url on GiteaConfiguration, BookStackConfiguration, TaskBookStackLink, ClientTicket
- Fix concurrent task/ticket numbering: use pg_advisory_xact_lock instead of FOR UPDATE with MAX()
- Wrap CreateTaskTool numbering in transaction
- Harmonize repository contracts: both return max number, caller adds +1
Tickets: T-004, T-008, T-011, T-012
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add non-persisted plainPassword field to User entity (write-only via API)
- Remove direct write access to password field
- Update UserPasswordHasherProcessor to hash from plainPassword
- Update frontend DTO and UserDrawer component
Ticket: T-009
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Block SVG MIME type in TaskDocumentProcessor upload validation
- Serve existing SVG files as attachment (defense-in-depth) in download controller
- Block ROLE_CLIENT from uploading documents to tasks (only allowed via portal tickets)
- Add Doctrine extension to filter projects by allowedProjects for ROLE_CLIENT
Tickets: T-003, T-005, T-006
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ManyToOne relation from TimeEntry to ClientTicket entity.
MCP tools create-time-entry, update-time-entry, and list-time-entries
now support clientTicketId parameter for linking tickets to time entries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CreateTaskTool called nonexistent findMaxNumberByProject instead of
findMaxNumberByProjectForUpdate. Also removed FOR UPDATE clause from the
query as PostgreSQL does not support it with aggregate functions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use getMimeType() instead of getClientMimeType() to prevent MIME spoofing
- Change IsGranted to IS_AUTHENTICATED_FULLY so ROLE_CLIENT can access avatars
- Remove Groups from avatarFileName (only avatarUrl needed by frontend)
- Disable aggressive caching to prevent stale avatar images
- Add error handling to avatar upload in profile page
- Use i18n for "Mon profil" button text
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tools: list-users, list-clients, list/get/create/update-project,
list/get/create/update/delete-task, list-statuses/priorities/efforts/tags,
list/create/update-group, list/create/update/delete-time-entry.
Attribute moved to class level for SDK discovery compatibility.
Install nyholm/psr7 for HTTP transport PSR-17 support.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Install symfony/mcp-bundle, add STDIO + HTTP transport config,
API token auth on User entity with custom authenticator and firewall,
generate-api-token console command, Nginx /_mcp location, fixture token.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
API Platform 4 requires explicit uriVariables declaration for
URI template parameters on DTO resources.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>