Files
fm_be/internal/transport/http/dto/user_dto.go
2026-07-16 22:16:45 +07:00

104 lines
3.5 KiB
Go

package dto
import (
"bytes"
"encoding/json"
)
// JSON:API User DTOs
type UserResource struct {
Type string `json:"type" example:"user"`
ID string `json:"id" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
Attributes UserAttributes `json:"attributes"`
}
type UserListResponse struct {
Data []UserResource `json:"data"`
Meta struct {
PageNumber int `json:"page_number" example:"1"`
PageSize int `json:"page_size" example:"20"`
Total int64 `json:"total" example:"120"`
} `json:"meta"`
}
type UserDataTableResponse struct {
Data []UserResource `json:"data"`
Meta struct {
Draw int `json:"draw" example:"1"`
RecordsTotal int64 `json:"records_total" example:"120"`
RecordsFiltered int64 `json:"records_filtered" example:"12"`
} `json:"meta"`
}
// Create
type UserCreateAttributes struct {
Email string `json:"email" validate:"required,email" example:"user@example.com"`
Username string `json:"username" validate:"required,min=3,max=100" example:"john.doe"`
FirstName string `json:"first_name" validate:"required" example:"John"`
LastName string `json:"last_name" validate:"required" example:"Doe"`
MobilePhone string `json:"mobile_phone,omitempty" example:"+628123456789"`
Timezone *string `json:"timezone,omitempty" example:"Asia/Jakarta"`
ImageUUID *string `json:"image_uuid,omitempty" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e90"`
RoleID string `json:"role_id" validate:"required" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
RoleIDs []string `json:"role_ids,omitempty" example:"[\"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d\",\"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9e\"]"`
}
type UserCreateData struct {
Type string `json:"type" validate:"required,oneof=user_create user" example:"user_create"`
Attributes UserCreateAttributes `json:"attributes" validate:"required"`
}
type UserCreateRequest struct {
Data UserCreateData `json:"data" validate:"required"`
}
// Update
type UserUpdateAttributes struct {
Email *string `json:"email,omitempty" validate:"omitempty,email" example:"user@example.com"`
FirstName *string `json:"first_name,omitempty" example:"John"`
LastName *string `json:"last_name,omitempty" example:"Doe"`
MobilePhone *string `json:"mobile_phone,omitempty" example:"+628123456789"`
Timezone *string `json:"timezone,omitempty" example:"Asia/Jakarta"`
ImageUUID NullString `json:"image_uuid,omitempty" swaggertype:"string" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e90"`
}
// NullString allows PATCH semantics:
// - field omitted => Set=false (no change)
// - value null => Set=true, Valid=false (clear value)
// - value string => Set=true, Valid=true, Value=<string>
type NullString struct {
Set bool
Valid bool
Value string
}
func (n *NullString) UnmarshalJSON(data []byte) error {
n.Set = true
trimmed := bytes.TrimSpace(data)
if bytes.Equal(trimmed, []byte("null")) {
n.Valid = false
n.Value = ""
return nil
}
var v string
if err := json.Unmarshal(trimmed, &v); err != nil {
return err
}
n.Valid = true
n.Value = v
return nil
}
type UserUpdateData struct {
Type string `json:"type" validate:"required,oneof=user_update user" example:"user_update"`
ID string `json:"id" example:"018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"`
Attributes UserUpdateAttributes `json:"attributes" validate:"required"`
}
type UserUpdateRequest struct {
Data UserUpdateData `json:"data" validate:"required"`
}