Initial commit: MyCrib API in Go
Complete rewrite of Django REST API to Go with: - Gin web framework for HTTP routing - GORM for database operations - GoAdmin for admin panel - Gorush integration for push notifications - Redis for caching and job queues Features implemented: - User authentication (login, register, logout, password reset) - Residence management (CRUD, sharing, share codes) - Task management (CRUD, kanban board, completions) - Contractor management (CRUD, specialties) - Document management (CRUD, warranties) - Notifications (preferences, push notifications) - Subscription management (tiers, limits) Infrastructure: - Docker Compose for local development - Database migrations and seed data - Admin panel for data management 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
139
internal/dto/responses/contractor.go
Normal file
139
internal/dto/responses/contractor.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package responses
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/treytartt/mycrib-api/internal/models"
|
||||
)
|
||||
|
||||
// ContractorSpecialtyResponse represents a contractor specialty
|
||||
type ContractorSpecialtyResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Icon string `json:"icon"`
|
||||
DisplayOrder int `json:"display_order"`
|
||||
}
|
||||
|
||||
// ContractorUserResponse represents a user in contractor context
|
||||
type ContractorUserResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Username string `json:"username"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
}
|
||||
|
||||
// ContractorResponse represents a contractor in the API response
|
||||
type ContractorResponse struct {
|
||||
ID uint `json:"id"`
|
||||
ResidenceID uint `json:"residence_id"`
|
||||
CreatedByID uint `json:"created_by_id"`
|
||||
CreatedBy *ContractorUserResponse `json:"created_by,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Company string `json:"company"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
Website string `json:"website"`
|
||||
Notes string `json:"notes"`
|
||||
StreetAddress string `json:"street_address"`
|
||||
City string `json:"city"`
|
||||
StateProvince string `json:"state_province"`
|
||||
PostalCode string `json:"postal_code"`
|
||||
Specialties []ContractorSpecialtyResponse `json:"specialties"`
|
||||
Rating *float64 `json:"rating"`
|
||||
IsFavorite bool `json:"is_favorite"`
|
||||
IsActive bool `json:"is_active"`
|
||||
TaskCount int `json:"task_count,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ContractorListResponse represents a paginated list of contractors
|
||||
type ContractorListResponse struct {
|
||||
Count int `json:"count"`
|
||||
Next *string `json:"next"`
|
||||
Previous *string `json:"previous"`
|
||||
Results []ContractorResponse `json:"results"`
|
||||
}
|
||||
|
||||
// ToggleFavoriteResponse represents the response after toggling favorite
|
||||
type ToggleFavoriteResponse struct {
|
||||
Message string `json:"message"`
|
||||
IsFavorite bool `json:"is_favorite"`
|
||||
}
|
||||
|
||||
// === Factory Functions ===
|
||||
|
||||
// NewContractorSpecialtyResponse creates a ContractorSpecialtyResponse from a model
|
||||
func NewContractorSpecialtyResponse(s *models.ContractorSpecialty) ContractorSpecialtyResponse {
|
||||
return ContractorSpecialtyResponse{
|
||||
ID: s.ID,
|
||||
Name: s.Name,
|
||||
Description: s.Description,
|
||||
Icon: s.Icon,
|
||||
DisplayOrder: s.DisplayOrder,
|
||||
}
|
||||
}
|
||||
|
||||
// NewContractorUserResponse creates a ContractorUserResponse from a User model
|
||||
func NewContractorUserResponse(u *models.User) *ContractorUserResponse {
|
||||
if u == nil {
|
||||
return nil
|
||||
}
|
||||
return &ContractorUserResponse{
|
||||
ID: u.ID,
|
||||
Username: u.Username,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
}
|
||||
}
|
||||
|
||||
// NewContractorResponse creates a ContractorResponse from a Contractor model
|
||||
func NewContractorResponse(c *models.Contractor) ContractorResponse {
|
||||
resp := ContractorResponse{
|
||||
ID: c.ID,
|
||||
ResidenceID: c.ResidenceID,
|
||||
CreatedByID: c.CreatedByID,
|
||||
Name: c.Name,
|
||||
Company: c.Company,
|
||||
Phone: c.Phone,
|
||||
Email: c.Email,
|
||||
Website: c.Website,
|
||||
Notes: c.Notes,
|
||||
StreetAddress: c.StreetAddress,
|
||||
City: c.City,
|
||||
StateProvince: c.StateProvince,
|
||||
PostalCode: c.PostalCode,
|
||||
Rating: c.Rating,
|
||||
IsFavorite: c.IsFavorite,
|
||||
IsActive: c.IsActive,
|
||||
TaskCount: len(c.Tasks),
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
}
|
||||
|
||||
if c.CreatedBy.ID != 0 {
|
||||
resp.CreatedBy = NewContractorUserResponse(&c.CreatedBy)
|
||||
}
|
||||
|
||||
resp.Specialties = make([]ContractorSpecialtyResponse, len(c.Specialties))
|
||||
for i, s := range c.Specialties {
|
||||
resp.Specialties[i] = NewContractorSpecialtyResponse(&s)
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// NewContractorListResponse creates a ContractorListResponse from a slice of contractors
|
||||
func NewContractorListResponse(contractors []models.Contractor) ContractorListResponse {
|
||||
results := make([]ContractorResponse, len(contractors))
|
||||
for i, c := range contractors {
|
||||
results[i] = NewContractorResponse(&c)
|
||||
}
|
||||
return ContractorListResponse{
|
||||
Count: len(contractors),
|
||||
Next: nil,
|
||||
Previous: nil,
|
||||
Results: results,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user