CRA-Helper/lib/api-spec/openapi.yaml
SylvainP1 bf72bbb7bb Add ability to include descriptions for time entries
Updates the API and UI to allow users to add optional descriptions to time entries, with a visual indicator for cells containing descriptions.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 55837015-10e9-4be9-b857-7f5e6be73772
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 3bc0faf3-6f86-46e5-8577-13a2e2e88062
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1cc377db-7ea0-49f2-97ce-c3e87e0228cc/55837015-10e9-4be9-b857-7f5e6be73772/Dzp7voC
Replit-Helium-Checkpoint-Created: true
2026-04-14 12:55:38 +00:00

771 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
description:
type: string
nullable: true
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
description:
type: string
nullable: true
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