@@ -3,6 +3,7 @@ package labels
33import (
44 "context"
55 "net/http"
6+ "strings"
67
78 "dkhalife.com/tasks/core/internal/models"
89 repos "dkhalife.com/tasks/core/internal/repos/label"
@@ -49,13 +50,34 @@ func (s *LabelService) GetUserLabels(ctx context.Context, userID int) (int, inte
4950func (s * LabelService ) CreateLabel (ctx context.Context , userId int , req models.CreateLabelReq ) (int , interface {}) {
5051 log := logging .FromContext (ctx )
5152
53+ exists , err := s .r .LabelExistsByName (ctx , userId , req .Name , 0 )
54+ if err != nil {
55+ log .Errorf ("Failed to check label existence: %s" , err .Error ())
56+ telemetry .TrackError (ctx , "label_check_failed" , "label-service" , err , nil )
57+ return http .StatusInternalServerError , gin.H {
58+ "error" : "Failed to create label" ,
59+ }
60+ }
61+
62+ if exists {
63+ return http .StatusConflict , gin.H {
64+ "error" : "A label with this name already exists" ,
65+ }
66+ }
67+
5268 label := & models.Label {
5369 Name : req .Name ,
5470 Color : req .Color ,
5571 CreatedBy : userId ,
5672 }
5773
5874 if err := s .r .CreateLabels (ctx , []* models.Label {label }); err != nil {
75+ if isDuplicateKeyError (err ) {
76+ return http .StatusConflict , gin.H {
77+ "error" : "A label with this name already exists" ,
78+ }
79+ }
80+
5981 log .Errorf ("Failed to create label: %s" , err .Error ())
6082 telemetry .TrackError (ctx , "label_create_failed" , "label-service" , err , nil )
6183 return http .StatusInternalServerError , gin.H {
@@ -76,7 +98,9 @@ func (s *LabelService) CreateLabel(ctx context.Context, userId int, req models.C
7698 Data : newLabel ,
7799 })
78100
79- return http .StatusCreated , newLabel
101+ return http .StatusCreated , gin.H {
102+ "label" : label .ID ,
103+ }
80104}
81105
82106func (s * LabelService ) UpdateLabel (ctx context.Context , userId int , req models.UpdateLabelReq ) (int , interface {}) {
@@ -95,7 +119,28 @@ func (s *LabelService) UpdateLabel(ctx context.Context, userId int, req models.U
95119 }
96120 }
97121
122+ exists , err := s .r .LabelExistsByName (ctx , userId , req .Name , req .ID )
123+ if err != nil {
124+ log .Errorf ("Failed to check label existence: %s" , err .Error ())
125+ telemetry .TrackError (ctx , "label_check_failed" , "label-service" , err , nil )
126+ return http .StatusInternalServerError , gin.H {
127+ "error" : "Error updating label" ,
128+ }
129+ }
130+
131+ if exists {
132+ return http .StatusConflict , gin.H {
133+ "error" : "A label with this name already exists" ,
134+ }
135+ }
136+
98137 if err := s .r .UpdateLabel (ctx , userId , label ); err != nil {
138+ if isDuplicateKeyError (err ) {
139+ return http .StatusConflict , gin.H {
140+ "error" : "A label with this name already exists" ,
141+ }
142+ }
143+
99144 log .Errorf ("Failed to update label: %s" , err .Error ())
100145 telemetry .TrackError (ctx , "label_update_failed" , "label-service" , err , nil )
101146 return http .StatusInternalServerError , gin.H {
@@ -137,3 +182,12 @@ func (s *LabelService) DeleteLabel(ctx context.Context, userID int, labelID int)
137182 })
138183 return http .StatusNoContent , nil
139184}
185+
186+ func isDuplicateKeyError (err error ) bool {
187+ msg := err .Error ()
188+ // SQLite: "UNIQUE constraint failed: ..."
189+ // MySQL: "Error 1062 (23000): Duplicate entry ..."
190+ return strings .Contains (msg , "UNIQUE constraint failed" ) ||
191+ strings .Contains (msg , "Duplicate entry" ) ||
192+ strings .Contains (msg , "Error 1062" )
193+ }
0 commit comments