d1516c3f5d
First business module of Phase 2 (LST-64, rodage). Strangler-style, additive move — no behavioural change to the public API or MCP tools. - New module App\Module\TimeTracking (TimeTrackingModule, id "time-tracking", declares time-tracking.entries.view/export permissions in the RBAC catalog; operation security left on ROLE_USER, not re-wired here). - Move TimeEntry entity, repository (now interface + Doctrine impl bound in services.yaml), ActiveTimeEntryProvider, export service/controller and the 4 MCP TimeEntry tools into the module. #[ApiResource] (operations, security, uriTemplates /time_entries/*), filters and serialization groups preserved. - Doctrine mapping "TimeTracking" added; table time_entry unchanged. - Sidebar item gated with module "time-tracking" (SidebarFilter disables the route when the module is inactive). - Timestampable/Blamable adopted (first adopter): additive migration adds created_at/updated_at/created_by/updated_by (nullable, FK SET NULL) + COMMENT ON COLUMN. Functional test confirms created_at on persist and updated_at refresh on update — the suspected preUpdate recompute issue does not occur (Doctrine ORM 3.6.2 recomputes change sets after preUpdate). 159 tests green, schema mapping valid, php-cs-fixer clean.
38 lines
1.9 KiB
PHP
38 lines
1.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Définition de la sidebar (sections + items) — navigation GLOBALE uniquement.
|
|
* Filtrée par SidebarFilter :
|
|
* - `module` : route ajoutée à disabledRoutes si module inactif ;
|
|
* - `roles` : section ou item masqué si l'utilisateur n'a aucun des rôles listés (gate minimal) ;
|
|
* - `permission` : section ou item masqué si la permission effective absente (RBAC fin —
|
|
* `User::getEffectivePermissions()` ; ROLE_ADMIN bypasse via le voter, mais la
|
|
* sidebar évalue les permissions effectives réelles — combiner avec `roles` au besoin).
|
|
* Les items contextuels (Kanban/Groupes/Archives), feature-flag (Documents, Mail) et user-flag
|
|
* (Mes absences) restent rendus côté layout, hors de cet endpoint.
|
|
* Les labels sont des clés i18n (sidebar.<domaine>.<item>).
|
|
*/
|
|
return [
|
|
[
|
|
'label' => 'sidebar.general.section',
|
|
'icon' => 'mdi:view-dashboard-outline',
|
|
'items' => [
|
|
['label' => 'sidebar.general.dashboard', 'to' => '/', 'icon' => 'mdi:view-dashboard-outline'],
|
|
['label' => 'sidebar.general.myTasks', 'to' => '/my-tasks', 'icon' => 'mdi:clipboard-check-outline'],
|
|
['label' => 'sidebar.general.projects', 'to' => '/projects', 'icon' => 'mdi:folder-outline'],
|
|
['label' => 'sidebar.general.timeTracking', 'to' => '/time-tracking', 'icon' => 'mdi:calendar-edit-outline', 'module' => 'time-tracking'],
|
|
],
|
|
],
|
|
[
|
|
'label' => 'sidebar.admin.section',
|
|
'icon' => 'mdi:cog-outline',
|
|
'roles' => ['ROLE_ADMIN'],
|
|
'items' => [
|
|
['label' => 'sidebar.admin.teamAbsences', 'to' => '/team-absences', 'icon' => 'mdi:calendar-account-outline'],
|
|
['label' => 'sidebar.admin.administration', 'to' => '/admin', 'icon' => 'mdi:cog-outline', 'permission' => 'core.users.view'],
|
|
],
|
|
],
|
|
];
|