refactor(modules): removed swagger entities and added docs to dtos

This commit is contained in:
Matthieu Haineault 2025-08-11 14:08:55 -04:00
parent a99f39bbf6
commit 80ddc853a4
32 changed files with 610 additions and 892 deletions

View File

@ -169,7 +169,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmployeeEntity"
"$ref": "#/components/schemas/CreateEmployeeDto"
}
}
}
@ -199,7 +199,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EmployeeEntity"
"$ref": "#/components/schemas/CreateEmployeeDto"
}
}
}
@ -239,7 +239,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmployeeEntity"
"$ref": "#/components/schemas/CreateEmployeeDto"
}
}
}
@ -318,7 +318,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmployeeEntity"
"$ref": "#/components/schemas/CreateEmployeeDto"
}
}
}
@ -328,7 +328,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmployeeEntity"
"$ref": "#/components/schemas/CreateEmployeeDto"
}
}
}
@ -371,7 +371,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TimesheetEntity"
"$ref": "#/components/schemas/CreateTimesheetDto"
}
}
}
@ -401,7 +401,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TimesheetEntity"
"$ref": "#/components/schemas/CreateTimesheetDto"
}
}
}
@ -441,7 +441,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TimesheetEntity"
"$ref": "#/components/schemas/CreateTimesheetDto"
}
}
}
@ -488,7 +488,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TimesheetEntity"
"$ref": "#/components/schemas/CreateTimesheetDto"
}
}
}
@ -525,7 +525,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TimesheetEntity"
"$ref": "#/components/schemas/CreateTimesheetDto"
}
}
}
@ -593,7 +593,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExpenseEntity"
"$ref": "#/components/schemas/CreateExpenseDto"
}
}
}
@ -623,7 +623,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ExpenseEntity"
"$ref": "#/components/schemas/CreateExpenseDto"
}
}
}
@ -663,7 +663,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExpenseEntity"
"$ref": "#/components/schemas/CreateExpenseDto"
}
}
}
@ -710,7 +710,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExpenseEntity"
"$ref": "#/components/schemas/CreateExpenseDto"
}
}
}
@ -747,7 +747,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExpenseEntity"
"$ref": "#/components/schemas/CreateExpenseDto"
}
}
}
@ -815,7 +815,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ShiftEntity"
"$ref": "#/components/schemas/CreateShiftDto"
}
}
}
@ -845,7 +845,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ShiftEntity"
"$ref": "#/components/schemas/CreateShiftDto"
}
}
}
@ -885,7 +885,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ShiftEntity"
"$ref": "#/components/schemas/CreateShiftDto"
}
}
}
@ -932,7 +932,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ShiftEntity"
"$ref": "#/components/schemas/CreateShiftDto"
}
}
}
@ -969,7 +969,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ShiftEntity"
"$ref": "#/components/schemas/CreateShiftDto"
}
}
}
@ -1079,7 +1079,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LeaveRequestEntity"
"$ref": "#/components/schemas/CreateLeaveRequestsDto"
}
}
}
@ -1109,7 +1109,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/LeaveRequestEntity"
"$ref": "#/components/schemas/CreateLeaveRequestsDto"
}
}
}
@ -1149,7 +1149,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LeaveRequestEntity"
"$ref": "#/components/schemas/CreateLeaveRequestsDto"
}
}
}
@ -1196,7 +1196,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LeaveRequestEntity"
"$ref": "#/components/schemas/CreateLeaveRequestsDto"
}
}
}
@ -1233,7 +1233,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LeaveRequestEntity"
"$ref": "#/components/schemas/CreateLeaveRequestsDto"
}
}
}
@ -1471,7 +1471,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomerEntity"
"$ref": "#/components/schemas/CreateCustomerDto"
}
}
}
@ -1501,7 +1501,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CustomerEntity"
"$ref": "#/components/schemas/CreateCustomerDto"
}
}
}
@ -1541,7 +1541,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomerEntity"
"$ref": "#/components/schemas/CreateCustomerDto"
}
}
}
@ -1588,7 +1588,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomerEntity"
"$ref": "#/components/schemas/CreateCustomerDto"
}
}
}
@ -1625,7 +1625,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomerEntity"
"$ref": "#/components/schemas/CreateCustomerDto"
}
}
}
@ -1665,7 +1665,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OAuthSessionEntity"
"$ref": "#/components/schemas/CreateOauthSessionDto"
}
}
}
@ -1695,7 +1695,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/OAuthSessionEntity"
"$ref": "#/components/schemas/CreateOauthSessionDto"
}
}
}
@ -1735,7 +1735,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OAuthSessionEntity"
"$ref": "#/components/schemas/CreateOauthSessionDto"
}
}
}
@ -1782,7 +1782,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OAuthSessionEntity"
"$ref": "#/components/schemas/CreateOauthSessionDto"
}
}
}
@ -1819,7 +1819,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OAuthSessionEntity"
"$ref": "#/components/schemas/CreateOauthSessionDto"
}
}
}
@ -2119,10 +2119,6 @@
"contact": {}
},
"tags": [
{
"name": "Users",
"description": ""
},
{
"name": "Employees",
"description": ""
@ -2142,18 +2138,6 @@
{
"name": "Leave Requests",
"description": ""
},
{
"name": "Shift Codes",
"description": ""
},
{
"name": "OAuth Access Tokens",
"description": ""
},
{
"name": "Authorization",
"description": ""
}
],
"servers": [],
@ -2172,6 +2156,16 @@
"CreateEmployeeDto": {
"type": "object",
"properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of an employee(primary-key, auto-incremented)"
},
"user_id": {
"type": "string",
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID of the user linked to that employee"
},
"first_name": {
"type": "string",
"example": "Frodo",
@ -2199,12 +2193,12 @@
},
"external_payroll_id": {
"type": "number",
"example": "BagginsF7464",
"description": "Employee`s payroll id"
"example": 7464,
"description": "external ID for the pay system"
},
"company_code": {
"type": "number",
"example": "335567447",
"example": 335567447,
"description": "Employee`s company code"
},
"first_work_day": {
@ -2221,6 +2215,8 @@
}
},
"required": [
"id",
"user_id",
"first_name",
"last_name",
"email",
@ -2230,7 +2226,7 @@
"first_work_day"
]
},
"EmployeeEntity": {
"UpdateEmployeeDto": {
"type": "object",
"properties": {
"id": {
@ -2243,40 +2239,6 @@
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID of the user linked to that employee"
},
"external_payroll_id": {
"type": "number",
"example": 7464,
"description": "external ID for the pay system"
},
"company_code": {
"type": "number",
"example": 335567447,
"description": "company code"
},
"first_work_day": {
"format": "date-time",
"type": "string",
"example": "3018-09-23T00:00:00.000Z",
"description": "Employee first day at work"
},
"last_work_day": {
"format": "date-time",
"type": "string",
"example": "3019-03-25T00:00:00.000Z",
"description": "Employee last day at work"
}
},
"required": [
"id",
"user_id",
"external_payroll_id",
"company_code",
"first_work_day"
]
},
"UpdateEmployeeDto": {
"type": "object",
"properties": {
"first_name": {
"type": "string",
"example": "Frodo",
@ -2304,12 +2266,12 @@
},
"external_payroll_id": {
"type": "number",
"example": "BagginsF7464",
"description": "Employee`s payroll id"
"example": 7464,
"description": "external ID for the pay system"
},
"company_code": {
"type": "number",
"example": "335567447",
"example": 335567447,
"description": "Employee`s company code"
},
"first_work_day": {
@ -2333,23 +2295,29 @@
"CreateTimesheetDto": {
"type": "object",
"properties": {
"id": {
"type": "number",
"example": 1,
"description": "timesheet`s unique ID (auto-generated)"
},
"employee_id": {
"type": "number",
"example": "426433",
"example": 426433,
"description": "employee`s ID number of linked timsheet"
},
"is_approved": {
"type": "boolean",
"example": "True or False or Pending or Denied or Cancelled or Escalated",
"description": "Timesheet`s approval status"
"example": true,
"description": "Timesheet`s status approval"
}
},
"required": [
"id",
"employee_id",
"is_approved"
]
},
"TimesheetEntity": {
"UpdateTimesheetDto": {
"type": "object",
"properties": {
"id": {
@ -2365,35 +2333,11 @@
"is_approved": {
"type": "boolean",
"example": true,
"description": "Timesheet`s approval status"
}
},
"required": [
"id",
"employee_id",
"is_approved"
]
},
"UpdateTimesheetDto": {
"type": "object",
"properties": {
"employee_id": {
"type": "number",
"example": "426433",
"description": "employee`s ID number of linked timsheet"
},
"is_approved": {
"type": "boolean",
"example": "True or False or Pending or Denied or Cancelled or Escalated",
"description": "Timesheet`s approval status"
"description": "Timesheet`s status approval"
}
}
},
"CreateExpenseDto": {
"type": "object",
"properties": {}
},
"ExpenseEntity": {
"type": "object",
"properties": {
"id": {
@ -2417,16 +2361,21 @@
"example": "3018-10-20T00:00:00.000Z",
"description": "Date where the expense was made"
},
"is_approuved": {
"type": "boolean",
"example": "DENIED, APPROUVED, PENDING, etc...",
"description": "validation status"
"amount": {
"type": "number",
"example": 17.82,
"description": "amount in $ for a refund"
},
"description": {
"type": "string",
"example": "Spent for mileage between A and B",
"description": "explain`s why the expense was made"
},
"is_approved": {
"type": "boolean",
"example": "DENIED, APPROUVED, PENDING, etc...",
"description": "validation status"
},
"supervisor_comment": {
"type": "string",
"example": "Asked X to go there as an emergency response",
@ -2438,20 +2387,59 @@
"timesheet_id",
"bank_code_id",
"date",
"is_approuved",
"amount",
"description",
"is_approved",
"supervisor_comment"
]
},
"UpdateExpenseDto": {
"type": "object",
"properties": {}
"properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of the expense (auto-generated)"
},
"timesheet_id": {
"type": "number",
"example": 101,
"description": "ID number for a set timesheet"
},
"bank_code_id": {
"type": "number",
"example": 7,
"description": "ID number of an bank code (link with bank-codes)"
},
"date": {
"format": "date-time",
"type": "string",
"example": "3018-10-20T00:00:00.000Z",
"description": "Date where the expense was made"
},
"amount": {
"type": "number",
"example": 17.82,
"description": "amount in $ for a refund"
},
"description": {
"type": "string",
"example": "Spent for mileage between A and B",
"description": "explain`s why the expense was made"
},
"is_approved": {
"type": "boolean",
"example": "DENIED, APPROUVED, PENDING, etc...",
"description": "validation status"
},
"supervisor_comment": {
"type": "string",
"example": "Asked X to go there as an emergency response",
"description": "Supervisro`s justification for the spending of an employee"
}
}
},
"CreateShiftDto": {
"type": "object",
"properties": {}
},
"ShiftEntity": {
"type": "object",
"properties": {
"id": {
@ -2499,16 +2487,60 @@
},
"UpdateShiftsDto": {
"type": "object",
"properties": {}
"properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of the shift (auto-generated)"
},
"timesheet_id": {
"type": "number",
"example": 101,
"description": "ID number for a set timesheet"
},
"bank_code_id": {
"type": "number",
"example": 7,
"description": "ID number of a shift code (link with bank-codes)"
},
"date": {
"format": "date-time",
"type": "string",
"example": "3018-10-20T00:00:00.000Z",
"description": "Date where the shift takes place"
},
"start_time": {
"format": "date-time",
"type": "string",
"example": "3018-10-20T08:00:00.000Z",
"description": "Start time of the said shift"
},
"end_time": {
"format": "date-time",
"type": "string",
"example": "3018-10-20T17:00:00.000Z",
"description": "End time of the said shift"
}
}
},
"CreateLeaveRequestsDto": {
"type": "object",
"properties": {
"id": {
"type": "number",
"example": 1,
"description": "Leave request`s unique id(auto-incremented)"
},
"employee_id": {
"type": "number",
"example": "4655867",
"description": "Employee`s id"
},
"bank_code_id": {
"type": "number",
"example": 7,
"description": "ID number of a leave-request code (link with bank-codes)"
},
"leave_type": {
"type": "string",
"example": "Sick or Vacation or Unpaid or Bereavement or Parental or Legal",
@ -2538,7 +2570,9 @@
}
},
"required": [
"id",
"employee_id",
"bank_code_id",
"leave_type",
"start_date_time",
"end_date_time",
@ -2546,7 +2580,7 @@
"approval_status"
]
},
"LeaveRequestEntity": {
"UpdateLeaveRequestsDto": {
"type": "object",
"properties": {
"id": {
@ -2554,72 +2588,16 @@
"example": 1,
"description": "Leave request`s unique id(auto-incremented)"
},
"employee_id": {
"type": "number",
"example": 42,
"description": "ID of concerned employee"
},
"leave_type": {
"type": "string",
"example": "SICK",
"enum": [
"SICK",
"VACATION",
"UNPAID",
"BEREAVEMENT",
"PARENTAL",
"LEGAL",
"WEDDING"
],
"description": "type of leave request for an accounting perception"
},
"start_date_time": {
"format": "date-time",
"type": "string",
"example": "22/06/2463",
"description": "Leave request`s start date"
},
"end_date_time": {
"format": "date-time",
"type": "string",
"example": "25/03/3019",
"description": "Leave request`s end date (optionnal)"
},
"comment": {
"type": "string",
"example": "My precious",
"description": "Leave request employee`s comment"
},
"approval_status": {
"type": "string",
"example": "PENDING",
"enum": [
"PENDING",
"APPROVED",
"DENIED",
"CANCELLED",
"ESCALATED"
],
"description": "Leave request`s approval status"
}
},
"required": [
"id",
"employee_id",
"leave_type",
"start_date_time",
"comment",
"approval_status"
]
},
"UpdateLeaveRequestsDto": {
"type": "object",
"properties": {
"employee_id": {
"type": "number",
"example": "4655867",
"description": "Employee`s id"
},
"bank_code_id": {
"type": "number",
"example": 7,
"description": "ID number of a leave-request code (link with bank-codes)"
},
"leave_type": {
"type": "string",
"example": "Sick or Vacation or Unpaid or Bereavement or Parental or Legal",
@ -2651,15 +2629,84 @@
},
"CreateBankCodeDto": {
"type": "object",
"properties": {}
"properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of a bank-code (auto-generated)"
},
"type": {
"type": "string",
"example": "regular, vacation, emergency, sick, parental, etc",
"description": "Type of codes"
},
"categorie": {
"type": "string",
"example": "shift, expense, leave",
"description": "categorie of the related code"
},
"modifier": {
"type": "number",
"example": "0, 0.72, 1, 1.5, 2",
"description": "modifier number to apply to salary"
},
"bank_code": {
"type": "string",
"example": "G1, G345, G501, G43, G700",
"description": "codes given by the bank"
}
},
"required": [
"id",
"type",
"categorie",
"modifier",
"bank_code"
]
},
"UpdateBankCodeDto": {
"type": "object",
"properties": {}
"properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of a bank-code (auto-generated)"
},
"type": {
"type": "string",
"example": "regular, vacation, emergency, sick, parental, etc",
"description": "Type of codes"
},
"categorie": {
"type": "string",
"example": "shift, expense, leave",
"description": "categorie of the related code"
},
"modifier": {
"type": "number",
"example": "0, 0.72, 1, 1.5, 2",
"description": "modifier number to apply to salary"
},
"bank_code": {
"type": "string",
"example": "G1, G345, G501, G43, G700",
"description": "codes given by the bank"
}
}
},
"CreateCustomerDto": {
"type": "object",
"properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of a customer(primary-key, auto-incremented)"
},
"user_id": {
"type": "string",
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID of the user linked to that customer"
},
"first_name": {
"type": "string",
"example": "Gandalf",
@ -2692,13 +2739,15 @@
}
},
"required": [
"id",
"user_id",
"first_name",
"last_name",
"email",
"phone_number"
]
},
"CustomerEntity": {
"UpdateCustomerDto": {
"type": "object",
"properties": {
"id": {
@ -2711,36 +2760,6 @@
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID of the user linked to that customer"
},
"email": {
"type": "string",
"example": "you_shall_not_pass@middleEarth.com",
"description": "customer`s email (optional)"
},
"phone_number": {
"type": "number",
"example": 8436637464,
"description": "customer`s phone number (numbers only)"
},
"residence": {
"type": "string",
"example": "1 Ringbearers way, Mount Doom city, ME, T1R 1N6",
"description": "customer`s residence address (optional)"
},
"invoice_id": {
"type": "number",
"example": 4263253,
"description": "customer`s invoice number (optionnal, unique)"
}
},
"required": [
"id",
"user_id",
"phone_number"
]
},
"UpdateCustomerDto": {
"type": "object",
"properties": {
"first_name": {
"type": "string",
"example": "Gandalf",
@ -2776,6 +2795,11 @@
"CreateOauthSessionDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"example": "cklwi0vb70000z2z20q6f19qk",
"description": "Unique ID of an OAuth token (auto-generated)"
},
"user_id": {
"type": "string",
"example": "S7A2U8R7O6N6",
@ -2818,6 +2842,7 @@
}
},
"required": [
"id",
"user_id",
"application",
"access_token",
@ -2825,7 +2850,7 @@
"access_token_expiry"
]
},
"OAuthSessionEntity": {
"UpdateOauthSessionDto": {
"type": "object",
"properties": {
"id": {
@ -2833,82 +2858,6 @@
"example": "cklwi0vb70000z2z20q6f19qk",
"description": "Unique ID of an OAuth token (auto-generated)"
},
"user_id": {
"type": "string",
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID User`s unique identification number"
},
"application": {
"type": "string",
"example": "app.targo.ca",
"description": "URL in which the access token is used for"
},
"access_token": {
"type": "string",
"example": "L5O6R4D3/O6F3#T8H4E3&R6I4N6G4S7",
"description": "Access token"
},
"refresh_token": {
"type": "string",
"example": "Th3731102h1p07Th3R1n92",
"description": "Refresh token"
},
"access_token_expiry": {
"format": "date-time",
"type": "string",
"example": "3018-12-25T00:00:00.000Z",
"description": "Access token`s expiry date"
},
"refresh_token_expiry": {
"format": "date-time",
"type": "string",
"example": "3019-02-26T00:00:00.000Z",
"description": "Refresh token`s expiry date (optional)"
},
"scopes": {
"example": [
"email",
"profile",
"access_tolkiens"
],
"description": "scopes of infos linked to the access token",
"type": "array",
"items": {
"type": "string"
}
},
"is_revoked": {
"type": "boolean",
"example": false,
"description": "revoke status"
},
"created_at": {
"format": "date-time",
"type": "string",
"example": "2025-07-22",
"description": "creation date"
},
"updated_at": {
"format": "date-time",
"type": "string",
"example": "2025-07-23",
"description": "Latest update (optional)"
}
},
"required": [
"id",
"user_id",
"application",
"access_token",
"refresh_token",
"access_token_expiry",
"is_revoked",
"created_at"
]
},
"UpdateOauthSessionDto": {
"type": "object",
"properties": {
"user_id": {
"type": "string",
"example": "S7A2U8R7O6N6",

View File

@ -1,19 +1,41 @@
import { ApiProperty } from "@nestjs/swagger";
import { IsNotEmpty, IsNumber, IsString } from "class-validator";
export class CreateBankCodeDto {
@ApiProperty({
example: 1,
description: 'Unique ID of a bank-code (auto-generated)',
})
id: number;
@ApiProperty({
example: 'regular, vacation, emergency, sick, parental, etc',
description: 'Type of codes',
})
@IsString()
@IsNotEmpty()
type: string;
@ApiProperty({
example: 'shift, expense, leave',
description: 'categorie of the related code',
})
@IsString()
@IsNotEmpty()
categorie: string;
@ApiProperty({
example: '0, 0.72, 1, 1.5, 2',
description: 'modifier number to apply to salary',
})
@IsNumber()
@IsNotEmpty()
modifier: number;
@ApiProperty({
example: 'G1, G345, G501, G43, G700',
description: 'codes given by the bank',
})
@IsString()
@IsNotEmpty()
bank_code: string;

View File

@ -1,34 +0,0 @@
import { ApiProperty } from "@nestjs/swagger";
export class BankCodesEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of a bank-code (auto-generated)',
})
id: number;
@ApiProperty({
example: 'regular, vacation, emergency, sick, parental, etc',
description: 'Type of codes',
})
type: string;
@ApiProperty({
example: 'shift, expense, leave',
description: 'categorie of the related code',
})
categorie: string;
@ApiProperty({
example: '0, 0.72, 1, 1.5, 2',
description: 'modifier number to apply to salary',
})
modifier: number;
@ApiProperty({
example: 'G1, G345, G501, G43, G700',
description: 'codes given by the bank',
})
bank_code: string;
}

View File

@ -6,7 +6,6 @@ import { UpdateCustomerDto } from '../dtos/update-customer.dto';
import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { CustomerEntity } from '../dtos/swagger-entities/customers.entity';
@ApiTags('Customers')
@ApiBearerAuth('access-token')
@ -18,7 +17,7 @@ export class CustomersController {
@Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Create customer' })
@ApiResponse({ status: 201, description: 'Customer created', type: CustomerEntity })
@ApiResponse({ status: 201, description: 'Customer created', type: CreateCustomerDto })
@ApiResponse({ status: 400, description: 'Invalid task or invalid data' })
create(@Body() dto: CreateCustomerDto): Promise<Customers> {
return this.customersService.create(dto);
@ -27,7 +26,7 @@ export class CustomersController {
@Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find all customers' })
@ApiResponse({ status: 201, description: 'List of customers found', type: CustomerEntity, isArray: true })
@ApiResponse({ status: 201, description: 'List of customers found', type: CreateCustomerDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of customers not found' })
findAll(): Promise<Customers[]> {
return this.customersService.findAll();
@ -36,7 +35,7 @@ export class CustomersController {
@Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find customer' })
@ApiResponse({ status: 201, description: 'Customer found', type: CustomerEntity })
@ApiResponse({ status: 201, description: 'Customer found', type: CreateCustomerDto })
@ApiResponse({ status: 400, description: 'Customer not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<Customers> {
return this.customersService.findOne(id);
@ -45,7 +44,7 @@ export class CustomersController {
@Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE,RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Update customer' })
@ApiResponse({ status: 201, description: 'Customer updated', type: CustomerEntity })
@ApiResponse({ status: 201, description: 'Customer updated', type: CreateCustomerDto })
@ApiResponse({ status: 400, description: 'Customer not found' })
update(
@Param('id', ParseIntPipe) id: number,
@ -57,7 +56,7 @@ export class CustomersController {
@Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Delete customer' })
@ApiResponse({ status: 201, description: 'Customer deleted', type: CustomerEntity })
@ApiResponse({ status: 201, description: 'Customer deleted', type: CreateCustomerDto })
@ApiResponse({ status: 400, description: 'Customer not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<Customers>{
return this.customersService.remove(id);

View File

@ -10,6 +10,17 @@ import {
} from "class-validator";
export class CreateCustomerDto {
@ApiProperty({
example: 1,
description: 'Unique ID of a customer(primary-key, auto-incremented)',
})
id: number;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID of the user linked to that customer',
})
user_id: string;
@ApiProperty({
example: 'Gandalf',

View File

@ -1,42 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class CustomerEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of a customer(primary-key, auto-incremented)',
})
id: number;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID of the user linked to that customer',
})
user_id: string;
@ApiProperty({
example: 'you_shall_not_pass@middleEarth.com',
description: 'customer`s email (optional)',
required: false,
})
email?: string;
@ApiProperty({
example: 8436637464,
description: 'customer`s phone number (numbers only)',
})
phone_number: number;
@ApiProperty({
example: '1 Ringbearers way, Mount Doom city, ME, T1R 1N6',
description: 'customer`s residence address (optional)',
required: false,
})
residence?: string;
@ApiProperty({
example: 4263253,
description: 'customer`s invoice number (optionnal, unique)',
required: false,
})
invoice_id?: number;
}

View File

@ -5,7 +5,6 @@ import { CreateEmployeeDto } from '../dtos/create-employee.dto';
import { UpdateEmployeeDto } from '../dtos/update-employee.dto';
import { RolesAllowed } from '../../../common/decorators/roles.decorators';
import { ApiBearerAuth, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
import { EmployeeEntity } from '../dtos/swagger-entities/employees.entity';
@ApiTags('Employees')
@ApiBearerAuth('access-token')
@ -17,7 +16,7 @@ export class EmployeesController {
@Post()
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Create employee' })
@ApiResponse({ status: 201, description: 'Employee created', type: EmployeeEntity })
@ApiResponse({ status: 201, description: 'Employee created', type: CreateEmployeeDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateEmployeeDto): Promise<Employees> {
return this.employeesService.create(dto);
@ -26,7 +25,7 @@ export class EmployeesController {
@Get()
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ACCOUNTING)
@ApiOperation({summary: 'Find all employees' })
@ApiResponse({ status: 200, description: 'List of employees found', type: EmployeeEntity, isArray: true })
@ApiResponse({ status: 200, description: 'List of employees found', type: CreateEmployeeDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of employees not found' })
findAll(): Promise<Employees[]> {
return this.employeesService.findAll();
@ -35,7 +34,7 @@ export class EmployeesController {
@Get(':id')
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR,RoleEnum.ACCOUNTING )
@ApiOperation({summary: 'Find employee' })
@ApiResponse({ status: 200, description: 'Employee found', type: EmployeeEntity })
@ApiResponse({ status: 200, description: 'Employee found', type: CreateEmployeeDto })
@ApiResponse({ status: 400, description: 'Employee not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<Employees> {
return this.employeesService.findOne(id);
@ -56,8 +55,8 @@ export class EmployeesController {
@ApiBearerAuth('access-token')
@ApiOperation({ summary: 'Update, archive or restore an employee' })
@ApiParam({ name: 'id', type: Number, description: 'Identifier of the employee' })
@ApiResponse({ status: 200, description: 'Employee updated or restored', type: EmployeeEntity })
@ApiResponse({ status: 202, description: 'Employee archived successfully', type: EmployeeEntity })
@ApiResponse({ status: 200, description: 'Employee updated or restored', type: CreateEmployeeDto })
@ApiResponse({ status: 202, description: 'Employee archived successfully', type: CreateEmployeeDto })
@ApiResponse({ status: 404, description: 'Employee not found in active or archive' })
@Patch(':id')
async updateOrArchiveOrRestore(@Param('id') id: string, @Body() dto: UpdateEmployeeDto,) {

View File

@ -12,6 +12,17 @@ import { Type } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger';
export class CreateEmployeeDto {
@ApiProperty({
example: 1,
description: 'Unique ID of an employee(primary-key, auto-incremented)',
})
id: number;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID of the user linked to that employee',
})
user_id: string;
@ApiProperty({
example: 'Frodo',
@ -56,8 +67,8 @@ export class CreateEmployeeDto {
residence?: string;
@ApiProperty({
example: 'BagginsF7464',
description: 'Employee`s payroll id',
example: 7464,
description: 'external ID for the pay system',
})
@IsInt()
@IsPositive()
@ -65,7 +76,7 @@ export class CreateEmployeeDto {
external_payroll_id: number;
@ApiProperty({
example: '335567447',
example: 335567447,
description: 'Employee`s company code',
})
@IsInt()

View File

@ -1,40 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class EmployeeEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of an employee(primary-key, auto-incremented)',
})
id: number;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID of the user linked to that employee',
})
user_id: string;
@ApiProperty({
example: 7464,
description: 'external ID for the pay system',
})
external_payroll_id: number;
@ApiProperty({
example: 335567447,
description: 'company code',
})
company_code: number;
@ApiProperty({
example: '3018-09-23T00:00:00.000Z',
description: 'Employee first day at work',
})
first_work_day: Date;
@ApiProperty({
example: '3019-03-25T00:00:00.000Z',
description: 'Employee last day at work',
required: false,
})
last_work_day?: Date;
}

View File

@ -6,7 +6,6 @@ import { Roles as RoleEnum } from '.prisma/client';
import { UpdateExpenseDto } from "../dtos/update-expense.dto";
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { ExpenseEntity } from "../dtos/swagger-entities/expenses.entity";
import { ExpensesApprovalService } from "../services/expenses-approval.service";
import { SearchExpensesDto } from "../dtos/search-expense.dto";
@ -23,7 +22,7 @@ export class ExpensesController {
@Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Create expense' })
@ApiResponse({ status: 201, description: 'Expense created',type: ExpenseEntity })
@ApiResponse({ status: 201, description: 'Expense created',type: CreateExpenseDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateExpenseDto): Promise<Expenses> {
return this.expensesService.create(dto);
@ -32,7 +31,7 @@ export class ExpensesController {
@Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find all expenses' })
@ApiResponse({ status: 201, description: 'List of expenses found',type: ExpenseEntity, isArray: true })
@ApiResponse({ status: 201, description: 'List of expenses found',type: CreateExpenseDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of expenses not found' })
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
findAll(@Query() filters: SearchExpensesDto): Promise<Expenses[]> {
@ -42,7 +41,7 @@ export class ExpensesController {
@Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find expense' })
@ApiResponse({ status: 201, description: 'Expense found',type: ExpenseEntity })
@ApiResponse({ status: 201, description: 'Expense found',type: CreateExpenseDto })
@ApiResponse({ status: 400, description: 'Expense not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise <Expenses> {
return this.expensesService.findOne(id);
@ -51,7 +50,7 @@ export class ExpensesController {
@Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Expense shift' })
@ApiResponse({ status: 201, description: 'Expense updated',type: ExpenseEntity })
@ApiResponse({ status: 201, description: 'Expense updated',type: CreateExpenseDto })
@ApiResponse({ status: 400, description: 'Expense not found' })
update(@Param('id', ParseIntPipe) id: number, @Body() dto: UpdateExpenseDto) {
return this.expensesService.update(id,dto);
@ -60,7 +59,7 @@ export class ExpensesController {
@Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Delete expense' })
@ApiResponse({ status: 201, description: 'Expense deleted',type: ExpenseEntity })
@ApiResponse({ status: 201, description: 'Expense deleted',type: CreateExpenseDto })
@ApiResponse({ status: 400, description: 'Expense not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<Expenses> {
return this.expensesService.remove(id);

View File

@ -1,32 +1,67 @@
import { ApiProperty } from "@nestjs/swagger";
import { Type } from "class-transformer";
import { IsBoolean, IsDate, IsDateString, IsInt, IsOptional, IsString } from "class-validator";
export class CreateExpenseDto {
@ApiProperty({
example: 1,
description: 'Unique ID of the expense (auto-generated)',
})
id: number;
@ApiProperty({
example: 101,
description: 'ID number for a set timesheet',
})
@Type(()=> Number)
@IsInt()
timesheet_id: number;
@ApiProperty({
example: 7,
description: 'ID number of an bank code (link with bank-codes)',
})
@Type(() => Number)
@IsInt()
bank_code_id: number;
@ApiProperty({
example: '3018-10-20T00:00:00.000Z',
description: 'Date where the expense was made',
})
@IsDateString()
@Type(() => Date)
@IsDate()
date: Date;
@ApiProperty({
example: 17.82,
description: 'amount in $ for a refund',
})
@Type(() => Number)
@IsInt()
amount: number
@ApiProperty({
example:'Spent for mileage between A and B',
description:'explain`s why the expense was made'
})
@IsString()
description?: string;
@ApiProperty({
example: 'DENIED, APPROUVED, PENDING, etc...',
description: 'validation status',
})
@IsOptional()
@IsBoolean()
is_approved?: boolean;
@ApiProperty({
example:'Asked X to go there as an emergency response',
description:'Supervisro`s justification for the spending of an employee'
})
@IsString()
supervisor_comment?: string;
}

View File

@ -1,46 +0,0 @@
import { ApiProperty } from "@nestjs/swagger";
export class ExpenseEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of the expense (auto-generated)',
})
id: number;
@ApiProperty({
example: 101,
description: 'ID number for a set timesheet',
})
timesheet_id: number;
@ApiProperty({
example: 7,
description: 'ID number of an bank code (link with bank-codes)',
})
bank_code_id: number;
@ApiProperty({
example: '3018-10-20T00:00:00.000Z',
description: 'Date where the expense was made',
})
date: Date;
@ApiProperty({
example: 'DENIED, APPROUVED, PENDING, etc...',
description: 'validation status',
})
is_approuved: boolean;
@ApiProperty({
example:'Spent for mileage between A and B',
description:'explain`s why the expense was made'
})
description: string;
@ApiProperty({
example:'Asked X to go there as an emergency response',
description:'Supervisro`s justification for the spending of an employee'
})
supervisor_comment: string;
}

View File

@ -6,7 +6,6 @@ import { UpdateLeaveRequestsDto } from "../dtos/update-leave-requests.dto";
import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { LeaveApprovalStatus, Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { LeaveRequestEntity } from "../dtos/swagger-entities/leave-requests.entity";
import { SearchLeaveRequestsDto } from "../dtos/search-leave-requests.dto";
@ApiTags('Leave Requests')
@ -19,7 +18,7 @@ export class LeaveRequestController {
@Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Create leave request' })
@ApiResponse({ status: 201, description: 'Leave request created',type: LeaveRequestEntity })
@ApiResponse({ status: 201, description: 'Leave request created',type: CreateLeaveRequestsDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateLeaveRequestsDto): Promise<LeaveRequests> {
return this. leaveRequetsService.create(dto);
@ -28,7 +27,7 @@ export class LeaveRequestController {
@Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Find all leave request' })
@ApiResponse({ status: 201, description: 'List of Leave requests found',type: LeaveRequestEntity, isArray: true })
@ApiResponse({ status: 201, description: 'List of Leave requests found',type: CreateLeaveRequestsDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of leave request not found' })
@UsePipes(new ValidationPipe({transform: true, whitelist: true}))
findAll(@Query() filters: SearchLeaveRequestsDto): Promise<(LeaveRequests & {daysRequested:number; cost: number})[]> {
@ -38,7 +37,7 @@ export class LeaveRequestController {
@Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Find leave request' })
@ApiResponse({ status: 201, description: 'Leave request found',type: LeaveRequestEntity })
@ApiResponse({ status: 201, description: 'Leave request found',type: CreateLeaveRequestsDto })
@ApiResponse({ status: 400, description: 'Leave request not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<LeaveRequests> {
return this.leaveRequetsService.findOne(id);
@ -47,7 +46,7 @@ export class LeaveRequestController {
@Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Update leave request' })
@ApiResponse({ status: 201, description: 'Leave request updated',type: LeaveRequestEntity })
@ApiResponse({ status: 201, description: 'Leave request updated',type: CreateLeaveRequestsDto })
@ApiResponse({ status: 400, description: 'Leave request not found' })
update(@Param('id', ParseIntPipe) id: number,@Body() dto: UpdateLeaveRequestsDto): Promise<LeaveRequests> {
return this.leaveRequetsService.update(id, dto);
@ -56,7 +55,7 @@ export class LeaveRequestController {
@Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Delete leave request' })
@ApiResponse({ status: 201, description: 'Leave request deleted',type: LeaveRequestEntity })
@ApiResponse({ status: 201, description: 'Leave request deleted',type: CreateLeaveRequestsDto })
@ApiResponse({ status: 400, description: 'Leave request not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<LeaveRequests> {
return this.leaveRequetsService.remove(id);

View File

@ -4,6 +4,11 @@ import { Type } from "class-transformer";
import { IsEnum, IsInt, IsNotEmpty, IsOptional, IsString } from "class-validator";
export class CreateLeaveRequestsDto {
@ApiProperty({
example: 1,
description: 'Leave request`s unique id(auto-incremented)',
})
id: number;
@ApiProperty({
example: '4655867',
description: 'Employee`s id',
@ -12,6 +17,10 @@ export class CreateLeaveRequestsDto {
@IsInt()
employee_id: number;
@ApiProperty({
example: 7,
description: 'ID number of a leave-request code (link with bank-codes)',
})
@Type(()=> Number)
@IsInt()
bank_code_id: number;

View File

@ -1,49 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
import { LeaveApprovalStatus, LeaveTypes } from '@prisma/client';
export class LeaveRequestEntity {
@ApiProperty({
example: 1,
description: 'Leave request`s unique id(auto-incremented)',
})
id: number;
@ApiProperty({
example: 42,
description: 'ID of concerned employee',
})
employee_id: number;
@ApiProperty({
example: 'SICK',
enum: LeaveTypes,
description: 'type of leave request for an accounting perception',
})
leave_type: LeaveTypes;
@ApiProperty({
example: '22/06/2463',
description: 'Leave request`s start date',
})
start_date_time: Date;
@ApiProperty({
example: '25/03/3019',
description: 'Leave request`s end date (optionnal)',
required: false,
})
end_date_time?: Date;
@ApiProperty({
example: 'My precious',
description: 'Leave request employee`s comment',
})
comment: string;
@ApiProperty({
example: 'PENDING',
enum: LeaveApprovalStatus,
description: 'Leave request`s approval status',
})
approval_status: LeaveApprovalStatus;
}

View File

@ -5,7 +5,6 @@ import { Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { CreateOauthSessionDto } from '../dtos/create-oauth-sessions.dto';
import { OauthSessionsService } from '../services/oauth-sessions.service';
import { OAuthSessionEntity } from '../dtos/swagger-entities/oauth-sessions.entity';
import { UpdateOauthSessionDto } from '../dtos/update-oauth-sessions.dto';
@ApiTags('OAuth Sessions')
@ -18,7 +17,7 @@ export class OauthSessionsController {
@Post()
@RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Create OAuth session' })
@ApiResponse({ status: 201, description: 'OAuth session created', type: OAuthSessionEntity })
@ApiResponse({ status: 201, description: 'OAuth session created', type: CreateOauthSessionDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body()dto: CreateOauthSessionDto): Promise<OAuthSessions> {
return this.oauthSessionsService.create(dto);
@ -27,7 +26,7 @@ export class OauthSessionsController {
@Get()
@RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Find all OAuth session' })
@ApiResponse({ status: 201, description: 'List of OAuth session found', type: OAuthSessionEntity, isArray: true })
@ApiResponse({ status: 201, description: 'List of OAuth session found', type: CreateOauthSessionDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of OAuth session not found' })
findAll(): Promise<OAuthSessions[]> {
return this.oauthSessionsService.findAll();
@ -36,7 +35,7 @@ export class OauthSessionsController {
@Get(':id')
@RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Find OAuth session' })
@ApiResponse({ status: 201, description: 'OAuth session found', type: OAuthSessionEntity })
@ApiResponse({ status: 201, description: 'OAuth session found', type: CreateOauthSessionDto })
@ApiResponse({ status: 400, description: 'OAuth session not found' })
findOne(@Param('id') id: string): Promise<OAuthSessions> {
return this.oauthSessionsService.findOne(id);
@ -45,7 +44,7 @@ export class OauthSessionsController {
@Patch(':id')
@RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Update OAuth session' })
@ApiResponse({ status: 201, description: 'OAuth session updated', type: OAuthSessionEntity })
@ApiResponse({ status: 201, description: 'OAuth session updated', type: CreateOauthSessionDto })
@ApiResponse({ status: 400, description: 'OAuth session not found' })
update(@Param('id') id: string, @Body() dto: UpdateOauthSessionDto): Promise<OAuthSessions> {
return this.oauthSessionsService.update(id,dto);
@ -54,7 +53,7 @@ export class OauthSessionsController {
@Delete(':id')
@RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Delete OAuth session' })
@ApiResponse({ status: 201, description: 'OAuth session deleted', type: OAuthSessionEntity })
@ApiResponse({ status: 201, description: 'OAuth session deleted', type: CreateOauthSessionDto })
@ApiResponse({ status: 400, description: 'OAuth session not found' })
remove(@Param('id') id: string): Promise<OAuthSessions> {
return this.oauthSessionsService.remove(id);

View File

@ -3,6 +3,11 @@ import { Type } from "class-transformer";
import { IsArray, IsDate, IsOptional, IsString, IsUUID } from "class-validator";
export class CreateOauthSessionDto {
@ApiProperty({
example: 'cklwi0vb70000z2z20q6f19qk',
description: 'Unique ID of an OAuth token (auto-generated)',
})
id: string;
@ApiProperty({
example: 'S7A2U8R7O6N6',

View File

@ -1,72 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class OAuthSessionEntity {
@ApiProperty({
example: 'cklwi0vb70000z2z20q6f19qk',
description: 'Unique ID of an OAuth token (auto-generated)',
})
id: string;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID User`s unique identification number',
})
user_id: string;
@ApiProperty({
example: 'app.targo.ca',
description: 'URL in which the access token is used for',
})
application: string;
@ApiProperty({
example: 'L5O6R4D3/O6F3#T8H4E3&R6I4N6G4S7',
description: 'Access token',
})
access_token: string;
@ApiProperty({
example: 'Th3731102h1p07Th3R1n92',
description: 'Refresh token',
})
refresh_token: string;
@ApiProperty({
example: '3018-12-25T00:00:00.000Z',
description: 'Access token`s expiry date',
})
access_token_expiry: Date;
@ApiProperty({
example: '3019-02-26T00:00:00.000Z',
description: 'Refresh token`s expiry date (optional)',
required: false,
})
refresh_token_expiry?: Date;
@ApiProperty({
example: ['email', 'profile', 'access_tolkiens'],
description: 'scopes of infos linked to the access token',
required: false,
})
scopes: string[];
@ApiProperty({
example: false,
description: 'revoke status',
})
is_revoked: boolean;
@ApiProperty({
example: '2025-07-22',
description: 'creation date',
})
created_at: Date;
@ApiProperty({
example: '2025-07-23',
description: 'Latest update (optional)',
required: false,
})
updated_at?: Date;
}

View File

@ -5,7 +5,7 @@ import { Module } from "@nestjs/common";
import { PayPeriodsCommandService } from "./services/pay-periods-command.service";
import { PayPeriodsQueryService } from "./services/pay-periods-query.service";
import { TimesheetsModule } from "../timesheets/timesheets.module";
import { TimesheetsApprovalService } from "../timesheets/services/timesheets-approval.service";
import { TimesheetsCommandService } from "../timesheets/services/timesheets-command.service";
import { ExpensesApprovalService } from "../expenses/services/expenses-approval.service";
import { ShiftsApprovalService } from "../shifts/services/shifts-approval.service";
@ -15,7 +15,7 @@ import { ShiftsApprovalService } from "../shifts/services/shifts-approval.servic
PayPeriodsService,
PayPeriodsQueryService,
PayPeriodsCommandService,
TimesheetsApprovalService,
TimesheetsCommandService,
ExpensesApprovalService,
ShiftsApprovalService,
],

View File

@ -1,12 +1,12 @@
import { Injectable, NotFoundException } from "@nestjs/common";
import { TimesheetsApprovalService } from "src/modules/timesheets/services/timesheets-approval.service";
import { TimesheetsCommandService } from "src/modules/timesheets/services/timesheets-command.service";
import { PrismaService } from "src/prisma/prisma.service";
@Injectable()
export class PayPeriodsCommandService {
constructor(
private readonly prisma: PrismaService,
private readonly timesheetsApproval: TimesheetsApprovalService,
private readonly timesheetsApproval: TimesheetsCommandService,
) {}
async approvalPayPeriod(year: number , periodNumber: number): Promise<void> {

View File

@ -6,7 +6,6 @@ import { UpdateShiftsDto } from "../dtos/update-shift.dto";
import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { ShiftEntity } from "../dtos/swagger-entities/shift.entity";
import { ShiftsApprovalService } from "../services/shifts-approval.service";
import { SearchShiftsDto } from "../dtos/search-shifts.dto";
@ -23,7 +22,7 @@ export class ShiftsController {
@Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Create shift' })
@ApiResponse({ status: 201, description: 'Shift created',type: ShiftEntity })
@ApiResponse({ status: 201, description: 'Shift created',type: CreateShiftDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateShiftDto): Promise<Shifts> {
return this.shiftsService.create(dto);
@ -32,7 +31,7 @@ export class ShiftsController {
@Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find all shifts' })
@ApiResponse({ status: 201, description: 'List of shifts found',type: ShiftEntity, isArray: true })
@ApiResponse({ status: 201, description: 'List of shifts found',type: CreateShiftDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of shifts not found' })
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
findAll(@Query() filters: SearchShiftsDto) {
@ -42,7 +41,7 @@ export class ShiftsController {
@Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find shift' })
@ApiResponse({ status: 201, description: 'Shift found',type: ShiftEntity })
@ApiResponse({ status: 201, description: 'Shift found',type: CreateShiftDto })
@ApiResponse({ status: 400, description: 'Shift not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<Shifts> {
return this.shiftsService.findOne(id);
@ -51,7 +50,7 @@ export class ShiftsController {
@Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Update shift' })
@ApiResponse({ status: 201, description: 'Shift updated',type: ShiftEntity })
@ApiResponse({ status: 201, description: 'Shift updated',type: CreateShiftDto })
@ApiResponse({ status: 400, description: 'Shift not found' })
update(@Param('id', ParseIntPipe) id: number,@Body() dto: UpdateShiftsDto): Promise<Shifts> {
return this.shiftsService.update(id, dto);
@ -60,7 +59,7 @@ export class ShiftsController {
@Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Delete shift' })
@ApiResponse({ status: 201, description: 'Shift deleted',type: ShiftEntity })
@ApiResponse({ status: 201, description: 'Shift deleted',type: CreateShiftDto })
@ApiResponse({ status: 400, description: 'Shift not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<Shifts> {
return this.shiftsService.remove(id);

View File

@ -1,26 +1,52 @@
import { ApiProperty } from "@nestjs/swagger";
import { Type } from "class-transformer";
import { IsDate, IsDateString, IsInt, IsString } from "class-validator";
export class CreateShiftDto {
@ApiProperty({
example: 1,
description: 'Unique ID of the shift (auto-generated)',
})
id: number;
@ApiProperty({
example: 101,
description: 'ID number for a set timesheet',
})
@Type(() => Number)
@IsInt()
timesheet_id: number;
@ApiProperty({
example: 7,
description: 'ID number of a shift code (link with bank-codes)',
})
@Type(() => Number)
@IsInt()
bank_code_id: number;
@ApiProperty({
example: '3018-10-20T00:00:00.000Z',
description: 'Date where the shift takes place',
})
@IsDateString()
@Type(() => Date)
@IsDate()
date: Date;
@ApiProperty({
example: '3018-10-20T08:00:00.000Z',
description: 'Start time of the said shift',
})
@IsDateString()
@Type(() => Date)
@IsDate()
start_time: Date;
@ApiProperty({
example: '3018-10-20T17:00:00.000Z',
description: 'End time of the said shift',
})
@IsDateString()
@Type(() => Date)
@IsDate()

View File

@ -1,39 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class ShiftEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of the shift (auto-generated)',
})
id: number;
@ApiProperty({
example: 101,
description: 'ID number for a set timesheet',
})
timesheet_id: number;
@ApiProperty({
example: 7,
description: 'ID number of a shift code (link with bank-codes)',
})
bank_code_id: number;
@ApiProperty({
example: '3018-10-20T00:00:00.000Z',
description: 'Date where the shift takes place',
})
date: Date;
@ApiProperty({
example: '3018-10-20T08:00:00.000Z',
description: 'Start time of the said shift',
})
start_time: Date;
@ApiProperty({
example: '3018-10-20T17:00:00.000Z',
description: 'End time of the said shift',
})
end_time: Date;
}

View File

@ -1,4 +1,4 @@
import { Injectable, NotFoundException } from "@nestjs/common";
import { Injectable } from "@nestjs/common";
import { Shifts } from "@prisma/client";
import { BaseApprovalService } from "src/common/shared/base-approval.service";
import { PrismaService } from "src/prisma/prisma.service";

View File

@ -32,8 +32,9 @@ export class ShiftsOverviewService {
where: { date: { gte: start_date, lte: end_date } },
include: {
bank_code: true,
timesheet: { include: { employee: {
include: { user:true,
timesheet: { include: {
employee: { include: {
user:true,
supervisor: { include: { user: true } },
} },
} },

View File

@ -6,8 +6,7 @@ import { UpdateTimesheetDto } from '../dtos/update-timesheet.dto';
import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { TimesheetEntity } from '../dtos/swagger-entities/timesheet.entity';
import { TimesheetsApprovalService } from '../services/timesheets-approval.service';
import { TimesheetsCommandService } from '../services/timesheets-command.service';
import { SearchTimesheetDto } from '../dtos/search-timesheets.dto';
@ApiTags('Timesheets')
@ -17,13 +16,13 @@ import { SearchTimesheetDto } from '../dtos/search-timesheets.dto';
export class TimesheetsController {
constructor(
private readonly timesheetsService: TimesheetsService,
private readonly timesheetsApprovalService: TimesheetsApprovalService,
private readonly timesheetsCommandService: TimesheetsCommandService,
) {}
@Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Create timesheet' })
@ApiResponse({ status: 201, description: 'Timesheet created', type: TimesheetEntity })
@ApiResponse({ status: 201, description: 'Timesheet created', type: CreateTimesheetDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateTimesheetDto): Promise<Timesheets> {
return this.timesheetsService.create(dto);
@ -32,7 +31,7 @@ export class TimesheetsController {
@Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find all timesheets' })
@ApiResponse({ status: 201, description: 'List of timesheet found', type: TimesheetEntity, isArray: true })
@ApiResponse({ status: 201, description: 'List of timesheet found', type: CreateTimesheetDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of timesheets not found' })
@UsePipes(new ValidationPipe({transform: true, whitelist: true }))
findAll(@Query() filters: SearchTimesheetDto): Promise<any[]> {
@ -42,7 +41,7 @@ export class TimesheetsController {
@Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find timesheet' })
@ApiResponse({ status: 201, description: 'Timesheet found', type: TimesheetEntity })
@ApiResponse({ status: 201, description: 'Timesheet found', type: CreateTimesheetDto })
@ApiResponse({ status: 400, description: 'Timesheet not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<Timesheets> {
return this.timesheetsService.findOne(id);
@ -51,7 +50,7 @@ export class TimesheetsController {
@Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Update timesheet' })
@ApiResponse({ status: 201, description: 'Timesheet updated', type: TimesheetEntity })
@ApiResponse({ status: 201, description: 'Timesheet updated', type: CreateTimesheetDto })
@ApiResponse({ status: 400, description: 'Timesheet not found' })
update(
@Param('id', ParseIntPipe) id:number,
@ -63,7 +62,7 @@ export class TimesheetsController {
@Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Delete timesheet' })
@ApiResponse({ status: 201, description: 'Timesheet deleted', type: TimesheetEntity })
@ApiResponse({ status: 201, description: 'Timesheet deleted', type: CreateTimesheetDto })
@ApiResponse({ status: 400, description: 'Timesheet not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<Timesheets> {
return this.timesheetsService.remove(id);
@ -72,6 +71,6 @@ export class TimesheetsController {
@Patch(':id/approval')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
async approve(@Param('id', ParseIntPipe) id: number, @Body('is_approved', ParseBoolPipe) isApproved: boolean) {
return this.timesheetsApprovalService.updateApproval(id, isApproved);
return this.timesheetsCommandService.updateApproval(id, isApproved);
}
}

View File

@ -3,9 +3,14 @@ import { Type } from "class-transformer";
import { IsBoolean, IsInt, IsOptional } from "class-validator";
export class CreateTimesheetDto {
@ApiProperty({
example: 1,
description: 'timesheet`s unique ID (auto-generated)',
})
id: number;
@ApiProperty({
example: '426433',
example: 426433,
description: 'employee`s ID number of linked timsheet',
})
@Type(() => Number)
@ -13,8 +18,8 @@ export class CreateTimesheetDto {
employee_id: number;
@ApiProperty({
example: 'True or False or Pending or Denied or Cancelled or Escalated',
description: 'Timesheet`s approval status',
example: true,
description: 'Timesheet`s status approval',
})
@IsOptional()
@IsBoolean()

View File

@ -6,15 +6,15 @@ export class SearchTimesheetDto {
@IsOptional()
@Type(() => Number)
@IsInt()
timesheet_id: number;
timesheet_id?: number;
@IsOptional()
@Type(()=> Number)
@IsInt()
employee_id: number;
employee_id?: number;
@IsOptional()
@Type(()=> Boolean)
@IsBoolean()
is_approved: boolean;
is_approved?: boolean;
}

View File

@ -1,21 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class TimesheetEntity {
@ApiProperty({
example: 1,
description: 'timesheet`s unique ID (auto-generated)',
})
id: number;
@ApiProperty({
example: 426433,
description: 'employee`s ID number of linked timsheet',
})
employee_id: number;
@ApiProperty({
example: true,
description: 'Timesheet`s approval status',
})
is_approved: boolean;
}

View File

@ -1,18 +1,12 @@
import { Injectable, NotFoundException } from "@nestjs/common";
import { Injectable } from "@nestjs/common";
import { Timesheets } from "@prisma/client";
import { BaseApprovalService } from "src/common/shared/base-approval.service";
import { ExpensesApprovalService } from "src/modules/expenses/services/expenses-approval.service";
import { ShiftsApprovalService } from "src/modules/shifts/services/shifts-approval.service";
import { PrismaService } from "src/prisma/prisma.service";
@Injectable()
export class TimesheetsApprovalService extends BaseApprovalService<Timesheets>{
constructor(
prisma: PrismaService,
private readonly shiftsApproval: ShiftsApprovalService,
private readonly expensesApproval: ExpensesApprovalService,
) {super(prisma);}
export class TimesheetsCommandService extends BaseApprovalService<Timesheets>{
constructor(prisma: PrismaService) {super(prisma);}
protected get delegate() {
return this.prisma.timesheets;

View File

@ -2,7 +2,7 @@ import { Module } from '@nestjs/common';
import { TimesheetsController } from './controllers/timesheets.controller';
import { TimesheetsService } from './services/timesheets.service';
import { BusinessLogicsModule } from 'src/modules/business-logics/business-logics.module';
import { TimesheetsApprovalService } from './services/timesheets-approval.service';
import { TimesheetsCommandService } from './services/timesheets-command.service';
import { ShiftsApprovalService } from '../shifts/services/shifts-approval.service';
import { ExpensesApprovalService } from '../expenses/services/expenses-approval.service';
@ -11,7 +11,7 @@ import { ExpensesApprovalService } from '../expenses/services/expenses-approval.
controllers: [TimesheetsController],
providers: [
TimesheetsService,
TimesheetsApprovalService,
TimesheetsCommandService,
ShiftsApprovalService,
ExpensesApprovalService
],

View File

@ -1,7 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { Roles } from '@prisma/client';
export class UserEntity {
export class UserDto {
@ApiProperty({
example: 'd67f05be-6dd1-464f-b5f7-31b325e21b4a',
description: 'User`s unique UUID (primary key)',