Okouro doc

Une feuille de temps couvre un consultant sur une période. Chaque feuille de temps contient une ou plusieurs lignes, une par affectation, et chaque ligne enregistre un statut pour chaque jour de la période. L’enregistrement suit un cycle de vie fixe : draft, submitted, puis validated ou rejected.

Cycle de vie

draft  --submit-->  submitted  --validate-->  validated
  ^                     |
  +------reject---------+   (rejected is editable again, like draft)
  • draft et rejected sont modifiables.
  • submitted est verrouillé en attendant la revue.
  • validated est définitif.

Qui fait quoi

ActionRôle
Créer une feuille de temps, ajouter une ligne, supprimer un brouillonAdministrateur
Marquer les jours, modifier le commentaire d’une ligneLe consultant propriétaire ou un administrateur, tant que draft/rejected
SoumettreLe consultant propriétaire, depuis draft/rejected
Valider ou rejeterAdministrateur (ou le responsable d’équipe du consultant)

1. Créer la feuille de temps

Un administrateur crée la feuille pour un consultant et une période. Les dates de la période suivent la cadence du compte (voir Conventions).

POST /timesheets HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "consultant_id": "0190a1c2-...",
  "period_start": "2026-01-01",
  "period_end": "2026-01-31"
}

Renvoie 201 Created avec une TimesheetDetailResponse - la feuille de temps ainsi que ses lines. Une feuille couvrant déjà ce consultant et cette période renvoie 409 Conflict.

2. Ajouter une ligne par affectation

Chaque ligne relie la feuille de temps à une affectation (un consultant sur une mission). Voir Dérouler une mission pour créer des affectations.

POST /timesheets/{timesheet_id}/lines HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{ "assignment_id": "0190a1c2-..." }

Renvoie 201 Created. L’affectation doit appartenir au même consultant ; sinon vous obtenez 422.

3. Marquer les jours

Pour chaque jour travaillé par le consultant, définissez un statut sur la ligne. status vaut worked, half_day ou not_worked.

PUT /timesheets/{timesheet_id}/lines/{line_id}/day HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{ "date": "2026-01-05", "status": "worked" }

Renvoie 200 OK avec la ligne mise à jour. Une date hors de la période renvoie 422. Le work_day_count de la ligne est dérivé de ses jours (un jour worked compte 1, half_day compte 0,5).

Ajoutez éventuellement un commentaire à la ligne :

PUT /timesheets/{timesheet_id}/lines HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{ "line_id": "0190a1c2-...", "comment": "Client onboarding sprint" }

4. Soumettre

Le consultant soumet la feuille terminée. Elle devient en lecture seule.

POST /timesheets/{timesheet_id}/submit HTTP/1.1
Authorization: Bearer <access_token>

Renvoie 200 OK avec la TimesheetResponse (status vaut désormais submitted). Soumettre une feuille qui n’est pas draft/rejected renvoie 409.

5. Valider ou rejeter

Un administrateur ou le responsable d’équipe du consultant décide.

POST /timesheets/{timesheet_id}/validate HTTP/1.1
Authorization: Bearer <access_token>
POST /timesheets/{timesheet_id}/reject HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{ "reason": "Missing the Friday entry" }

Valider fait passer la feuille à validated (définitif). Rejeter la fait passer à rejected avec un motif, et elle redevient modifiable pour que le consultant puisse corriger et resoumettre.

Lire les feuilles de temps

GET /timesheets les liste, paginé et filtrable par consultant_id, status, period_start/period_end, search et scope (mine ou team). GET /timesheets/{id} renvoie le détail complet avec les lignes et les jours.

Une ligne ressemble à ceci (notez que billing_rate est null pour les appelants au rôle consultant) :

{
  "id": "0190a1c2-...",
  "timesheet_id": "0190a1c2-...",
  "assignment_id": "0190a1c2-...",
  "mission_name": "Apollo",
  "billing_rate": "900.00",
  "work_day_count": "21",
  "comment": "Client onboarding sprint",
  "days": [
    { "date": "2026-01-05", "status": "worked" },
    { "date": "2026-01-06", "status": "half_day" }
  ]
}

Points d’entrée en un coup d’œil

ActionMéthodeCheminSuccès
ListerGET/timesheets200
Obtenir le détailGET/timesheets/{id}200
CréerPOST/timesheets201
Ajouter une lignePOST/timesheets/{id}/lines201
Définir un jourPUT/timesheets/{id}/lines/{line_id}/day200
Modifier la lignePUT/timesheets/{id}/lines200
SoumettrePOST/timesheets/{id}/submit200
ValiderPOST/timesheets/{id}/validate200
RejeterPOST/timesheets/{id}/reject200
Supprimer un brouillonDELETE/timesheets/{id}204