From 9749d5658cc8ab67be4eb43e9dead0087cb2cb7a Mon Sep 17 00:00:00 2001 From: Jean Jacques Avril Date: Sun, 9 Mar 2025 19:55:23 +0000 Subject: [PATCH] feat: Add create and update DTOs for Company, Customer, Project, Activity, User, and TimeEntry entities --- backend/go.mod | 2 +- backend/internal/domain/entities/activity.go | 15 +- backend/internal/domain/entities/company.go | 9 ++ backend/internal/domain/entities/customer.go | 11 ++ backend/internal/domain/entities/project.go | 11 ++ backend/internal/domain/entities/timeentry.go | 21 +++ backend/internal/domain/entities/user.go | 17 +++ .../interfaces/http/dto/activity_dto.go | 11 ++ .../interfaces/http/dto/company_dto.go | 9 ++ .../interfaces/http/dto/customer_dto.go | 11 ++ .../interfaces/http/dto/project_dto.go | 15 +- .../interfaces/http/dto/timeentry_dto.go | 21 +++ .../internal/interfaces/http/dto/user_dto.go | 21 ++- backend/tygo.yml | 2 +- frontend/src/types/activity.ts | 19 +++ frontend/src/types/company.ts | 19 +++ frontend/src/types/customer.ts | 19 +++ frontend/src/types/dto.ts | 130 ++++++++++++++++++ frontend/src/types/index.ts | 62 --------- frontend/src/types/project.ts | 19 +++ frontend/src/types/timeentry.ts | 34 +++++ frontend/src/types/user.ts | 19 +++ 22 files changed, 430 insertions(+), 67 deletions(-) create mode 100644 frontend/src/types/activity.ts create mode 100644 frontend/src/types/company.ts create mode 100644 frontend/src/types/customer.ts create mode 100644 frontend/src/types/dto.ts delete mode 100644 frontend/src/types/index.ts create mode 100644 frontend/src/types/project.ts create mode 100644 frontend/src/types/timeentry.ts create mode 100644 frontend/src/types/user.ts diff --git a/backend/go.mod b/backend/go.mod index f559082..ddb98cb 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -4,6 +4,7 @@ go 1.23.6 require ( github.com/gin-gonic/gin v1.10.0 + github.com/oklog/ulid/v2 v2.1.0 github.com/swaggo/files v1.0.1 github.com/swaggo/gin-swagger v1.6.0 github.com/swaggo/swag v1.16.4 @@ -32,7 +33,6 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/oklog/ulid/v2 v2.1.0 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect diff --git a/backend/internal/domain/entities/activity.go b/backend/internal/domain/entities/activity.go index 56df0d3..3035183 100644 --- a/backend/internal/domain/entities/activity.go +++ b/backend/internal/domain/entities/activity.go @@ -1,9 +1,22 @@ package entities -import "github.com/oklog/ulid/v2" +import ( + "github.com/oklog/ulid/v2" +) type Activity struct { ID ulid.ULID Name string BillingRate float64 } + +type ActivityUpdate struct { + ID ulid.ULID + Name *string + BillingRate *float64 +} + +type ActivityCreate struct { + Name string + BillingRate float64 +} diff --git a/backend/internal/domain/entities/company.go b/backend/internal/domain/entities/company.go index d78ed4f..e6fb88f 100644 --- a/backend/internal/domain/entities/company.go +++ b/backend/internal/domain/entities/company.go @@ -6,3 +6,12 @@ type Company struct { ID ulid.ULID Name string } + +type CompanyCreate struct { + Name string +} + +type CompanyUpdate struct { + ID ulid.ULID + Name *string +} diff --git a/backend/internal/domain/entities/customer.go b/backend/internal/domain/entities/customer.go index 6badb90..c6d6daf 100644 --- a/backend/internal/domain/entities/customer.go +++ b/backend/internal/domain/entities/customer.go @@ -7,3 +7,14 @@ type Customer struct { Name string CompanyID int } + +type CustomerCreate struct { + Name string + CompanyID int +} + +type CustomerUpdate struct { + ID ulid.ULID + Name *string + CompanyID *int +} diff --git a/backend/internal/domain/entities/project.go b/backend/internal/domain/entities/project.go index e71daf0..310e16a 100644 --- a/backend/internal/domain/entities/project.go +++ b/backend/internal/domain/entities/project.go @@ -7,3 +7,14 @@ type Project struct { Name string CustomerID int } + +type ProjectCreate struct { + Name string + CustomerID int +} + +type ProjectUpdate struct { + ID ulid.ULID + Name *string + CustomerID *int +} diff --git a/backend/internal/domain/entities/timeentry.go b/backend/internal/domain/entities/timeentry.go index 19e20d7..7dbdda9 100644 --- a/backend/internal/domain/entities/timeentry.go +++ b/backend/internal/domain/entities/timeentry.go @@ -16,3 +16,24 @@ type TimeEntry struct { Description string Billable int // Percentage (0-100) } + +type TimeEntryCreate struct { + UserID int + ProjectID int + ActivityID int + Start time.Time + End time.Time + Description string + Billable int // Percentage (0-100) +} + +type TimeEntryUpdate struct { + ID ulid.ULID + UserID *int + ProjectID *int + ActivityID *int + Start *time.Time + End *time.Time + Description *string + Billable *int // Percentage (0-100) +} diff --git a/backend/internal/domain/entities/user.go b/backend/internal/domain/entities/user.go index e33a586..7818183 100644 --- a/backend/internal/domain/entities/user.go +++ b/backend/internal/domain/entities/user.go @@ -10,3 +10,20 @@ type User struct { CompanyID int HourlyRate float64 } + +type UserCreate struct { + Username string + Password string + Role string + CompanyID int + HourlyRate float64 +} + +type UserUpdate struct { + ID ulid.ULID + Username *string + Password *string + Role *string + CompanyID *int + HourlyRate *float64 +} diff --git a/backend/internal/interfaces/http/dto/activity_dto.go b/backend/internal/interfaces/http/dto/activity_dto.go index 4222886..cdb24ff 100644 --- a/backend/internal/interfaces/http/dto/activity_dto.go +++ b/backend/internal/interfaces/http/dto/activity_dto.go @@ -9,3 +9,14 @@ type ActivityDto struct { Name string `json:"name"` BillingRate float64 `json:"billingRate"` } + +type ActivityCreateDto struct { + Name string `json:"name"` + BillingRate float64 `json:"billingRate"` +} + +type ActivityUpdateDto struct { + ID ulid.ULID `json:"id"` + Name *string `json:"name"` + BillingRate *float64 `json:"billingRate"` +} diff --git a/backend/internal/interfaces/http/dto/company_dto.go b/backend/internal/interfaces/http/dto/company_dto.go index 53b6588..a151ec2 100644 --- a/backend/internal/interfaces/http/dto/company_dto.go +++ b/backend/internal/interfaces/http/dto/company_dto.go @@ -8,3 +8,12 @@ type CompanyDto struct { ID ulid.ULID `json:"id"` Name string `json:"name"` } + +type CompanyCreateDto struct { + Name string `json:"name"` +} + +type CompanyUpdateDto struct { + ID ulid.ULID `json:"id"` + Name *string `json:"name"` +} diff --git a/backend/internal/interfaces/http/dto/customer_dto.go b/backend/internal/interfaces/http/dto/customer_dto.go index c0e38fe..2616586 100644 --- a/backend/internal/interfaces/http/dto/customer_dto.go +++ b/backend/internal/interfaces/http/dto/customer_dto.go @@ -9,3 +9,14 @@ type CustomerDto struct { Name string `json:"name"` CompanyID int `json:"companyId"` } + +type CustomerCreateDto struct { + Name string `json:"name"` + CompanyID int `json:"companyId"` +} + +type CustomerUpdateDto struct { + ID ulid.ULID `json:"id"` + Name *string `json:"name"` + CompanyID *int `json:"companyId"` +} diff --git a/backend/internal/interfaces/http/dto/project_dto.go b/backend/internal/interfaces/http/dto/project_dto.go index d53dcd0..c0b3692 100644 --- a/backend/internal/interfaces/http/dto/project_dto.go +++ b/backend/internal/interfaces/http/dto/project_dto.go @@ -1,9 +1,22 @@ package dto -import "github.com/oklog/ulid/v2" +import ( + "github.com/oklog/ulid/v2" +) type ProjectDto struct { ID ulid.ULID `json:"id"` Name string `json:"name"` CustomerID int `json:"customerId"` } + +type ProjectCreateDto struct { + Name string `json:"name"` + CustomerID int `json:"customerId"` +} + +type ProjectUpdateDto struct { + ID ulid.ULID `json:"id"` + Name *string `json:"name"` + CustomerID *int `json:"customerId"` +} diff --git a/backend/internal/interfaces/http/dto/timeentry_dto.go b/backend/internal/interfaces/http/dto/timeentry_dto.go index 7053aa2..a182f7a 100644 --- a/backend/internal/interfaces/http/dto/timeentry_dto.go +++ b/backend/internal/interfaces/http/dto/timeentry_dto.go @@ -16,3 +16,24 @@ type TimeEntryDto struct { Description string `json:"description"` Billable int `json:"billable"` // Percentage (0-100) } + +type TimeEntryCreateDto struct { + UserID int `json:"userId"` + ProjectID int `json:"projectId"` + ActivityID int `json:"activityId"` + Start time.Time `json:"start"` + End time.Time `json:"end"` + Description string `json:"description"` + Billable int `json:"billable"` // Percentage (0-100) +} + +type TimeEntryUpdateDto struct { + ID ulid.ULID `json:"id"` + UserID *int `json:"userId"` + ProjectID *int `json:"projectId"` + ActivityID *int `json:"activityId"` + Start *time.Time `json:"start"` + End *time.Time `json:"end"` + Description *string `json:"description"` + Billable *int `json:"billable"` // Percentage (0-100) +} diff --git a/backend/internal/interfaces/http/dto/user_dto.go b/backend/internal/interfaces/http/dto/user_dto.go index 197ece1..f73cca4 100644 --- a/backend/internal/interfaces/http/dto/user_dto.go +++ b/backend/internal/interfaces/http/dto/user_dto.go @@ -1,6 +1,8 @@ package dto -import "github.com/oklog/ulid/v2" +import ( + "github.com/oklog/ulid/v2" +) type UserDto struct { ID ulid.ULID `json:"id"` @@ -10,3 +12,20 @@ type UserDto struct { CompanyID int `json:"companyId"` HourlyRate float64 `json:"hourlyRate"` } + +type UserCreateDto struct { + Username string `json:"username"` + Password string `json:"password"` // Note: In a real application, you would NEVER send the password in a DTO. This is just for demonstration. + Role string `json:"role"` + CompanyID int `json:"companyId"` + HourlyRate float64 `json:"hourlyRate"` +} + +type UserUpdateDto struct { + ID ulid.ULID `json:"id"` + Username *string `json:"username"` + Password *string `json:"password"` // Note: In a real application, you would NEVER send the password in a DTO. This is just for demonstration. + Role *string `json:"role"` + CompanyID *int `json:"companyId"` + HourlyRate *float64 `json:"hourlyRate"` +} diff --git a/backend/tygo.yml b/backend/tygo.yml index 55a63e7..a382056 100644 --- a/backend/tygo.yml +++ b/backend/tygo.yml @@ -3,4 +3,4 @@ packages: type_mappings: "time.Time": "string" "ulid.ULID": "string" - output_path: ../frontend/src/types + output_path: ../frontend/src/types/dto.ts diff --git a/frontend/src/types/activity.ts b/frontend/src/types/activity.ts new file mode 100644 index 0000000..5d5fcdc --- /dev/null +++ b/frontend/src/types/activity.ts @@ -0,0 +1,19 @@ +import { ActivityDto, ActivityCreateDto, ActivityUpdateDto } from "./dto"; + +export type Activity = ActivityDto; + +export const mapActivityDtoToActivity = (dto: ActivityDto): Activity => ({ + ...dto, +}); + +export type ActivityCreate = ActivityCreateDto; + +export const mapActivityCreateDtoToActivityCreate = (dto: ActivityCreateDto): ActivityCreate => ({ + ...dto, +}); + +export type ActivityUpdate = ActivityUpdateDto; + +export const mapActivityUpdateDtoToActivityUpdate = (dto: ActivityUpdateDto): ActivityUpdate => ({ + ...dto, +}); diff --git a/frontend/src/types/company.ts b/frontend/src/types/company.ts new file mode 100644 index 0000000..d19a311 --- /dev/null +++ b/frontend/src/types/company.ts @@ -0,0 +1,19 @@ +import { CompanyDto, CompanyCreateDto, CompanyUpdateDto } from "./dto"; + +export type Company = CompanyDto; + +export const mapCompanyDtoToCompany = (dto: CompanyDto): Company => ({ + ...dto, +}); + +export type CompanyCreate = CompanyCreateDto; + +export const mapCompanyCreateDtoToCompanyCreate = (dto: CompanyCreateDto): CompanyCreate => ({ + ...dto, +}); + +export type CompanyUpdate = CompanyUpdateDto; + +export const mapCompanyUpdateDtoToCompanyUpdate = (dto: CompanyUpdateDto): CompanyUpdate => ({ + ...dto, +}); diff --git a/frontend/src/types/customer.ts b/frontend/src/types/customer.ts new file mode 100644 index 0000000..4240c11 --- /dev/null +++ b/frontend/src/types/customer.ts @@ -0,0 +1,19 @@ +import { CustomerDto, CustomerCreateDto, CustomerUpdateDto } from "./dto"; + +export type Customer = CustomerDto; + +export const mapCustomerDtoToCustomer = (dto: CustomerDto): Customer => ({ + ...dto, +}); + +export type CustomerCreate = CustomerCreateDto; + +export const mapCustomerCreateDtoToCustomerCreate = (dto: CustomerCreateDto): CustomerCreate => ({ + ...dto, +}); + +export type CustomerUpdate = CustomerUpdateDto; + +export const mapCustomerUpdateDtoToCustomerUpdate = (dto: CustomerUpdateDto): CustomerUpdate => ({ + ...dto, +}); diff --git a/frontend/src/types/dto.ts b/frontend/src/types/dto.ts new file mode 100644 index 0000000..3a02b9e --- /dev/null +++ b/frontend/src/types/dto.ts @@ -0,0 +1,130 @@ +// Code generated by tygo. DO NOT EDIT. + +////////// +// source: activity_dto.go + +export interface ActivityDto { + id: string; + name: string; + billingRate: number /* float64 */; +} +export interface ActivityCreateDto { + name: string; + billingRate: number /* float64 */; +} +export interface ActivityUpdateDto { + id: string; + name?: string; + billingRate?: number /* float64 */; +} + +////////// +// source: company_dto.go + +export interface CompanyDto { + id: string; + name: string; +} +export interface CompanyCreateDto { + name: string; +} +export interface CompanyUpdateDto { + id: string; + name?: string; +} + +////////// +// source: customer_dto.go + +export interface CustomerDto { + id: string; + name: string; + companyId: number /* int */; +} +export interface CustomerCreateDto { + name: string; + companyId: number /* int */; +} +export interface CustomerUpdateDto { + id: string; + name?: string; + companyId?: number /* int */; +} + +////////// +// source: project_dto.go + +export interface ProjectDto { + id: string; + name: string; + customerId: number /* int */; +} +export interface ProjectCreateDto { + name: string; + customerId: number /* int */; +} +export interface ProjectUpdateDto { + id: string; + name?: string; + customerId?: number /* int */; +} + +////////// +// source: timeentry_dto.go + +export interface TimeEntryDto { + id: string; + userId: number /* int */; + projectId: number /* int */; + activityId: number /* int */; + start: string; + end: string; + description: string; + billable: number /* int */; // Percentage (0-100) +} +export interface TimeEntryCreateDto { + userId: number /* int */; + projectId: number /* int */; + activityId: number /* int */; + start: string; + end: string; + description: string; + billable: number /* int */; // Percentage (0-100) +} +export interface TimeEntryUpdateDto { + id: string; + userId?: number /* int */; + projectId?: number /* int */; + activityId?: number /* int */; + start?: string; + end?: string; + description?: string; + billable?: number /* int */; // Percentage (0-100) +} + +////////// +// source: user_dto.go + +export interface UserDto { + id: string; + username: string; + password: string; // Note: In a real application, you would NEVER send the password in a DTO. This is just for demonstration. + role: string; + companyId: number /* int */; + hourlyRate: number /* float64 */; +} +export interface UserCreateDto { + username: string; + password: string; // Note: In a real application, you would NEVER send the password in a DTO. This is just for demonstration. + role: string; + companyId: number /* int */; + hourlyRate: number /* float64 */; +} +export interface UserUpdateDto { + id: string; + username?: string; + password?: string; // Note: In a real application, you would NEVER send the password in a DTO. This is just for demonstration. + role?: string; + companyId?: number /* int */; + hourlyRate?: number /* float64 */; +} diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts deleted file mode 100644 index 82ce61e..0000000 --- a/frontend/src/types/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -// Code generated by tygo. DO NOT EDIT. - -////////// -// source: activity_dto.go - -export interface ActivityDto { - id: string; - name: string; - billingRate: number /* float64 */; -} - -////////// -// source: company_dto.go - -export interface CompanyDto { - id: string; - name: string; -} - -////////// -// source: customer_dto.go - -export interface CustomerDto { - id: string; - name: string; - companyId: number /* int */; -} - -////////// -// source: project_dto.go - -export interface ProjectDto { - id: string; - name: string; - customerId: number /* int */; -} - -////////// -// source: timeentry_dto.go - -export interface TimeEntryDto { - id: string; - userId: number /* int */; - projectId: number /* int */; - activityId: number /* int */; - start: string; - end: string; - description: string; - billable: number /* int */; // Percentage (0-100) -} - -////////// -// source: user_dto.go - -export interface UserDto { - id: string; - username: string; - password: string; // Note: In a real application, you would NEVER send the password in a DTO. This is just for demonstration. - role: string; - companyId: number /* int */; - hourlyRate: number /* float64 */; -} diff --git a/frontend/src/types/project.ts b/frontend/src/types/project.ts new file mode 100644 index 0000000..ba052a4 --- /dev/null +++ b/frontend/src/types/project.ts @@ -0,0 +1,19 @@ +import { ProjectDto, ProjectCreateDto, ProjectUpdateDto } from "./dto"; + +export type Project = ProjectDto; + +export const mapProjectDtoToProject = (dto: ProjectDto): Project => ({ + ...dto, +}); + +export type ProjectCreate = ProjectCreateDto; + +export const mapProjectCreateDtoToProjectCreate = (dto: ProjectCreateDto): ProjectCreate => ({ + ...dto, +}); + +export type ProjectUpdate = ProjectUpdateDto; + +export const mapProjectUpdateDtoToProjectUpdate = (dto: ProjectUpdateDto): ProjectUpdate => ({ + ...dto, +}); diff --git a/frontend/src/types/timeentry.ts b/frontend/src/types/timeentry.ts new file mode 100644 index 0000000..4f5a31d --- /dev/null +++ b/frontend/src/types/timeentry.ts @@ -0,0 +1,34 @@ +import { TimeEntryDto, TimeEntryCreateDto, TimeEntryUpdateDto } from "./dto"; + +export type TimeEntry = Omit & { + start: Date; + end: Date; +}; + +export const mapTimeEntryDtoToTimeEntry = (dto: TimeEntryDto): TimeEntry => ({ + ...dto, + start: new Date(dto.start), + end: new Date(dto.end), +}); + +export type TimeEntryCreate = Omit & { + start: Date; + end: Date; +}; + +export const mapTimeEntryCreateDtoToTimeEntryCreate = (dto: TimeEntryCreateDto): TimeEntryCreate => ({ + ...dto, + start: new Date(dto.start), + end: new Date(dto.end), +}); + +export type TimeEntryUpdate = Omit & { + start?: Date; + end?: Date; +}; + +export const mapTimeEntryUpdateDtoToTimeEntryUpdate = (dto: TimeEntryUpdateDto): TimeEntryUpdate => ({ + ...dto, + start: dto.start ? new Date(dto.start) : undefined, + end: dto.end ? new Date(dto.end) : undefined, +}); diff --git a/frontend/src/types/user.ts b/frontend/src/types/user.ts new file mode 100644 index 0000000..8c42263 --- /dev/null +++ b/frontend/src/types/user.ts @@ -0,0 +1,19 @@ +import { UserDto, UserCreateDto, UserUpdateDto } from "./dto"; + +export type User = Omit; + +export const mapUserDtoToUser = (dto: UserDto): User => ({ + ...dto, +}); + +export type UserCreate = Omit; + +export const mapUserCreateDtoToUserCreate = (dto: UserCreateDto): UserCreate => ({ + ...dto, +}); + +export type UserUpdate = Omit; + +export const mapUserUpdateDtoToUserUpdate = (dto: UserUpdateDto): UserUpdate => ({ + ...dto, +});