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:
189
internal/dto/responses/residence.go
Normal file
189
internal/dto/responses/residence.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package responses
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
|
||||
"github.com/treytartt/mycrib-api/internal/models"
|
||||
)
|
||||
|
||||
// ResidenceTypeResponse represents a residence type in the API response
|
||||
type ResidenceTypeResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// ResidenceUserResponse represents a user with access to a residence
|
||||
type ResidenceUserResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
}
|
||||
|
||||
// ResidenceResponse represents a residence in the API response
|
||||
type ResidenceResponse struct {
|
||||
ID uint `json:"id"`
|
||||
OwnerID uint `json:"owner_id"`
|
||||
Owner *ResidenceUserResponse `json:"owner,omitempty"`
|
||||
Users []ResidenceUserResponse `json:"users,omitempty"`
|
||||
Name string `json:"name"`
|
||||
PropertyTypeID *uint `json:"property_type_id"`
|
||||
PropertyType *ResidenceTypeResponse `json:"property_type,omitempty"`
|
||||
StreetAddress string `json:"street_address"`
|
||||
ApartmentUnit string `json:"apartment_unit"`
|
||||
City string `json:"city"`
|
||||
StateProvince string `json:"state_province"`
|
||||
PostalCode string `json:"postal_code"`
|
||||
Country string `json:"country"`
|
||||
Bedrooms *int `json:"bedrooms"`
|
||||
Bathrooms *decimal.Decimal `json:"bathrooms"`
|
||||
SquareFootage *int `json:"square_footage"`
|
||||
LotSize *decimal.Decimal `json:"lot_size"`
|
||||
YearBuilt *int `json:"year_built"`
|
||||
Description string `json:"description"`
|
||||
PurchaseDate *time.Time `json:"purchase_date"`
|
||||
PurchasePrice *decimal.Decimal `json:"purchase_price"`
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
IsActive bool `json:"is_active"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ResidenceListResponse represents the paginated list of residences
|
||||
type ResidenceListResponse struct {
|
||||
Count int `json:"count"`
|
||||
Next *string `json:"next"`
|
||||
Previous *string `json:"previous"`
|
||||
Results []ResidenceResponse `json:"results"`
|
||||
}
|
||||
|
||||
// ShareCodeResponse represents a share code in the API response
|
||||
type ShareCodeResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Code string `json:"code"`
|
||||
ResidenceID uint `json:"residence_id"`
|
||||
CreatedByID uint `json:"created_by_id"`
|
||||
IsActive bool `json:"is_active"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// JoinResidenceResponse represents the response after joining a residence
|
||||
type JoinResidenceResponse struct {
|
||||
Message string `json:"message"`
|
||||
Residence ResidenceResponse `json:"residence"`
|
||||
}
|
||||
|
||||
// GenerateShareCodeResponse represents the response after generating a share code
|
||||
type GenerateShareCodeResponse struct {
|
||||
Message string `json:"message"`
|
||||
ShareCode ShareCodeResponse `json:"share_code"`
|
||||
}
|
||||
|
||||
// === Factory Functions ===
|
||||
|
||||
// NewResidenceUserResponse creates a ResidenceUserResponse from a User model
|
||||
func NewResidenceUserResponse(user *models.User) *ResidenceUserResponse {
|
||||
if user == nil {
|
||||
return nil
|
||||
}
|
||||
return &ResidenceUserResponse{
|
||||
ID: user.ID,
|
||||
Username: user.Username,
|
||||
Email: user.Email,
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
}
|
||||
}
|
||||
|
||||
// NewResidenceTypeResponse creates a ResidenceTypeResponse from a ResidenceType model
|
||||
func NewResidenceTypeResponse(rt *models.ResidenceType) *ResidenceTypeResponse {
|
||||
if rt == nil {
|
||||
return nil
|
||||
}
|
||||
return &ResidenceTypeResponse{
|
||||
ID: rt.ID,
|
||||
Name: rt.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// NewResidenceResponse creates a ResidenceResponse from a Residence model
|
||||
func NewResidenceResponse(residence *models.Residence) ResidenceResponse {
|
||||
resp := ResidenceResponse{
|
||||
ID: residence.ID,
|
||||
OwnerID: residence.OwnerID,
|
||||
Name: residence.Name,
|
||||
PropertyTypeID: residence.PropertyTypeID,
|
||||
StreetAddress: residence.StreetAddress,
|
||||
ApartmentUnit: residence.ApartmentUnit,
|
||||
City: residence.City,
|
||||
StateProvince: residence.StateProvince,
|
||||
PostalCode: residence.PostalCode,
|
||||
Country: residence.Country,
|
||||
Bedrooms: residence.Bedrooms,
|
||||
Bathrooms: residence.Bathrooms,
|
||||
SquareFootage: residence.SquareFootage,
|
||||
LotSize: residence.LotSize,
|
||||
YearBuilt: residence.YearBuilt,
|
||||
Description: residence.Description,
|
||||
PurchaseDate: residence.PurchaseDate,
|
||||
PurchasePrice: residence.PurchasePrice,
|
||||
IsPrimary: residence.IsPrimary,
|
||||
IsActive: residence.IsActive,
|
||||
CreatedAt: residence.CreatedAt,
|
||||
UpdatedAt: residence.UpdatedAt,
|
||||
}
|
||||
|
||||
// Include owner if loaded
|
||||
if residence.Owner.ID != 0 {
|
||||
resp.Owner = NewResidenceUserResponse(&residence.Owner)
|
||||
}
|
||||
|
||||
// Include property type if loaded
|
||||
if residence.PropertyType != nil {
|
||||
resp.PropertyType = NewResidenceTypeResponse(residence.PropertyType)
|
||||
}
|
||||
|
||||
// Include shared users if loaded
|
||||
if len(residence.Users) > 0 {
|
||||
resp.Users = make([]ResidenceUserResponse, len(residence.Users))
|
||||
for i, user := range residence.Users {
|
||||
resp.Users[i] = *NewResidenceUserResponse(&user)
|
||||
}
|
||||
} else {
|
||||
resp.Users = []ResidenceUserResponse{}
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// NewResidenceListResponse creates a paginated list response
|
||||
func NewResidenceListResponse(residences []models.Residence) ResidenceListResponse {
|
||||
results := make([]ResidenceResponse, len(residences))
|
||||
for i, r := range residences {
|
||||
results[i] = NewResidenceResponse(&r)
|
||||
}
|
||||
|
||||
return ResidenceListResponse{
|
||||
Count: len(residences),
|
||||
Next: nil, // Pagination not implemented yet
|
||||
Previous: nil,
|
||||
Results: results,
|
||||
}
|
||||
}
|
||||
|
||||
// NewShareCodeResponse creates a ShareCodeResponse from a ResidenceShareCode model
|
||||
func NewShareCodeResponse(sc *models.ResidenceShareCode) ShareCodeResponse {
|
||||
return ShareCodeResponse{
|
||||
ID: sc.ID,
|
||||
Code: sc.Code,
|
||||
ResidenceID: sc.ResidenceID,
|
||||
CreatedByID: sc.CreatedByID,
|
||||
IsActive: sc.IsActive,
|
||||
ExpiresAt: sc.ExpiresAt,
|
||||
CreatedAt: sc.CreatedAt,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user