feat: custom content type icons, built-in types, user lookup

This commit is contained in:
Florian Sylvain committed 2026-10-19 18:22:55 +02:00
1 parent e6e088c963
commit 73a75d5cb9
31 files changed
+1611 -36

No files matched your search

+37 -8
View File
@@ -26,15 +26,35 @@ func NewHandler(create *useCases.CreateContentTypeUseCase, list *useCases.ListCo
return &Handler{CreateUseCase: create, ListUseCase: list, GetUseCase: get, UpdateUseCase: update, DeleteUseCase: deleteUseCase}
}
type iconInput struct {
value *string
invalid bool
}
func (i *iconInput) UnmarshalJSON(data []byte) error {
if string(data) == "null" {
return nil
}
var text string
if err := json.Unmarshal(data, &text); err != nil {
i.invalid = true
return nil
}
i.value = &text
return nil
}
type PostContentType struct {
Key string `json:"key" validate:"required"`
Name string `json:"name" validate:"required,max=100"`
Icon iconInput `json:"icon"`
Fields []domain.Field `json:"fields"`
}
type PutContentType struct {
Key string `json:"key"`
Name string `json:"name" validate:"required,max=100"`
Icon iconInput `json:"icon"`
Fields []domain.Field `json:"fields"`
}
@@ -42,23 +62,22 @@ type contentTypeResponse struct {
ID uint32 `json:"id"`
Key string `json:"key"`
Name string `json:"name"`
Icon *string `json:"icon"`
Fields []domain.Field `json:"fields"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func toResponse(contentType domain.ContentType) contentTypeResponse {
fields := make([]domain.Field, 0, len(contentType.Fields))
for _, field := range contentType.Fields {
if field.Options == nil {
field.Options = []string{}
}
fields = append(fields, field)
fields := contentType.Fields
if fields == nil {
fields = []domain.Field{}
}
return contentTypeResponse{
ID: contentType.ID,
Key: contentType.Key,
Name: contentType.Name,
Icon: contentType.Icon,
Fields: fields,
CreatedAt: contentType.CreatedAt,
UpdatedAt: contentType.UpdatedAt,
@@ -77,6 +96,8 @@ func writeContentTypeError(w http.ResponseWriter, err error) {
http.Error(w, apperr.SchemaIncompatibleErrorMessage, http.StatusConflict)
case errors.Is(err, domain.ErrInvalidName):
http.Error(w, apperr.BodyErrorMessage, http.StatusBadRequest)
case errors.Is(err, domain.ErrInvalidIcon):
http.Error(w, apperr.InvalidIconErrorMessage, http.StatusBadRequest)
case errors.Is(err, domain.ErrInvalidKey):
http.Error(w, apperr.InvalidContentTypeKeyErrorMessage, http.StatusBadRequest)
case errors.Is(err, domain.ErrInvalidField):
@@ -118,7 +139,11 @@ func (h *Handler) Create(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
created, err := h.CreateUseCase.Create(useCases.CreateContentTypeCommand{Key: request.Key, Name: request.Name, Fields: request.Fields})
if request.Icon.invalid {
writeContentTypeError(w, domain.ErrInvalidIcon)
return
}
created, err := h.CreateUseCase.Create(useCases.CreateContentTypeCommand{Key: request.Key, Name: request.Name, Icon: request.Icon.value, Fields: request.Fields})
if err != nil {
writeContentTypeError(w, err)
return
@@ -136,7 +161,11 @@ func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
updated, err := h.UpdateUseCase.Update(useCases.UpdateContentTypeCommand{Key: chi.URLParam(r, "key"), Name: request.Name, Fields: request.Fields})
if request.Icon.invalid {
writeContentTypeError(w, domain.ErrInvalidIcon)
return
}
updated, err := h.UpdateUseCase.Update(useCases.UpdateContentTypeCommand{Key: chi.URLParam(r, "key"), Name: request.Name, Icon: request.Icon.value, Fields: request.Fields})
if err != nil {
writeContentTypeError(w, err)
return