CRA-Helper/lib/api-spec/openapi.yaml
SylvainP1 1df1e34c21 Add optional description field for time entries and improve button accessibility
Update API and frontend to include an optional description field for time entries and move the quick entry button to the sidebar for better visibility.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 55837015-10e9-4be9-b857-7f5e6be73772
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 734a5162-3dd4-4103-b626-ee12b22fd002
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1cc377db-7ea0-49f2-97ce-c3e87e0228cc/55837015-10e9-4be9-b857-7f5e6be73772/1SIrmNK
Replit-Helium-Checkpoint-Created: true
2026-04-14 08:19:30 +00:00

765 lines
17 KiB
YAML

openapi: 3.1.0
info:
# Do not change the title, if the title changes, the import paths will be broken
title: Api
version: 0.1.0
description: CRA (Compte Rendu d'Activité) API
servers:
- url: /api
description: Base API path
tags:
- name: health
description: Health operations
- name: projects
description: Project management
- name: timesheets
description: Timesheet management
- name: timesheet-lines
description: Timesheet line management
- name: time-entries
description: Time entry management
- name: dashboard
description: Dashboard and summary endpoints
paths:
/healthz:
get:
operationId: healthCheck
tags: [health]
summary: Health check
description: Returns server health status
responses:
"200":
description: Healthy
content:
application/json:
schema:
$ref: "#/components/schemas/HealthStatus"
/projects:
get:
operationId: listProjects
tags: [projects]
summary: List all projects
responses:
"200":
description: List of projects
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Project"
post:
operationId: createProject
tags: [projects]
summary: Create a new project
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateProjectBody"
responses:
"201":
description: Project created
content:
application/json:
schema:
$ref: "#/components/schemas/Project"
/projects/{id}:
get:
operationId: getProject
tags: [projects]
summary: Get a project by ID
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"200":
description: Project details
content:
application/json:
schema:
$ref: "#/components/schemas/Project"
"404":
description: Not found
patch:
operationId: updateProject
tags: [projects]
summary: Update a project
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateProjectBody"
responses:
"200":
description: Project updated
content:
application/json:
schema:
$ref: "#/components/schemas/Project"
delete:
operationId: deleteProject
tags: [projects]
summary: Delete a project
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"204":
description: Deleted
/timesheets:
get:
operationId: listTimesheets
tags: [timesheets]
summary: List timesheets
parameters:
- name: year
in: query
schema:
type: integer
- name: month
in: query
schema:
type: integer
responses:
"200":
description: List of timesheets
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Timesheet"
post:
operationId: createTimesheet
tags: [timesheets]
summary: Create a new timesheet
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateTimesheetBody"
responses:
"201":
description: Timesheet created
content:
application/json:
schema:
$ref: "#/components/schemas/Timesheet"
/timesheets/{id}:
get:
operationId: getTimesheet
tags: [timesheets]
summary: Get timesheet with lines and entries
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"200":
description: Timesheet details with lines
content:
application/json:
schema:
$ref: "#/components/schemas/TimesheetDetail"
"404":
description: Not found
patch:
operationId: updateTimesheet
tags: [timesheets]
summary: Update timesheet status
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateTimesheetBody"
responses:
"200":
description: Timesheet updated
content:
application/json:
schema:
$ref: "#/components/schemas/Timesheet"
delete:
operationId: deleteTimesheet
tags: [timesheets]
summary: Delete a timesheet
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"204":
description: Deleted
/timesheets/{timesheetId}/lines:
get:
operationId: listTimesheetLines
tags: [timesheet-lines]
summary: List lines for a timesheet
parameters:
- name: timesheetId
in: path
required: true
schema:
type: integer
responses:
"200":
description: Timesheet lines
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/TimesheetLine"
post:
operationId: createTimesheetLine
tags: [timesheet-lines]
summary: Add a line to a timesheet
parameters:
- name: timesheetId
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateTimesheetLineBody"
responses:
"201":
description: Line created
content:
application/json:
schema:
$ref: "#/components/schemas/TimesheetLine"
/timesheets/{timesheetId}/lines/{lineId}:
delete:
operationId: deleteTimesheetLine
tags: [timesheet-lines]
summary: Delete a timesheet line
parameters:
- name: timesheetId
in: path
required: true
schema:
type: integer
- name: lineId
in: path
required: true
schema:
type: integer
responses:
"204":
description: Deleted
/timesheets/{timesheetId}/entries:
put:
operationId: upsertTimeEntries
tags: [time-entries]
summary: Create or update time entries for a timesheet (batch)
parameters:
- name: timesheetId
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpsertTimeEntriesBody"
responses:
"200":
description: Entries saved
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/TimeEntry"
/quick-entry:
post:
operationId: quickAddTime
tags: [time-entries]
summary: Quick add time - auto-creates timesheet and line if needed
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/QuickAddTimeBody"
responses:
"200":
description: Time entry saved
content:
application/json:
schema:
$ref: "#/components/schemas/QuickAddTimeResponse"
/dashboard/summary:
get:
operationId: getDashboardSummary
tags: [dashboard]
summary: Get summary stats for the dashboard
parameters:
- name: year
in: query
schema:
type: integer
responses:
"200":
description: Dashboard summary
content:
application/json:
schema:
$ref: "#/components/schemas/DashboardSummary"
/dashboard/monthly-hours:
get:
operationId: getMonthlyHours
tags: [dashboard]
summary: Get total hours per month for the year
parameters:
- name: year
in: query
schema:
type: integer
responses:
"200":
description: Monthly hours breakdown
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/MonthlyHours"
/dashboard/project-hours:
get:
operationId: getProjectHours
tags: [dashboard]
summary: Get total hours per project
parameters:
- name: year
in: query
schema:
type: integer
- name: month
in: query
schema:
type: integer
responses:
"200":
description: Hours per project
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ProjectHours"
components:
schemas:
HealthStatus:
type: object
properties:
status:
type: string
required:
- status
Project:
type: object
properties:
id:
type: integer
code:
type: string
name:
type: string
parentProjectId:
type: ["integer", "null"]
client:
type: ["string", "null"]
category:
type: ["string", "null"]
isActive:
type: boolean
createdAt:
type: string
format: date-time
required:
- id
- code
- name
- isActive
- createdAt
CreateProjectBody:
type: object
properties:
code:
type: string
name:
type: string
parentProjectId:
type: ["integer", "null"]
client:
type: ["string", "null"]
category:
type: ["string", "null"]
required:
- code
- name
UpdateProjectBody:
type: object
properties:
code:
type: string
name:
type: string
parentProjectId:
type: ["integer", "null"]
client:
type: ["string", "null"]
category:
type: ["string", "null"]
isActive:
type: boolean
Timesheet:
type: object
properties:
id:
type: integer
year:
type: integer
month:
type: integer
status:
type: string
enum: [draft, submitted, validated]
collaborator:
type: string
totalHours:
type: number
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
required:
- id
- year
- month
- status
- collaborator
- totalHours
- createdAt
- updatedAt
CreateTimesheetBody:
type: object
properties:
year:
type: integer
month:
type: integer
collaborator:
type: string
required:
- year
- month
- collaborator
UpdateTimesheetBody:
type: object
properties:
status:
type: string
enum: [draft, submitted, validated]
collaborator:
type: string
TimesheetDetail:
type: object
properties:
id:
type: integer
year:
type: integer
month:
type: integer
status:
type: string
enum: [draft, submitted, validated]
collaborator:
type: string
totalHours:
type: number
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
lines:
type: array
items:
$ref: "#/components/schemas/TimesheetLineWithEntries"
required:
- id
- year
- month
- status
- collaborator
- totalHours
- createdAt
- updatedAt
- lines
TimesheetLine:
type: object
properties:
id:
type: integer
timesheetId:
type: integer
projectId:
type: integer
projectCode:
type: string
projectName:
type: string
client:
type: ["string", "null"]
category:
type: ["string", "null"]
totalHours:
type: number
required:
- id
- timesheetId
- projectId
- projectCode
- projectName
- totalHours
TimesheetLineWithEntries:
type: object
properties:
id:
type: integer
timesheetId:
type: integer
projectId:
type: integer
projectCode:
type: string
projectName:
type: string
client:
type: ["string", "null"]
category:
type: ["string", "null"]
totalHours:
type: number
entries:
type: array
items:
$ref: "#/components/schemas/TimeEntry"
required:
- id
- timesheetId
- projectId
- projectCode
- projectName
- totalHours
- entries
CreateTimesheetLineBody:
type: object
properties:
projectId:
type: integer
required:
- projectId
TimeEntry:
type: object
properties:
id:
type: integer
timesheetLineId:
type: integer
date:
type: string
format: date
hours:
type: number
required:
- id
- timesheetLineId
- date
- hours
UpsertTimeEntriesBody:
type: object
properties:
entries:
type: array
items:
type: object
properties:
timesheetLineId:
type: integer
date:
type: string
format: date
hours:
type: number
required:
- timesheetLineId
- date
- hours
required:
- entries
DashboardSummary:
type: object
properties:
totalHoursThisMonth:
type: number
totalHoursThisYear:
type: number
activeProjects:
type: integer
pendingTimesheets:
type: integer
validatedTimesheets:
type: integer
required:
- totalHoursThisMonth
- totalHoursThisYear
- activeProjects
- pendingTimesheets
- validatedTimesheets
MonthlyHours:
type: object
properties:
month:
type: integer
totalHours:
type: number
label:
type: string
required:
- month
- totalHours
- label
ProjectHours:
type: object
properties:
projectId:
type: integer
projectCode:
type: string
projectName:
type: string
totalHours:
type: number
required:
- projectId
- projectCode
- projectName
- totalHours
QuickAddTimeBody:
type: object
properties:
projectId:
type: integer
date:
type: string
format: date
hours:
type: number
collaborator:
type: string
description:
type: string
nullable: true
required:
- projectId
- date
- hours
- collaborator
QuickAddTimeResponse:
type: object
properties:
timesheetId:
type: integer
timesheetLineId:
type: integer
entryId:
type: integer
date:
type: string
format: date
hours:
type: number
projectCode:
type: string
projectName:
type: string
required:
- timesheetId
- timesheetLineId
- entryId
- date
- hours
- projectCode
- projectName