Markdown Converter
Agent skill for markdown-converter
Auto-generated from all feature plans. Last updated: 2025-12-23
Sign in to like and favorite skills
Auto-generated from all feature plans. Last updated: 2025-12-23
src/ tests/
npm test && npm run lint
@if/@for) now defaultINTERDIT:
master ou maingh pr merge est INTERDIT)OBLIGATOIRE: Toujours suivre ce workflow:
git checkout -b feature/nom-descriptifgit push -u origin feature/nom-descriptifgh pr creategit checkout master && git pull# ❌ INTERDIT git commit -m "feat: something" git push origin master gh pr merge 123 # JAMAIS merger soi-même! # ✅ CORRECT git checkout -b feature/dark-mode git add -A git commit -m "feat: implement dark mode" git push -u origin feature/dark-mode gh pr create --title "feat: dark mode" --body "..." # STOP ICI - L'utilisateur mergera la PR
RAPPEL: Cette règle s'applique à TOUTES les modifications, même les plus petites.
INTERDIT: Ne JAMAIS utiliser
@RequestHeader pour récupérer le contexte utilisateur:
// ❌ INTERDIT - Ancienne méthode @GetMapping("/example") public ResponseEntity<?> example( @RequestHeader("X-User-Id") String userId, @RequestHeader("X-Username") String username, @RequestHeader("X-User-Role") String role) { ... }
OBLIGATOIRE: Toujours utiliser
@AuthenticationPrincipal GatewayUserPrincipal:
// ✅ CORRECT - Nouvelle méthode import com.trucktrack.common.security.GatewayUserPrincipal; import org.springframework.security.core.annotation.AuthenticationPrincipal; @GetMapping("/example") public ResponseEntity<?> example( @AuthenticationPrincipal GatewayUserPrincipal principal) { String userId = principal.userId(); String username = principal.username(); String role = principal.role(); String groups = principal.groups(); // comma-separated UUIDs // ... }
private String getUserId(GatewayUserPrincipal principal) { return principal != null ? principal.userId() : "anonymous"; } private String getUsername(GatewayUserPrincipal principal) { return principal != null ? principal.username() : "anonymous"; } private String getUserRole(GatewayUserPrincipal principal) { return principal != null ? principal.role() : "GUEST"; }
INTERDIT: Appels directs entre services (bypass du gateway)
OBLIGATOIRE: Passer par l'API Gateway avec
SERVICE_ACCOUNT_JWT:
gateway.service-token dans application.ymlPOST /admin/users/service-tokenIMPORTANT: Pour tout développement frontend Angular, TOUJOURS consulter et respecter:
frontend/ANGULAR_CONVENTIONS.mdSignal Inputs: Utiliser
input() au lieu de @Input()
readonly items = input<Item[]>([]); readonly id = input.required<string>();
Signal Outputs: Utiliser
output() au lieu de @Output() + EventEmitter
readonly clicked = output<void>();
Modern Control Flow: Utiliser
@if, @for, @switch au lieu de *ngIf, *ngFor, *ngSwitch
@if (condition()) { ... } @for (item of items(); track item.id) { ... }
Injection: Utiliser
inject() au lieu de constructor injection
private readonly http = inject(HttpClient);
Standalone Components: Tous les composants doivent être
standalone: true
OnPush: Utiliser
ChangeDetectionStrategy.OnPush avec les signals
Structure des fichiers de composant - JAMAIS inline:
.tscomponent-name.component.ts (logique)component-name.component.html (template)component-name.component.scss (styles)// ❌ INTERDIT - Template/styles inline @Component({ selector: 'app-example', template: `<div>...</div>`, styles: [`...`] }) // ✅ CORRECT - Fichiers séparés @Component({ selector: 'app-example', templateUrl: './example.component.html', styleUrls: ['./example.component.scss'] })
NgRx Store - TOUJOURS privilégier le store:
StoreFacade pour accéder aux données déjà chargées// ❌ INTERDIT - Appel API inutile ngOnInit() { this.authService.getUserProfile().subscribe(user => ...); } // ✅ CORRECT - Données du store readonly user = this.facade.currentUser;
facade.currentUserfacade.trucksComplete trip lifecycle management for dispatchers, fleet managers, and drivers.
PENDING → ASSIGNED → IN_PROGRESS → COMPLETED ↓ ↓ CANCELLED ←─────────┘
Admin Endpoints (
/admin/trips):
GET /admin/trips - List trips with filters (status, driver, truck, date range)GET /admin/trips/{id} - Get trip detailsPOST /admin/trips - Create new tripPUT /admin/trips/{id} - Update tripPOST /admin/trips/{id}/assign - Assign to truck/driverPOST /admin/trips/{id}/reassign - Reassign to different truck/driverPOST /admin/trips/{id}/cancel - Cancel tripGET /admin/trips/{id}/history - Get status change historyGET /admin/trips/stats - Get trip counts by statusGET /admin/trips/analytics - Get detailed KPIsDriver Endpoints (
/location/v1/trips):
GET /my - Get driver's assigned tripsGET /{id} - Get trip detailsPOST /{id}/start - Start trip (ASSIGNED → IN_PROGRESS)POST /{id}/complete - Complete trip (IN_PROGRESS → COMPLETED)TripService.java - Core business logicAdminTripController.java - Admin REST endpointsTripController.java - Driver REST endpointsTrip.java - Entity with status transitionsTripAnalyticsDTO.java - KPI calculationsTripListComponent - List with filters, date range picker, status cardsTripDetailComponent - View/edit/assign/reassign/cancelTripStatsComponent - KPI dashboard widgetTripsScreen - List of assigned tripsTripDetailScreen - Start/Complete trip actions