@@ -34,12 +34,16 @@ type Complex struct {
3434 Category string `json:"category" gorm:"not null" validate:"required"`
3535 CreatedAt time.Time `json:"created_at"`
3636 UpdatedAt time.Time `json:"updated_at"`
37+ Goals []Goal `json:"goals,omitempty"`
3738}
3839
3940// ComplexInput defines the expected input for creating a new complex.
4041type ComplexInput struct {
41- Content string `json:"content" validate:"required,min=1,max=255"`
42- Category string `json:"category" validate:"required,min=1,max=100"`
42+ Content string `json:"content" validate:"required,min=1,max=255"`
43+ Category string `json:"category" validate:"required,min=1,max=100"`
44+ SurfaceGoal string `json:"surface_goal,omitempty" validate:"omitempty,min=1,max=255"` // Optional: Goal to be created with complex
45+ UnderlyingGoal string `json:"underlying_goal,omitempty" validate:"omitempty,min=1,max=255"` // Optional: Goal to be created with complex
46+ InitialActions []ActionInput `json:"initial_actions,omitempty" validate:"omitempty,dive"` // Optional: Actions for the new goal
4347}
4448
4549// Goal represents the goal entity.
@@ -136,18 +140,57 @@ func CreateComplexHandler(c *gin.Context) {
136140 return
137141 }
138142
143+ // Start a database transaction
144+ tx := db .Begin ()
145+ if tx .Error != nil {
146+ c .JSON (http .StatusInternalServerError , NewErrorResponse (http .StatusInternalServerError , "Failed to start transaction: " + tx .Error .Error ()))
147+ return
148+ }
149+
150+ // Create Complex
139151 complex := Complex {
140152 UserID : userID .(string ),
141153 Content : input .Content ,
142154 Category : input .Category ,
143155 }
144156
145- if result := db .Create (& complex ); result .Error != nil {
157+ if result := tx .Create (& complex ); result .Error != nil {
158+ tx .Rollback ()
146159 c .JSON (http .StatusInternalServerError , NewErrorResponse (http .StatusInternalServerError , "Failed to create complex: " + result .Error .Error ()))
147160 return
148161 }
149162
150- c .JSON (http .StatusCreated , complex )
163+ // If goal fields are provided, create a goal associated with this complex
164+ if input .SurfaceGoal != "" && input .UnderlyingGoal != "" {
165+ goal := Goal {
166+ UserID : userID .(string ),
167+ ComplexID : complex .ID , // Link to the newly created complex
168+ SurfaceGoal : input .SurfaceGoal ,
169+ UnderlyingGoal : input .UnderlyingGoal ,
170+ }
171+ if result := tx .Create (& goal ); result .Error != nil {
172+ tx .Rollback ()
173+ c .JSON (http .StatusInternalServerError , NewErrorResponse (http .StatusInternalServerError , "Failed to create associated goal: " + result .Error .Error ()))
174+ return
175+ }
176+ } else if input .SurfaceGoal != "" || input .UnderlyingGoal != "" {
177+ // If only one of the goal fields is provided, it's an invalid request for creating a goal
178+ tx .Rollback ()
179+ c .JSON (http .StatusBadRequest , NewErrorResponse (http .StatusBadRequest , "Both surface_goal and underlying_goal are required to create a goal" ))
180+ return
181+ }
182+
183+ // Commit the transaction
184+ if err := tx .Commit ().Error ; err != nil {
185+ // Rollback is implicitly handled by GORM if Commit fails after successful operations within the transaction
186+ c .JSON (http .StatusInternalServerError , NewErrorResponse (http .StatusInternalServerError , "Failed to commit transaction: " + err .Error ()))
187+ return
188+ }
189+
190+ // Reload the complex with its goals to return the complete entity
191+ db .Preload ("Goals" ).First (& complex , complex .ID ) // GORM will load associated goals
192+
193+ c .JSON (http .StatusCreated , complex ) // Return the complex, potentially with its newly created goal(s)
151194}
152195
153196// GetComplexesHandler handles fetching all complexes for the authenticated user.
0 commit comments