gohorsejobs/backend/internal/dto/requests.go
Tiago Yamamoto cca951ca23 feat: add currency, salary period, and rich text description
Frontend:
- Added currency selector (BRL, USD, EUR, JPY, GBP, CNY, AED, CAD, AUD, CHF)
- Added salary period dropdown (hourly, daily, weekly, monthly, yearly)
- Created RichTextEditor component for job descriptions (Bold, Lists, Alignment)
- Updated confirmation step to display currency symbol and period label

Backend:
- JobService now persists currency in job creation
- Extended currency validation in DTOs

Seeder:
- Already includes currency in job insertion
2025-12-26 15:37:54 -03:00

162 lines
8.2 KiB
Go
Executable file

package dto
// CreateJobRequest represents the request to create a new job
type CreateJobRequest struct {
CompanyID string `json:"companyId" validate:"required"`
Title string `json:"title" validate:"required,min=5,max=255"`
Description string `json:"description" validate:"required,min=20"`
SalaryMin *float64 `json:"salaryMin,omitempty"`
SalaryMax *float64 `json:"salaryMax,omitempty"`
SalaryType *string `json:"salaryType,omitempty" validate:"omitempty,oneof=hourly daily weekly monthly yearly"`
Currency *string `json:"currency,omitempty" validate:"omitempty,oneof=BRL USD EUR GBP JPY CNY AED CAD AUD CHF"`
SalaryNegotiable bool `json:"salaryNegotiable"`
EmploymentType *string `json:"employmentType,omitempty" validate:"omitempty,oneof=full-time part-time dispatch contract temporary training voluntary permanent"`
WorkingHours *string `json:"workingHours,omitempty"`
Location *string `json:"location,omitempty"`
RegionID *int `json:"regionId,omitempty"`
CityID *int `json:"cityId,omitempty"`
Requirements map[string]interface{} `json:"requirements,omitempty"`
Benefits map[string]interface{} `json:"benefits,omitempty"`
VisaSupport bool `json:"visaSupport"`
LanguageLevel *string `json:"languageLevel,omitempty"`
Status string `json:"status" validate:"oneof=draft open closed review published paused expired archived reported"`
}
// UpdateJobRequest represents the request to update a job
type UpdateJobRequest struct {
Title *string `json:"title,omitempty" validate:"omitempty,min=5,max=255"`
Description *string `json:"description,omitempty" validate:"omitempty,min=20"`
SalaryMin *float64 `json:"salaryMin,omitempty"`
SalaryMax *float64 `json:"salaryMax,omitempty"`
SalaryType *string `json:"salaryType,omitempty" validate:"omitempty,oneof=hourly daily weekly monthly yearly"`
Currency *string `json:"currency,omitempty" validate:"omitempty,oneof=BRL USD EUR GBP JPY CNY AED CAD AUD CHF"`
SalaryNegotiable *bool `json:"salaryNegotiable,omitempty"`
EmploymentType *string `json:"employmentType,omitempty" validate:"omitempty,oneof=full-time part-time dispatch contract temporary training voluntary permanent"`
WorkingHours *string `json:"workingHours,omitempty"`
Location *string `json:"location,omitempty"`
RegionID *int `json:"regionId,omitempty"`
CityID *int `json:"cityId,omitempty"`
Requirements map[string]interface{} `json:"requirements,omitempty"`
Benefits map[string]interface{} `json:"benefits,omitempty"`
VisaSupport *bool `json:"visaSupport,omitempty"`
LanguageLevel *string `json:"languageLevel,omitempty"`
Status *string `json:"status,omitempty" validate:"omitempty,oneof=draft open closed review published paused expired archived reported"`
}
// CreateApplicationRequest represents a job application (guest or logged user)
type CreateApplicationRequest struct {
JobID string `json:"jobId" validate:"required"`
UserID *string `json:"userId,omitempty"`
Name *string `json:"name,omitempty"`
Phone *string `json:"phone,omitempty"`
LineID *string `json:"lineId,omitempty"`
WhatsApp *string `json:"whatsapp,omitempty"`
Email *string `json:"email,omitempty"`
Message *string `json:"message,omitempty"`
ResumeURL *string `json:"resumeUrl,omitempty"`
Documents map[string]interface{} `json:"documents,omitempty"`
}
// UpdateApplicationStatusRequest represents updating application status (recruiter only)
type UpdateApplicationStatusRequest struct {
Status string `json:"status" validate:"required,oneof=pending reviewed shortlisted rejected hired"`
Notes *string `json:"notes,omitempty"`
}
// CreateCompanyRequest represents creating a new company
type CreateCompanyRequest struct {
Name string `json:"name" validate:"required,min=3,max=255"`
Slug string `json:"slug" validate:"required,min=3,max=255"`
Type *string `json:"type,omitempty"`
Document *string `json:"document,omitempty"`
Address *string `json:"address,omitempty"`
RegionID *int `json:"regionId,omitempty"`
CityID *int `json:"cityId,omitempty"`
Phone *string `json:"phone,omitempty"`
Email *string `json:"email,omitempty"`
Website *string `json:"website,omitempty"`
LogoURL *string `json:"logoUrl,omitempty"`
Description *string `json:"description,omitempty"`
}
// UpdateCompanyRequest represents updating company information
type UpdateCompanyRequest struct {
Name *string `json:"name,omitempty" validate:"omitempty,min=3,max=255"`
Slug *string `json:"slug,omitempty" validate:"omitempty,min=3,max=255"`
Type *string `json:"type,omitempty"`
Document *string `json:"document,omitempty"`
Address *string `json:"address,omitempty"`
RegionID *int `json:"regionId,omitempty"`
CityID *int `json:"cityId,omitempty"`
Phone *string `json:"phone,omitempty"`
Email *string `json:"email,omitempty"`
Website *string `json:"website,omitempty"`
LogoURL *string `json:"logoUrl,omitempty"`
Description *string `json:"description,omitempty"`
Active *bool `json:"active,omitempty"`
Verified *bool `json:"verified,omitempty"`
}
// AssignUserToCompanyRequest represents assigning a user to a company
type AssignUserToCompanyRequest struct {
UserID string `json:"userId" validate:"required"`
CompanyID string `json:"companyId" validate:"required"`
Role string `json:"role" validate:"required,oneof=admin recruiter"`
Permissions map[string]interface{} `json:"permissions,omitempty"`
}
// PaginationQuery represents pagination parameters
type PaginationQuery struct {
Page int `form:"page" validate:"min=1"`
Limit int `form:"limit" validate:"min=1,max=100"`
}
// JobFilterQuery represents job filtering parameters
type JobFilterQuery struct {
PaginationQuery
CompanyID *string `form:"companyId"`
RegionID *int `form:"regionId"`
CityID *int `form:"cityId"`
EmploymentType *string `form:"employmentType"`
WorkMode *string `form:"workMode"` // "remote", "hybrid", "onsite"
Location *string `form:"location"` // Partial match
Status *string `form:"status"`
IsFeatured *bool `form:"isFeatured"` // Filter by featured status
VisaSupport *bool `form:"visaSupport"`
LanguageLevel *string `form:"languageLevel"`
Search *string `form:"search"` // Covers title, description, company name
// Advanced filters
SalaryMin *float64 `form:"salaryMin"` // Minimum salary filter
SalaryMax *float64 `form:"salaryMax"` // Maximum salary filter
Currency *string `form:"currency"` // BRL, USD, EUR, GBP, JPY
SortBy *string `form:"sortBy"` // recent, salary_asc, salary_desc, relevance
}
// PaginatedResponse represents a paginated API response
type PaginatedResponse struct {
Data interface{} `json:"data"`
Pagination Pagination `json:"pagination"`
}
// Pagination represents pagination metadata
type Pagination struct {
Page int `json:"page"`
Limit int `json:"limit"`
Total int `json:"total"`
}
// APIResponse represents a standard API response
// APIResponse represents a standard API response
type APIResponse struct {
Success bool `json:"success"`
Data interface{} `json:"data,omitempty"`
Error *string `json:"error,omitempty"`
Message *string `json:"message,omitempty"`
}
// SaveFCMTokenRequest represents the request to save an FCM token
type SaveFCMTokenRequest struct {
Token string `json:"token" validate:"required"`
Platform string `json:"platform" validate:"required,oneof=web android ios"`
}