File size: 468,568 Bytes
a58ece3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
{"category": "fiber", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> controllers\n\n// controllers/patientController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// PatientController handles HTTP requests for the Patient resource.\ntype PatientController struct {\n\tPatientService contracts.PatientServiceContract\n}\n\n// NewPatientController constructs a PatientController with its service dependency.\nfunc NewPatientController(svc contracts.PatientServiceContract) *PatientController {\n\treturn &PatientController{PatientService: svc}\n}\n\n// CreatePatient godoc\n// @Summary     Create a new patient\n// @Description Create a new patient in the system\n// @Tags        Patients\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.PatientInputDTO true \"Patient data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /patients [post]\nfunc (ctrl *PatientController) CreatePatient(c *fiber.Ctx) error {\n\tvar input contracts.PatientInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.Name == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"name is required\"})\n\t}\n\tif input.Contact == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"contact is required\"})\n\t}\n\n\tid, err := ctrl.PatientService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Patient created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByCPF godoc\n// @Summary     Get patient by CPF\n// @Description Retrieve a single patient identified by its CPF\n// @Tags        Patients\n// @Produce     json\n// @Security    BearerAuth\n// @Param       cpf path string true \"Patient CPF\"\n// @Success     200 {object} contracts.PatientDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /patients/{cpf} [get]\nfunc (ctrl *PatientController) GetByCPF(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"cpf\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"cpf is required\"})\n\t}\n\n\tresult, err := ctrl.PatientService.FindByCPF(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListPatients godoc\n// @Summary     List all patients\n// @Description Returns a paginated list of patients\n// @Tags        Patients\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.PatientDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /patients [get]\nfunc (ctrl *PatientController) ListPatients(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.PatientService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve patients\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"medical-sas-api/controllers\"\n\t\"medical-sas-api/initializers\"\n\t_ \"medical-sas-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewPatientController(svc.PatientService)\n\tpatients := protected.Group(\"/patients\")\n\tpatients.Post(\"/\",              entityCtrl.CreatePatient)\n\tpatients.Get(\"/\",               entityCtrl.ListPatients)\n\tpatients.Get(\"/:cpf\",   entityCtrl.GetByCPF)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"medical-sas-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> controllers\n\n// controllers/patientController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// PatientController handles HTTP requests for the Patient resource.\ntype PatientController struct {\n\tPatientService contracts.PatientServiceContract\n}\n\n// NewPatientController constructs a PatientController with its service dependency.\nfunc NewPatientController(svc contracts.PatientServiceContract) *PatientController {\n\treturn &PatientController{PatientService: svc}\n}\n\n// CreatePatient godoc\n// @Summary     Create a new patient\n// @Description Create a new patient in the system\n// @Tags        Patients\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.PatientInputDTO true \"Patient data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /patients [post]\nfunc (ctrl *PatientController) CreatePatient(c *fiber.Ctx) error {\n\tvar input contracts.PatientInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.Name == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"name is required\"})\n\t}\n\tif input.Contact == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"contact is required\"})\n\t}\n\n\tid, err := ctrl.PatientService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Patient created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByCPF godoc\n// @Summary     Get patient by CPF\n// @Description Retrieve a single patient identified by its CPF\n// @Tags        Patients\n// @Produce     json\n// @Security    BearerAuth\n// @Param       cpf path string true \"Patient CPF\"\n// @Success     200 {object} contracts.PatientDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /patients/{cpf} [get]\nfunc (ctrl *PatientController) GetByCPF(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"cpf\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"cpf is required\"})\n\t}\n\n\tresult, err := ctrl.PatientService.FindByCPF(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListPatients godoc\n// @Summary     List all patients\n// @Description Returns a paginated list of patients\n// @Tags        Patients\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.PatientDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /patients [get]\nfunc (ctrl *PatientController) ListPatients(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.PatientService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve patients\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"medical-sas-api/controllers\"\n\t\"medical-sas-api/initializers\"\n\t_ \"medical-sas-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewPatientController(svc.PatientService)\n\tpatients := protected.Group(\"/patients\")\n\tpatients.Post(\"/\",              entityCtrl.CreatePatient)\n\tpatients.Get(\"/\",               entityCtrl.ListPatients)\n\tpatients.Get(\"/:cpf\",   entityCtrl.GetByCPF)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"medical-sas-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> controllers\n\n// controllers/patientController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// PatientController handles HTTP requests for the Patient resource.\ntype PatientController struct {\n\tPatientService contracts.PatientServiceContract\n}\n\n// NewPatientController constructs a PatientController with its service dependency.\nfunc NewPatientController(svc contracts.PatientServiceContract) *PatientController {\n\treturn &PatientController{PatientService: svc}\n}\n\n// CreatePatient godoc\n// @Summary     Create a new patient\n// @Description Create a new patient in the system\n// @Tags        Patients\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.PatientInputDTO true \"Patient data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /patients [post]\nfunc (ctrl *PatientController) CreatePatient(c *fiber.Ctx) error {\n\tvar input contracts.PatientInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.Name == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"name is required\"})\n\t}\n\tif input.Contact == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"contact is required\"})\n\t}\n\n\tid, err := ctrl.PatientService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Patient created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByCPF godoc\n// @Summary     Get patient by CPF\n// @Description Retrieve a single patient identified by its CPF\n// @Tags        Patients\n// @Produce     json\n// @Security    BearerAuth\n// @Param       cpf path string true \"Patient CPF\"\n// @Success     200 {object} contracts.PatientDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /patients/{cpf} [get]\nfunc (ctrl *PatientController) GetByCPF(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"cpf\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"cpf is required\"})\n\t}\n\n\tresult, err := ctrl.PatientService.FindByCPF(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListPatients godoc\n// @Summary     List all patients\n// @Description Returns a paginated list of patients\n// @Tags        Patients\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.PatientDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /patients [get]\nfunc (ctrl *PatientController) ListPatients(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.PatientService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve patients\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"medical-sas-api/controllers\"\n\t\"medical-sas-api/initializers\"\n\t_ \"medical-sas-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewPatientController(svc.PatientService)\n\tpatients := protected.Group(\"/patients\")\n\tpatients.Post(\"/\",              entityCtrl.CreatePatient)\n\tpatients.Get(\"/\",               entityCtrl.ListPatients)\n\tpatients.Get(\"/:cpf\",   entityCtrl.GetByCPF)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"medical-sas-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> controllers\n\n// controllers/patientController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// PatientController handles HTTP requests for the Patient resource.\ntype PatientController struct {\n\tPatientService contracts.PatientServiceContract\n}\n\n// NewPatientController constructs a PatientController with its service dependency.\nfunc NewPatientController(svc contracts.PatientServiceContract) *PatientController {\n\treturn &PatientController{PatientService: svc}\n}\n\n// CreatePatient godoc\n// @Summary     Create a new patient\n// @Description Create a new patient in the system\n// @Tags        Patients\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.PatientInputDTO true \"Patient data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /patients [post]\nfunc (ctrl *PatientController) CreatePatient(c *fiber.Ctx) error {\n\tvar input contracts.PatientInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.Name == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"name is required\"})\n\t}\n\tif input.Contact == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"contact is required\"})\n\t}\n\n\tid, err := ctrl.PatientService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Patient created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByCPF godoc\n// @Summary     Get patient by CPF\n// @Description Retrieve a single patient identified by its CPF\n// @Tags        Patients\n// @Produce     json\n// @Security    BearerAuth\n// @Param       cpf path string true \"Patient CPF\"\n// @Success     200 {object} contracts.PatientDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /patients/{cpf} [get]\nfunc (ctrl *PatientController) GetByCPF(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"cpf\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"cpf is required\"})\n\t}\n\n\tresult, err := ctrl.PatientService.FindByCPF(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListPatients godoc\n// @Summary     List all patients\n// @Description Returns a paginated list of patients\n// @Tags        Patients\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.PatientDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /patients [get]\nfunc (ctrl *PatientController) ListPatients(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.PatientService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve patients\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"medical-sas-api/controllers\"\n\t\"medical-sas-api/initializers\"\n\t_ \"medical-sas-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewPatientController(svc.PatientService)\n\tpatients := protected.Group(\"/patients\")\n\tpatients.Post(\"/\",              entityCtrl.CreatePatient)\n\tpatients.Get(\"/\",               entityCtrl.ListPatients)\n\tpatients.Get(\"/:cpf\",   entityCtrl.GetByCPF)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"medical-sas-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> utils\n\n// utils/responseUtil.go\n// Pattern: response utility interface + JSON helper\n// Observed in: Medical-App-Core/utils/responseUtil.go\npackage utils\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ResponseUtil abstracts JSON response construction for testability.\ntype ResponseUtil interface {\n\tRespondWithJSON(c *fiber.Ctx, code int, payload any) error\n\tRespondWithError(c *fiber.Ctx, code int, message string) error\n}\n\n// JSONResponseUtil implements ResponseUtil using Fiber's context.\ntype JSONResponseUtil struct{}\n\nfunc (ru *JSONResponseUtil) RespondWithJSON(c *fiber.Ctx, code int, payload any) error {\n\tbody, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn c.Status(fiber.StatusInternalServerError).\n\t\t\tJSON(fiber.Map{\"error\": \"failed to marshal response\"})\n\t}\n\tc.Set(\"Content-Type\", \"application/json\")\n\treturn c.Status(code).Send(body)\n}\n\nfunc (ru *JSONResponseUtil) RespondWithError(c *fiber.Ctx, code int, message string) error {\n\treturn c.Status(code).JSON(fiber.Map{\"error\": message})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> controllers\n\n// controllers/orderController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"ecommerce-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// OrderController handles HTTP requests for the Order resource.\ntype OrderController struct {\n\tOrderService contracts.OrderServiceContract\n}\n\n// NewOrderController constructs a OrderController with its service dependency.\nfunc NewOrderController(svc contracts.OrderServiceContract) *OrderController {\n\treturn &OrderController{OrderService: svc}\n}\n\n// CreateOrder godoc\n// @Summary     Create a new order\n// @Description Create a new order in the system\n// @Tags        Orders\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.OrderInputDTO true \"Order data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /orders [post]\nfunc (ctrl *OrderController) CreateOrder(c *fiber.Ctx) error {\n\tvar input contracts.OrderInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.CustomerID == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"customer_id is required\"})\n\t}\n\tif len(input.Items) == 0 {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"items cannot be empty\"})\n\t}\n\n\tid, err := ctrl.OrderService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Order created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByOrderNumber godoc\n// @Summary     Get order by OrderNumber\n// @Description Retrieve a single order identified by its OrderNumber\n// @Tags        Orders\n// @Produce     json\n// @Security    BearerAuth\n// @Param       order_number path string true \"Order OrderNumber\"\n// @Success     200 {object} contracts.OrderDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /orders/{order_number} [get]\nfunc (ctrl *OrderController) GetByOrderNumber(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"order_number\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"order_number is required\"})\n\t}\n\n\tresult, err := ctrl.OrderService.FindByOrderNumber(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListOrders godoc\n// @Summary     List all orders\n// @Description Returns a paginated list of orders\n// @Tags        Orders\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.OrderDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /orders [get]\nfunc (ctrl *OrderController) ListOrders(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.OrderService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve orders\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"ecommerce-api/controllers\"\n\t\"ecommerce-api/initializers\"\n\t_ \"ecommerce-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewOrderController(svc.OrderService)\n\torders := protected.Group(\"/orders\")\n\torders.Post(\"/\",              entityCtrl.CreateOrder)\n\torders.Get(\"/\",               entityCtrl.ListOrders)\n\torders.Get(\"/:order_number\",   entityCtrl.GetByOrderNumber)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"ecommerce-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> controllers\n\n// controllers/orderController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"ecommerce-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// OrderController handles HTTP requests for the Order resource.\ntype OrderController struct {\n\tOrderService contracts.OrderServiceContract\n}\n\n// NewOrderController constructs a OrderController with its service dependency.\nfunc NewOrderController(svc contracts.OrderServiceContract) *OrderController {\n\treturn &OrderController{OrderService: svc}\n}\n\n// CreateOrder godoc\n// @Summary     Create a new order\n// @Description Create a new order in the system\n// @Tags        Orders\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.OrderInputDTO true \"Order data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /orders [post]\nfunc (ctrl *OrderController) CreateOrder(c *fiber.Ctx) error {\n\tvar input contracts.OrderInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.CustomerID == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"customer_id is required\"})\n\t}\n\tif len(input.Items) == 0 {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"items cannot be empty\"})\n\t}\n\n\tid, err := ctrl.OrderService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Order created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByOrderNumber godoc\n// @Summary     Get order by OrderNumber\n// @Description Retrieve a single order identified by its OrderNumber\n// @Tags        Orders\n// @Produce     json\n// @Security    BearerAuth\n// @Param       order_number path string true \"Order OrderNumber\"\n// @Success     200 {object} contracts.OrderDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /orders/{order_number} [get]\nfunc (ctrl *OrderController) GetByOrderNumber(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"order_number\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"order_number is required\"})\n\t}\n\n\tresult, err := ctrl.OrderService.FindByOrderNumber(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListOrders godoc\n// @Summary     List all orders\n// @Description Returns a paginated list of orders\n// @Tags        Orders\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.OrderDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /orders [get]\nfunc (ctrl *OrderController) ListOrders(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.OrderService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve orders\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"ecommerce-api/controllers\"\n\t\"ecommerce-api/initializers\"\n\t_ \"ecommerce-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewOrderController(svc.OrderService)\n\torders := protected.Group(\"/orders\")\n\torders.Post(\"/\",              entityCtrl.CreateOrder)\n\torders.Get(\"/\",               entityCtrl.ListOrders)\n\torders.Get(\"/:order_number\",   entityCtrl.GetByOrderNumber)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"ecommerce-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> controllers\n\n// controllers/orderController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"ecommerce-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// OrderController handles HTTP requests for the Order resource.\ntype OrderController struct {\n\tOrderService contracts.OrderServiceContract\n}\n\n// NewOrderController constructs a OrderController with its service dependency.\nfunc NewOrderController(svc contracts.OrderServiceContract) *OrderController {\n\treturn &OrderController{OrderService: svc}\n}\n\n// CreateOrder godoc\n// @Summary     Create a new order\n// @Description Create a new order in the system\n// @Tags        Orders\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.OrderInputDTO true \"Order data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /orders [post]\nfunc (ctrl *OrderController) CreateOrder(c *fiber.Ctx) error {\n\tvar input contracts.OrderInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.CustomerID == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"customer_id is required\"})\n\t}\n\tif len(input.Items) == 0 {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"items cannot be empty\"})\n\t}\n\n\tid, err := ctrl.OrderService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Order created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByOrderNumber godoc\n// @Summary     Get order by OrderNumber\n// @Description Retrieve a single order identified by its OrderNumber\n// @Tags        Orders\n// @Produce     json\n// @Security    BearerAuth\n// @Param       order_number path string true \"Order OrderNumber\"\n// @Success     200 {object} contracts.OrderDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /orders/{order_number} [get]\nfunc (ctrl *OrderController) GetByOrderNumber(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"order_number\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"order_number is required\"})\n\t}\n\n\tresult, err := ctrl.OrderService.FindByOrderNumber(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListOrders godoc\n// @Summary     List all orders\n// @Description Returns a paginated list of orders\n// @Tags        Orders\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.OrderDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /orders [get]\nfunc (ctrl *OrderController) ListOrders(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.OrderService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve orders\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"ecommerce-api/controllers\"\n\t\"ecommerce-api/initializers\"\n\t_ \"ecommerce-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewOrderController(svc.OrderService)\n\torders := protected.Group(\"/orders\")\n\torders.Post(\"/\",              entityCtrl.CreateOrder)\n\torders.Get(\"/\",               entityCtrl.ListOrders)\n\torders.Get(\"/:order_number\",   entityCtrl.GetByOrderNumber)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"ecommerce-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> controllers\n\n// controllers/orderController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"ecommerce-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// OrderController handles HTTP requests for the Order resource.\ntype OrderController struct {\n\tOrderService contracts.OrderServiceContract\n}\n\n// NewOrderController constructs a OrderController with its service dependency.\nfunc NewOrderController(svc contracts.OrderServiceContract) *OrderController {\n\treturn &OrderController{OrderService: svc}\n}\n\n// CreateOrder godoc\n// @Summary     Create a new order\n// @Description Create a new order in the system\n// @Tags        Orders\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.OrderInputDTO true \"Order data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /orders [post]\nfunc (ctrl *OrderController) CreateOrder(c *fiber.Ctx) error {\n\tvar input contracts.OrderInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.CustomerID == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"customer_id is required\"})\n\t}\n\tif len(input.Items) == 0 {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"items cannot be empty\"})\n\t}\n\n\tid, err := ctrl.OrderService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Order created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByOrderNumber godoc\n// @Summary     Get order by OrderNumber\n// @Description Retrieve a single order identified by its OrderNumber\n// @Tags        Orders\n// @Produce     json\n// @Security    BearerAuth\n// @Param       order_number path string true \"Order OrderNumber\"\n// @Success     200 {object} contracts.OrderDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /orders/{order_number} [get]\nfunc (ctrl *OrderController) GetByOrderNumber(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"order_number\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"order_number is required\"})\n\t}\n\n\tresult, err := ctrl.OrderService.FindByOrderNumber(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListOrders godoc\n// @Summary     List all orders\n// @Description Returns a paginated list of orders\n// @Tags        Orders\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.OrderDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /orders [get]\nfunc (ctrl *OrderController) ListOrders(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.OrderService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve orders\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"ecommerce-api/controllers\"\n\t\"ecommerce-api/initializers\"\n\t_ \"ecommerce-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewOrderController(svc.OrderService)\n\torders := protected.Group(\"/orders\")\n\torders.Post(\"/\",              entityCtrl.CreateOrder)\n\torders.Get(\"/\",               entityCtrl.ListOrders)\n\torders.Get(\"/:order_number\",   entityCtrl.GetByOrderNumber)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"ecommerce-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> utils\n\n// utils/responseUtil.go\n// Pattern: response utility interface + JSON helper\n// Observed in: Medical-App-Core/utils/responseUtil.go\npackage utils\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ResponseUtil abstracts JSON response construction for testability.\ntype ResponseUtil interface {\n\tRespondWithJSON(c *fiber.Ctx, code int, payload any) error\n\tRespondWithError(c *fiber.Ctx, code int, message string) error\n}\n\n// JSONResponseUtil implements ResponseUtil using Fiber's context.\ntype JSONResponseUtil struct{}\n\nfunc (ru *JSONResponseUtil) RespondWithJSON(c *fiber.Ctx, code int, payload any) error {\n\tbody, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn c.Status(fiber.StatusInternalServerError).\n\t\t\tJSON(fiber.Map{\"error\": \"failed to marshal response\"})\n\t}\n\tc.Set(\"Content-Type\", \"application/json\")\n\treturn c.Status(code).Send(body)\n}\n\nfunc (ru *JSONResponseUtil) RespondWithError(c *fiber.Ctx, code int, message string) error {\n\treturn c.Status(code).JSON(fiber.Map{\"error\": message})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> controllers\n\n// controllers/employeeController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"hrm-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// EmployeeController handles HTTP requests for the Employee resource.\ntype EmployeeController struct {\n\tEmployeeService contracts.EmployeeServiceContract\n}\n\n// NewEmployeeController constructs a EmployeeController with its service dependency.\nfunc NewEmployeeController(svc contracts.EmployeeServiceContract) *EmployeeController {\n\treturn &EmployeeController{EmployeeService: svc}\n}\n\n// CreateEmployee godoc\n// @Summary     Create a new employee\n// @Description Create a new employee in the system\n// @Tags        Employees\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.EmployeeInputDTO true \"Employee data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /employees [post]\nfunc (ctrl *EmployeeController) CreateEmployee(c *fiber.Ctx) error {\n\tvar input contracts.EmployeeInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.DepartmentName == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"department_name is required\"})\n\t}\n\tif input.Position == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"position is required\"})\n\t}\n\n\tid, err := ctrl.EmployeeService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Employee created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByCPF godoc\n// @Summary     Get employee by CPF\n// @Description Retrieve a single employee identified by its CPF\n// @Tags        Employees\n// @Produce     json\n// @Security    BearerAuth\n// @Param       cpf path string true \"Employee CPF\"\n// @Success     200 {object} contracts.EmployeeDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /employees/{cpf} [get]\nfunc (ctrl *EmployeeController) GetByCPF(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"cpf\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"cpf is required\"})\n\t}\n\n\tresult, err := ctrl.EmployeeService.FindByCPF(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListEmployees godoc\n// @Summary     List all employees\n// @Description Returns a paginated list of employees\n// @Tags        Employees\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.EmployeeDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /employees [get]\nfunc (ctrl *EmployeeController) ListEmployees(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.EmployeeService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve employees\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"hrm-api/controllers\"\n\t\"hrm-api/initializers\"\n\t_ \"hrm-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewEmployeeController(svc.EmployeeService)\n\temployees := protected.Group(\"/employees\")\n\temployees.Post(\"/\",              entityCtrl.CreateEmployee)\n\temployees.Get(\"/\",               entityCtrl.ListEmployees)\n\temployees.Get(\"/:cpf\",   entityCtrl.GetByCPF)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"hrm-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> controllers\n\n// controllers/employeeController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"hrm-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// EmployeeController handles HTTP requests for the Employee resource.\ntype EmployeeController struct {\n\tEmployeeService contracts.EmployeeServiceContract\n}\n\n// NewEmployeeController constructs a EmployeeController with its service dependency.\nfunc NewEmployeeController(svc contracts.EmployeeServiceContract) *EmployeeController {\n\treturn &EmployeeController{EmployeeService: svc}\n}\n\n// CreateEmployee godoc\n// @Summary     Create a new employee\n// @Description Create a new employee in the system\n// @Tags        Employees\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.EmployeeInputDTO true \"Employee data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /employees [post]\nfunc (ctrl *EmployeeController) CreateEmployee(c *fiber.Ctx) error {\n\tvar input contracts.EmployeeInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.DepartmentName == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"department_name is required\"})\n\t}\n\tif input.Position == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"position is required\"})\n\t}\n\n\tid, err := ctrl.EmployeeService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Employee created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByCPF godoc\n// @Summary     Get employee by CPF\n// @Description Retrieve a single employee identified by its CPF\n// @Tags        Employees\n// @Produce     json\n// @Security    BearerAuth\n// @Param       cpf path string true \"Employee CPF\"\n// @Success     200 {object} contracts.EmployeeDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /employees/{cpf} [get]\nfunc (ctrl *EmployeeController) GetByCPF(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"cpf\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"cpf is required\"})\n\t}\n\n\tresult, err := ctrl.EmployeeService.FindByCPF(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListEmployees godoc\n// @Summary     List all employees\n// @Description Returns a paginated list of employees\n// @Tags        Employees\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.EmployeeDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /employees [get]\nfunc (ctrl *EmployeeController) ListEmployees(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.EmployeeService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve employees\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"hrm-api/controllers\"\n\t\"hrm-api/initializers\"\n\t_ \"hrm-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewEmployeeController(svc.EmployeeService)\n\temployees := protected.Group(\"/employees\")\n\temployees.Post(\"/\",              entityCtrl.CreateEmployee)\n\temployees.Get(\"/\",               entityCtrl.ListEmployees)\n\temployees.Get(\"/:cpf\",   entityCtrl.GetByCPF)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"hrm-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> controllers\n\n// controllers/employeeController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"hrm-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// EmployeeController handles HTTP requests for the Employee resource.\ntype EmployeeController struct {\n\tEmployeeService contracts.EmployeeServiceContract\n}\n\n// NewEmployeeController constructs a EmployeeController with its service dependency.\nfunc NewEmployeeController(svc contracts.EmployeeServiceContract) *EmployeeController {\n\treturn &EmployeeController{EmployeeService: svc}\n}\n\n// CreateEmployee godoc\n// @Summary     Create a new employee\n// @Description Create a new employee in the system\n// @Tags        Employees\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.EmployeeInputDTO true \"Employee data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /employees [post]\nfunc (ctrl *EmployeeController) CreateEmployee(c *fiber.Ctx) error {\n\tvar input contracts.EmployeeInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.DepartmentName == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"department_name is required\"})\n\t}\n\tif input.Position == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"position is required\"})\n\t}\n\n\tid, err := ctrl.EmployeeService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Employee created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByCPF godoc\n// @Summary     Get employee by CPF\n// @Description Retrieve a single employee identified by its CPF\n// @Tags        Employees\n// @Produce     json\n// @Security    BearerAuth\n// @Param       cpf path string true \"Employee CPF\"\n// @Success     200 {object} contracts.EmployeeDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /employees/{cpf} [get]\nfunc (ctrl *EmployeeController) GetByCPF(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"cpf\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"cpf is required\"})\n\t}\n\n\tresult, err := ctrl.EmployeeService.FindByCPF(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListEmployees godoc\n// @Summary     List all employees\n// @Description Returns a paginated list of employees\n// @Tags        Employees\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.EmployeeDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /employees [get]\nfunc (ctrl *EmployeeController) ListEmployees(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.EmployeeService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve employees\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"hrm-api/controllers\"\n\t\"hrm-api/initializers\"\n\t_ \"hrm-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewEmployeeController(svc.EmployeeService)\n\temployees := protected.Group(\"/employees\")\n\temployees.Post(\"/\",              entityCtrl.CreateEmployee)\n\temployees.Get(\"/\",               entityCtrl.ListEmployees)\n\temployees.Get(\"/:cpf\",   entityCtrl.GetByCPF)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"hrm-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> controllers\n\n// controllers/employeeController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"hrm-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// EmployeeController handles HTTP requests for the Employee resource.\ntype EmployeeController struct {\n\tEmployeeService contracts.EmployeeServiceContract\n}\n\n// NewEmployeeController constructs a EmployeeController with its service dependency.\nfunc NewEmployeeController(svc contracts.EmployeeServiceContract) *EmployeeController {\n\treturn &EmployeeController{EmployeeService: svc}\n}\n\n// CreateEmployee godoc\n// @Summary     Create a new employee\n// @Description Create a new employee in the system\n// @Tags        Employees\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.EmployeeInputDTO true \"Employee data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /employees [post]\nfunc (ctrl *EmployeeController) CreateEmployee(c *fiber.Ctx) error {\n\tvar input contracts.EmployeeInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.DepartmentName == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"department_name is required\"})\n\t}\n\tif input.Position == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"position is required\"})\n\t}\n\n\tid, err := ctrl.EmployeeService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Employee created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByCPF godoc\n// @Summary     Get employee by CPF\n// @Description Retrieve a single employee identified by its CPF\n// @Tags        Employees\n// @Produce     json\n// @Security    BearerAuth\n// @Param       cpf path string true \"Employee CPF\"\n// @Success     200 {object} contracts.EmployeeDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /employees/{cpf} [get]\nfunc (ctrl *EmployeeController) GetByCPF(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"cpf\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"cpf is required\"})\n\t}\n\n\tresult, err := ctrl.EmployeeService.FindByCPF(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListEmployees godoc\n// @Summary     List all employees\n// @Description Returns a paginated list of employees\n// @Tags        Employees\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.EmployeeDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /employees [get]\nfunc (ctrl *EmployeeController) ListEmployees(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.EmployeeService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve employees\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"hrm-api/controllers\"\n\t\"hrm-api/initializers\"\n\t_ \"hrm-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewEmployeeController(svc.EmployeeService)\n\temployees := protected.Group(\"/employees\")\n\temployees.Post(\"/\",              entityCtrl.CreateEmployee)\n\temployees.Get(\"/\",               entityCtrl.ListEmployees)\n\temployees.Get(\"/:cpf\",   entityCtrl.GetByCPF)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"hrm-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> utils\n\n// utils/responseUtil.go\n// Pattern: response utility interface + JSON helper\n// Observed in: Medical-App-Core/utils/responseUtil.go\npackage utils\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ResponseUtil abstracts JSON response construction for testability.\ntype ResponseUtil interface {\n\tRespondWithJSON(c *fiber.Ctx, code int, payload any) error\n\tRespondWithError(c *fiber.Ctx, code int, message string) error\n}\n\n// JSONResponseUtil implements ResponseUtil using Fiber's context.\ntype JSONResponseUtil struct{}\n\nfunc (ru *JSONResponseUtil) RespondWithJSON(c *fiber.Ctx, code int, payload any) error {\n\tbody, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn c.Status(fiber.StatusInternalServerError).\n\t\t\tJSON(fiber.Map{\"error\": \"failed to marshal response\"})\n\t}\n\tc.Set(\"Content-Type\", \"application/json\")\n\treturn c.Status(code).Send(body)\n}\n\nfunc (ru *JSONResponseUtil) RespondWithError(c *fiber.Ctx, code int, message string) error {\n\treturn c.Status(code).JSON(fiber.Map{\"error\": message})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> controllers\n\n// controllers/shipmentController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"logistics-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ShipmentController handles HTTP requests for the Shipment resource.\ntype ShipmentController struct {\n\tShipmentService contracts.ShipmentServiceContract\n}\n\n// NewShipmentController constructs a ShipmentController with its service dependency.\nfunc NewShipmentController(svc contracts.ShipmentServiceContract) *ShipmentController {\n\treturn &ShipmentController{ShipmentService: svc}\n}\n\n// CreateShipment godoc\n// @Summary     Create a new shipment\n// @Description Create a new shipment in the system\n// @Tags        Shipments\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.ShipmentInputDTO true \"Shipment data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /shipments [post]\nfunc (ctrl *ShipmentController) CreateShipment(c *fiber.Ctx) error {\n\tvar input contracts.ShipmentInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.OriginAddress == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"origin_address is required\"})\n\t}\n\tif input.DestinationAddress == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"destination_address is required\"})\n\t}\n\n\tid, err := ctrl.ShipmentService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Shipment created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByTrackingCode godoc\n// @Summary     Get shipment by TrackingCode\n// @Description Retrieve a single shipment identified by its TrackingCode\n// @Tags        Shipments\n// @Produce     json\n// @Security    BearerAuth\n// @Param       tracking_code path string true \"Shipment TrackingCode\"\n// @Success     200 {object} contracts.ShipmentDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /shipments/{tracking_code} [get]\nfunc (ctrl *ShipmentController) GetByTrackingCode(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"tracking_code\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"tracking_code is required\"})\n\t}\n\n\tresult, err := ctrl.ShipmentService.FindByTrackingCode(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListShipments godoc\n// @Summary     List all shipments\n// @Description Returns a paginated list of shipments\n// @Tags        Shipments\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.ShipmentDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /shipments [get]\nfunc (ctrl *ShipmentController) ListShipments(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.ShipmentService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve shipments\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"logistics-api/controllers\"\n\t\"logistics-api/initializers\"\n\t_ \"logistics-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewShipmentController(svc.ShipmentService)\n\tshipments := protected.Group(\"/shipments\")\n\tshipments.Post(\"/\",              entityCtrl.CreateShipment)\n\tshipments.Get(\"/\",               entityCtrl.ListShipments)\n\tshipments.Get(\"/:tracking_code\",   entityCtrl.GetByTrackingCode)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"logistics-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> controllers\n\n// controllers/shipmentController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"logistics-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ShipmentController handles HTTP requests for the Shipment resource.\ntype ShipmentController struct {\n\tShipmentService contracts.ShipmentServiceContract\n}\n\n// NewShipmentController constructs a ShipmentController with its service dependency.\nfunc NewShipmentController(svc contracts.ShipmentServiceContract) *ShipmentController {\n\treturn &ShipmentController{ShipmentService: svc}\n}\n\n// CreateShipment godoc\n// @Summary     Create a new shipment\n// @Description Create a new shipment in the system\n// @Tags        Shipments\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.ShipmentInputDTO true \"Shipment data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /shipments [post]\nfunc (ctrl *ShipmentController) CreateShipment(c *fiber.Ctx) error {\n\tvar input contracts.ShipmentInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.OriginAddress == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"origin_address is required\"})\n\t}\n\tif input.DestinationAddress == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"destination_address is required\"})\n\t}\n\n\tid, err := ctrl.ShipmentService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Shipment created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByTrackingCode godoc\n// @Summary     Get shipment by TrackingCode\n// @Description Retrieve a single shipment identified by its TrackingCode\n// @Tags        Shipments\n// @Produce     json\n// @Security    BearerAuth\n// @Param       tracking_code path string true \"Shipment TrackingCode\"\n// @Success     200 {object} contracts.ShipmentDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /shipments/{tracking_code} [get]\nfunc (ctrl *ShipmentController) GetByTrackingCode(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"tracking_code\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"tracking_code is required\"})\n\t}\n\n\tresult, err := ctrl.ShipmentService.FindByTrackingCode(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListShipments godoc\n// @Summary     List all shipments\n// @Description Returns a paginated list of shipments\n// @Tags        Shipments\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.ShipmentDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /shipments [get]\nfunc (ctrl *ShipmentController) ListShipments(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.ShipmentService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve shipments\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"logistics-api/controllers\"\n\t\"logistics-api/initializers\"\n\t_ \"logistics-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewShipmentController(svc.ShipmentService)\n\tshipments := protected.Group(\"/shipments\")\n\tshipments.Post(\"/\",              entityCtrl.CreateShipment)\n\tshipments.Get(\"/\",               entityCtrl.ListShipments)\n\tshipments.Get(\"/:tracking_code\",   entityCtrl.GetByTrackingCode)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"logistics-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> controllers\n\n// controllers/shipmentController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"logistics-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ShipmentController handles HTTP requests for the Shipment resource.\ntype ShipmentController struct {\n\tShipmentService contracts.ShipmentServiceContract\n}\n\n// NewShipmentController constructs a ShipmentController with its service dependency.\nfunc NewShipmentController(svc contracts.ShipmentServiceContract) *ShipmentController {\n\treturn &ShipmentController{ShipmentService: svc}\n}\n\n// CreateShipment godoc\n// @Summary     Create a new shipment\n// @Description Create a new shipment in the system\n// @Tags        Shipments\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.ShipmentInputDTO true \"Shipment data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /shipments [post]\nfunc (ctrl *ShipmentController) CreateShipment(c *fiber.Ctx) error {\n\tvar input contracts.ShipmentInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.OriginAddress == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"origin_address is required\"})\n\t}\n\tif input.DestinationAddress == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"destination_address is required\"})\n\t}\n\n\tid, err := ctrl.ShipmentService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Shipment created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByTrackingCode godoc\n// @Summary     Get shipment by TrackingCode\n// @Description Retrieve a single shipment identified by its TrackingCode\n// @Tags        Shipments\n// @Produce     json\n// @Security    BearerAuth\n// @Param       tracking_code path string true \"Shipment TrackingCode\"\n// @Success     200 {object} contracts.ShipmentDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /shipments/{tracking_code} [get]\nfunc (ctrl *ShipmentController) GetByTrackingCode(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"tracking_code\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"tracking_code is required\"})\n\t}\n\n\tresult, err := ctrl.ShipmentService.FindByTrackingCode(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListShipments godoc\n// @Summary     List all shipments\n// @Description Returns a paginated list of shipments\n// @Tags        Shipments\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.ShipmentDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /shipments [get]\nfunc (ctrl *ShipmentController) ListShipments(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.ShipmentService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve shipments\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"logistics-api/controllers\"\n\t\"logistics-api/initializers\"\n\t_ \"logistics-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewShipmentController(svc.ShipmentService)\n\tshipments := protected.Group(\"/shipments\")\n\tshipments.Post(\"/\",              entityCtrl.CreateShipment)\n\tshipments.Get(\"/\",               entityCtrl.ListShipments)\n\tshipments.Get(\"/:tracking_code\",   entityCtrl.GetByTrackingCode)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"logistics-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> controllers\n\n// controllers/shipmentController.go\n// Pattern: struct controller + constructor injection + Swagger annotations\n// Observed in: Medical-App-Core/controllers/\npackage controllers\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"logistics-api/services/contracts\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ShipmentController handles HTTP requests for the Shipment resource.\ntype ShipmentController struct {\n\tShipmentService contracts.ShipmentServiceContract\n}\n\n// NewShipmentController constructs a ShipmentController with its service dependency.\nfunc NewShipmentController(svc contracts.ShipmentServiceContract) *ShipmentController {\n\treturn &ShipmentController{ShipmentService: svc}\n}\n\n// CreateShipment godoc\n// @Summary     Create a new shipment\n// @Description Create a new shipment in the system\n// @Tags        Shipments\n// @Accept      json\n// @Produce     json\n// @Security    BearerAuth\n// @Param       body body contracts.ShipmentInputDTO true \"Shipment data\"\n// @Success     201  {object} fiber.Map\n// @Failure     400  {object} fiber.Map\n// @Failure     422  {object} fiber.Map\n// @Failure     500  {object} fiber.Map\n// @Router      /shipments [post]\nfunc (ctrl *ShipmentController) CreateShipment(c *fiber.Ctx) error {\n\tvar input contracts.ShipmentInputDTO\n\tif err := c.BodyParser(&input); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\n\tif input.OriginAddress == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"origin_address is required\"})\n\t}\n\tif input.DestinationAddress == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"destination_address is required\"})\n\t}\n\n\tid, err := ctrl.ShipmentService.CreateFromInput(input)\n\tif err != nil {\n\t\treturn c.Status(http.StatusUnprocessableEntity).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusCreated).JSON(fiber.Map{\n\t\t\"message\": \"Shipment created successfully\",\n\t\t\"id\":      id,\n\t})\n}\n\n// GetByTrackingCode godoc\n// @Summary     Get shipment by TrackingCode\n// @Description Retrieve a single shipment identified by its TrackingCode\n// @Tags        Shipments\n// @Produce     json\n// @Security    BearerAuth\n// @Param       tracking_code path string true \"Shipment TrackingCode\"\n// @Success     200 {object} contracts.ShipmentDTO\n// @Failure     400 {object} fiber.Map\n// @Failure     404 {object} fiber.Map\n// @Router      /shipments/{tracking_code} [get]\nfunc (ctrl *ShipmentController) GetByTrackingCode(c *fiber.Ctx) error {\n\tidentifier := c.Params(\"tracking_code\")\n\tif identifier == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"tracking_code is required\"})\n\t}\n\n\tresult, err := ctrl.ShipmentService.FindByTrackingCode(identifier)\n\tif err != nil {\n\t\treturn c.Status(http.StatusNotFound).JSON(fiber.Map{\"error\": err.Error()})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(result)\n}\n\n// ListShipments godoc\n// @Summary     List all shipments\n// @Description Returns a paginated list of shipments\n// @Tags        Shipments\n// @Produce     json\n// @Security    BearerAuth\n// @Param       page  query int false \"Page number (default 1)\"\n// @Param       limit query int false \"Page size (default 20)\"\n// @Success     200  {array}  contracts.ShipmentDTO\n// @Failure     500  {object} fiber.Map\n// @Router      /shipments [get]\nfunc (ctrl *ShipmentController) ListShipments(c *fiber.Ctx) error {\n\tpage  := c.QueryInt(\"page\", 1)\n\tlimit := c.QueryInt(\"limit\", 20)\n\tif page < 1  { page = 1 }\n\tif limit < 1 { limit = 20 }\n\n\tresults, err := ctrl.ShipmentService.List(page, limit)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to retrieve shipments\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\n\t\t\"data\":  results,\n\t\t\"page\":  page,\n\t\t\"limit\": limit,\n\t})\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> main\n\n// cmd/main.go β€” Fiber router setup\n// Pattern: group-based routing + auth middleware + Swagger protection\n// Observed in: Medical-App-Core/cmd/main.go\npackage main\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"logistics-api/controllers\"\n\t\"logistics-api/initializers\"\n\t_ \"logistics-api/docs\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/gofiber/fiber/v2/middleware/basicauth\"\n\t\"github.com/gofiber/fiber/v2/middleware/cors\"\n\t\"github.com/gofiber/fiber/v2/middleware/logger\"\n\t\"github.com/gofiber/swagger\"\n\t\"github.com/joho/godotenv\"\n)\n\n// bearerAuthMiddleware validates the Authorization: Bearer <token> header.\n// Returns 401 if missing or invalid; calls Next() on success.\nfunc bearerAuthMiddleware(svc *initializers.Services) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif len(header) <= 7 || header[:7] != \"Bearer \" {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\t\tif err := svc.AuthTokenService.ValidateToken(header[7:]); err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n\nfunc configureMiddleware(app *fiber.App) {\n\tapp.Use(cors.New(cors.Config{\n\t\tAllowOrigins: \"*\",\n\t\tAllowMethods: \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n\t\tAllowHeaders: \"Origin, Content-Type, Accept, Authorization\",\n\t}))\n\tapp.Use(logger.New(logger.Config{\n\t\tFormat: `[$\\{time\\}] $\\{status\\} - $\\{method\\} $\\{path\\}\\n`,\n\t}))\n}\n\nfunc registerRoutes(app *fiber.App, svc *initializers.Services) {\n\tauth := app.Group(\"/auth\")\n\tauth.Post(\"/token\",    controllers.NewAuthController(svc.AuthTokenService).GenerateToken)\n\tauth.Post(\"/validate\", controllers.NewAuthController(svc.AuthTokenService).ValidateToken)\n\n\tprotected := app.Group(\"/\", bearerAuthMiddleware(svc))\n\n\tentityCtrl := controllers.NewShipmentController(svc.ShipmentService)\n\tshipments := protected.Group(\"/shipments\")\n\tshipments.Post(\"/\",              entityCtrl.CreateShipment)\n\tshipments.Get(\"/\",               entityCtrl.ListShipments)\n\tshipments.Get(\"/:tracking_code\",   entityCtrl.GetByTrackingCode)\n}\n\nfunc main() {\n\tif err := godotenv.Load(); err != nil {\n\t\tlog.Println(\"warning: .env file not found, using environment\")\n\t}\n\n\tdb  := initializers.InitialDB()\n\tinitializers.RunMigrations(db)\n\tsvc := initializers.InitServices(db)\n\n\tapp := fiber.New(fiber.Config{AppName: \"logistics-api v1\"})\n\tconfigureMiddleware(app)\n\n\t// Swagger endpoint protected by basic auth\n\tswaggerUser := os.Getenv(\"SWAGGER_USER\")\n\tswaggerPass := os.Getenv(\"SWAGGER_PASSWORD\")\n\tif swaggerUser == \"\" || swaggerPass == \"\" {\n\t\tlog.Fatal(\"SWAGGER_USER and SWAGGER_PASSWORD must be set\")\n\t}\n\tswaggerAuth := basicauth.New(basicauth.Config{\n\t\tUsers: map[string]string{swaggerUser: swaggerPass},\n\t})\n\tapp.Get(\"/swagger/*\", swaggerAuth, swagger.HandlerDefault)\n\n\tregisterRoutes(app, svc)\n\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tlog.Printf(\"server listening on :%s\", port)\n\tif err := app.Listen(\":\" + port); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n</go_file>\n"}
{"category": "fiber", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> utils\n\n// utils/responseUtil.go\n// Pattern: response utility interface + JSON helper\n// Observed in: Medical-App-Core/utils/responseUtil.go\npackage utils\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// ResponseUtil abstracts JSON response construction for testability.\ntype ResponseUtil interface {\n\tRespondWithJSON(c *fiber.Ctx, code int, payload any) error\n\tRespondWithError(c *fiber.Ctx, code int, message string) error\n}\n\n// JSONResponseUtil implements ResponseUtil using Fiber's context.\ntype JSONResponseUtil struct{}\n\nfunc (ru *JSONResponseUtil) RespondWithJSON(c *fiber.Ctx, code int, payload any) error {\n\tbody, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn c.Status(fiber.StatusInternalServerError).\n\t\t\tJSON(fiber.Map{\"error\": \"failed to marshal response\"})\n\t}\n\tc.Set(\"Content-Type\", \"application/json\")\n\treturn c.Status(code).Send(body)\n}\n\nfunc (ru *JSONResponseUtil) RespondWithError(c *fiber.Ctx, code int, message string) error {\n\treturn c.Status(code).JSON(fiber.Map{\"error\": message})\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> entities\n\n// domain/entities/patient.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Patient represents the patients database table.\ntype Patient struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID      `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tName           string         `gorm:\"type:varchar(255);not null\" json:\"name\" validate:\"required\"`\n\tContact        string         `gorm:\"type:varchar(50);not null\" json:\"contact\" validate:\"required\"`\n\tCPF            string         `gorm:\"type:varchar(14);uniqueIndex\" json:\"cpf,omitempty\"`\n\tSSN            string         `gorm:\"type:varchar(11);uniqueIndex\" json:\"ssn,omitempty\"`\n\tDOB            time.Time      `gorm:\"type:date\" json:\"dob\"`\n\tGender         string         `gorm:\"type:varchar(20)\" json:\"gender,omitempty\"`\n\tAddress        string         `gorm:\"type:text\" json:\"address,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Patient) TableName() string { return \"patients\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Patient) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> contracts\n\n// domain/repositories/contracts/patientRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// PatientRepository defines the persistence contract for Patient entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype PatientRepository interface {\n\tCreate(dto dtos.PatientDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.PatientDTO, error)\n\tFindByCPF(cpf string) (*dtos.PatientDTO, error)\n\tList(page, limit int) ([]dtos.PatientDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.PatientDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> repositories\n\n// infra/repositories/patientRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// PatientRepositoryImpl implements contracts.PatientRepository using GORM.\ntype PatientRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewPatientRepository constructs a new PatientRepositoryImpl.\nfunc NewPatientRepository(db *gorm.DB) *PatientRepositoryImpl {\n\treturn &PatientRepositoryImpl{db: db}\n}\n\nfunc (r *PatientRepositoryImpl) Create(dto dtos.PatientDTO) (uuid.UUID, error) {\n\tentity := entities.Patient{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"patient create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *PatientRepositoryImpl) FindByID(id uuid.UUID) (*dtos.PatientDTO, error) {\n\tvar entity entities.Patient\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"patient not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"patient find: %w\", err)\n\t}\n\tdto := dtos.PatientDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *PatientRepositoryImpl) FindByCPF(cpf string) (*dtos.PatientDTO, error) {\n\tvar entity entities.Patient\n\tif err := r.db.Where(\"cpf = ?\", cpf).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"patient with cpf=%s not found\", cpf)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"patient find by cpf: %w\", err)\n\t}\n\tdto := dtos.PatientDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *PatientRepositoryImpl) List(page, limit int) ([]dtos.PatientDTO, error) {\n\tvar entities []entities.Patient\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"patient list: %w\", err)\n\t}\n\tdtos := make([]dtos.PatientDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *PatientRepositoryImpl) Update(id uuid.UUID, dto dtos.PatientDTO) error {\n\tresult := r.db.Model(&entities.Patient{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"patient update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"patient not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *PatientRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Patient{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"patient delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"patient not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> entities\n\n// domain/entities/patient.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Patient represents the patients database table.\ntype Patient struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID      `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tName           string         `gorm:\"type:varchar(255);not null\" json:\"name\" validate:\"required\"`\n\tContact        string         `gorm:\"type:varchar(50);not null\" json:\"contact\" validate:\"required\"`\n\tCPF            string         `gorm:\"type:varchar(14);uniqueIndex\" json:\"cpf,omitempty\"`\n\tSSN            string         `gorm:\"type:varchar(11);uniqueIndex\" json:\"ssn,omitempty\"`\n\tDOB            time.Time      `gorm:\"type:date\" json:\"dob\"`\n\tGender         string         `gorm:\"type:varchar(20)\" json:\"gender,omitempty\"`\n\tAddress        string         `gorm:\"type:text\" json:\"address,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Patient) TableName() string { return \"patients\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Patient) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> contracts\n\n// domain/repositories/contracts/patientRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// PatientRepository defines the persistence contract for Patient entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype PatientRepository interface {\n\tCreate(dto dtos.PatientDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.PatientDTO, error)\n\tFindByCPF(cpf string) (*dtos.PatientDTO, error)\n\tList(page, limit int) ([]dtos.PatientDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.PatientDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> repositories\n\n// infra/repositories/patientRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// PatientRepositoryImpl implements contracts.PatientRepository using GORM.\ntype PatientRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewPatientRepository constructs a new PatientRepositoryImpl.\nfunc NewPatientRepository(db *gorm.DB) *PatientRepositoryImpl {\n\treturn &PatientRepositoryImpl{db: db}\n}\n\nfunc (r *PatientRepositoryImpl) Create(dto dtos.PatientDTO) (uuid.UUID, error) {\n\tentity := entities.Patient{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"patient create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *PatientRepositoryImpl) FindByID(id uuid.UUID) (*dtos.PatientDTO, error) {\n\tvar entity entities.Patient\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"patient not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"patient find: %w\", err)\n\t}\n\tdto := dtos.PatientDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *PatientRepositoryImpl) FindByCPF(cpf string) (*dtos.PatientDTO, error) {\n\tvar entity entities.Patient\n\tif err := r.db.Where(\"cpf = ?\", cpf).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"patient with cpf=%s not found\", cpf)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"patient find by cpf: %w\", err)\n\t}\n\tdto := dtos.PatientDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *PatientRepositoryImpl) List(page, limit int) ([]dtos.PatientDTO, error) {\n\tvar entities []entities.Patient\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"patient list: %w\", err)\n\t}\n\tdtos := make([]dtos.PatientDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *PatientRepositoryImpl) Update(id uuid.UUID, dto dtos.PatientDTO) error {\n\tresult := r.db.Model(&entities.Patient{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"patient update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"patient not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *PatientRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Patient{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"patient delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"patient not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> entities\n\n// domain/entities/patient.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Patient represents the patients database table.\ntype Patient struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID      `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tName           string         `gorm:\"type:varchar(255);not null\" json:\"name\" validate:\"required\"`\n\tContact        string         `gorm:\"type:varchar(50);not null\" json:\"contact\" validate:\"required\"`\n\tCPF            string         `gorm:\"type:varchar(14);uniqueIndex\" json:\"cpf,omitempty\"`\n\tSSN            string         `gorm:\"type:varchar(11);uniqueIndex\" json:\"ssn,omitempty\"`\n\tDOB            time.Time      `gorm:\"type:date\" json:\"dob\"`\n\tGender         string         `gorm:\"type:varchar(20)\" json:\"gender,omitempty\"`\n\tAddress        string         `gorm:\"type:text\" json:\"address,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Patient) TableName() string { return \"patients\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Patient) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> contracts\n\n// domain/repositories/contracts/patientRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// PatientRepository defines the persistence contract for Patient entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype PatientRepository interface {\n\tCreate(dto dtos.PatientDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.PatientDTO, error)\n\tFindByCPF(cpf string) (*dtos.PatientDTO, error)\n\tList(page, limit int) ([]dtos.PatientDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.PatientDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> repositories\n\n// infra/repositories/patientRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// PatientRepositoryImpl implements contracts.PatientRepository using GORM.\ntype PatientRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewPatientRepository constructs a new PatientRepositoryImpl.\nfunc NewPatientRepository(db *gorm.DB) *PatientRepositoryImpl {\n\treturn &PatientRepositoryImpl{db: db}\n}\n\nfunc (r *PatientRepositoryImpl) Create(dto dtos.PatientDTO) (uuid.UUID, error) {\n\tentity := entities.Patient{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"patient create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *PatientRepositoryImpl) FindByID(id uuid.UUID) (*dtos.PatientDTO, error) {\n\tvar entity entities.Patient\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"patient not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"patient find: %w\", err)\n\t}\n\tdto := dtos.PatientDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *PatientRepositoryImpl) FindByCPF(cpf string) (*dtos.PatientDTO, error) {\n\tvar entity entities.Patient\n\tif err := r.db.Where(\"cpf = ?\", cpf).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"patient with cpf=%s not found\", cpf)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"patient find by cpf: %w\", err)\n\t}\n\tdto := dtos.PatientDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *PatientRepositoryImpl) List(page, limit int) ([]dtos.PatientDTO, error) {\n\tvar entities []entities.Patient\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"patient list: %w\", err)\n\t}\n\tdtos := make([]dtos.PatientDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *PatientRepositoryImpl) Update(id uuid.UUID, dto dtos.PatientDTO) error {\n\tresult := r.db.Model(&entities.Patient{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"patient update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"patient not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *PatientRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Patient{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"patient delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"patient not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> entities\n\n// domain/entities/patient.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Patient represents the patients database table.\ntype Patient struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID      `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tName           string         `gorm:\"type:varchar(255);not null\" json:\"name\" validate:\"required\"`\n\tContact        string         `gorm:\"type:varchar(50);not null\" json:\"contact\" validate:\"required\"`\n\tCPF            string         `gorm:\"type:varchar(14);uniqueIndex\" json:\"cpf,omitempty\"`\n\tSSN            string         `gorm:\"type:varchar(11);uniqueIndex\" json:\"ssn,omitempty\"`\n\tDOB            time.Time      `gorm:\"type:date\" json:\"dob\"`\n\tGender         string         `gorm:\"type:varchar(20)\" json:\"gender,omitempty\"`\n\tAddress        string         `gorm:\"type:text\" json:\"address,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Patient) TableName() string { return \"patients\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Patient) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> contracts\n\n// domain/repositories/contracts/patientRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// PatientRepository defines the persistence contract for Patient entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype PatientRepository interface {\n\tCreate(dto dtos.PatientDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.PatientDTO, error)\n\tFindByCPF(cpf string) (*dtos.PatientDTO, error)\n\tList(page, limit int) ([]dtos.PatientDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.PatientDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> repositories\n\n// infra/repositories/patientRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// PatientRepositoryImpl implements contracts.PatientRepository using GORM.\ntype PatientRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewPatientRepository constructs a new PatientRepositoryImpl.\nfunc NewPatientRepository(db *gorm.DB) *PatientRepositoryImpl {\n\treturn &PatientRepositoryImpl{db: db}\n}\n\nfunc (r *PatientRepositoryImpl) Create(dto dtos.PatientDTO) (uuid.UUID, error) {\n\tentity := entities.Patient{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"patient create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *PatientRepositoryImpl) FindByID(id uuid.UUID) (*dtos.PatientDTO, error) {\n\tvar entity entities.Patient\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"patient not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"patient find: %w\", err)\n\t}\n\tdto := dtos.PatientDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *PatientRepositoryImpl) FindByCPF(cpf string) (*dtos.PatientDTO, error) {\n\tvar entity entities.Patient\n\tif err := r.db.Where(\"cpf = ?\", cpf).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"patient with cpf=%s not found\", cpf)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"patient find by cpf: %w\", err)\n\t}\n\tdto := dtos.PatientDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *PatientRepositoryImpl) List(page, limit int) ([]dtos.PatientDTO, error) {\n\tvar entities []entities.Patient\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"patient list: %w\", err)\n\t}\n\tdtos := make([]dtos.PatientDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *PatientRepositoryImpl) Update(id uuid.UUID, dto dtos.PatientDTO) error {\n\tresult := r.db.Model(&entities.Patient{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"patient update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"patient not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *PatientRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Patient{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"patient delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"patient not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> entities\n\n// domain/entities/doctor.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Doctor represents the doctors database table.\ntype Doctor struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tFullName       string    `gorm:\"type:varchar(255);not null\" json:\"full_name\" validate:\"required\"`\n\tCPF            string    `gorm:\"type:varchar(14);uniqueIndex\" json:\"cpf\"`\n\tCRM            string    `gorm:\"type:varchar(20);uniqueIndex\" json:\"crm\"`\n\tSpecialty      string    `gorm:\"type:varchar(100);not null\" json:\"specialty\" validate:\"required\"`\n\tEmail          string    `gorm:\"type:varchar(255);uniqueIndex\" json:\"email\" validate:\"required,email\"`\n\tPhone          string    `gorm:\"type:varchar(20)\" json:\"phone,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Doctor) TableName() string { return \"doctors\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Doctor) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> contracts\n\n// domain/repositories/contracts/doctorRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// DoctorRepository defines the persistence contract for Doctor entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype DoctorRepository interface {\n\tCreate(dto dtos.DoctorDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.DoctorDTO, error)\n\tFindByCRM(crm string) (*dtos.DoctorDTO, error)\n\tList(page, limit int) ([]dtos.DoctorDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.DoctorDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> repositories\n\n// infra/repositories/doctorRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// DoctorRepositoryImpl implements contracts.DoctorRepository using GORM.\ntype DoctorRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewDoctorRepository constructs a new DoctorRepositoryImpl.\nfunc NewDoctorRepository(db *gorm.DB) *DoctorRepositoryImpl {\n\treturn &DoctorRepositoryImpl{db: db}\n}\n\nfunc (r *DoctorRepositoryImpl) Create(dto dtos.DoctorDTO) (uuid.UUID, error) {\n\tentity := entities.Doctor{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"doctor create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *DoctorRepositoryImpl) FindByID(id uuid.UUID) (*dtos.DoctorDTO, error) {\n\tvar entity entities.Doctor\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"doctor not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"doctor find: %w\", err)\n\t}\n\tdto := dtos.DoctorDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *DoctorRepositoryImpl) FindByCRM(crm string) (*dtos.DoctorDTO, error) {\n\tvar entity entities.Doctor\n\tif err := r.db.Where(\"crm = ?\", crm).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"doctor with crm=%s not found\", crm)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"doctor find by crm: %w\", err)\n\t}\n\tdto := dtos.DoctorDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *DoctorRepositoryImpl) List(page, limit int) ([]dtos.DoctorDTO, error) {\n\tvar entities []entities.Doctor\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"doctor list: %w\", err)\n\t}\n\tdtos := make([]dtos.DoctorDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *DoctorRepositoryImpl) Update(id uuid.UUID, dto dtos.DoctorDTO) error {\n\tresult := r.db.Model(&entities.Doctor{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"doctor update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"doctor not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *DoctorRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Doctor{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"doctor delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"doctor not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> entities\n\n// domain/entities/doctor.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Doctor represents the doctors database table.\ntype Doctor struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tFullName       string    `gorm:\"type:varchar(255);not null\" json:\"full_name\" validate:\"required\"`\n\tCPF            string    `gorm:\"type:varchar(14);uniqueIndex\" json:\"cpf\"`\n\tCRM            string    `gorm:\"type:varchar(20);uniqueIndex\" json:\"crm\"`\n\tSpecialty      string    `gorm:\"type:varchar(100);not null\" json:\"specialty\" validate:\"required\"`\n\tEmail          string    `gorm:\"type:varchar(255);uniqueIndex\" json:\"email\" validate:\"required,email\"`\n\tPhone          string    `gorm:\"type:varchar(20)\" json:\"phone,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Doctor) TableName() string { return \"doctors\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Doctor) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> contracts\n\n// domain/repositories/contracts/doctorRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// DoctorRepository defines the persistence contract for Doctor entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype DoctorRepository interface {\n\tCreate(dto dtos.DoctorDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.DoctorDTO, error)\n\tFindByCRM(crm string) (*dtos.DoctorDTO, error)\n\tList(page, limit int) ([]dtos.DoctorDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.DoctorDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> repositories\n\n// infra/repositories/doctorRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// DoctorRepositoryImpl implements contracts.DoctorRepository using GORM.\ntype DoctorRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewDoctorRepository constructs a new DoctorRepositoryImpl.\nfunc NewDoctorRepository(db *gorm.DB) *DoctorRepositoryImpl {\n\treturn &DoctorRepositoryImpl{db: db}\n}\n\nfunc (r *DoctorRepositoryImpl) Create(dto dtos.DoctorDTO) (uuid.UUID, error) {\n\tentity := entities.Doctor{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"doctor create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *DoctorRepositoryImpl) FindByID(id uuid.UUID) (*dtos.DoctorDTO, error) {\n\tvar entity entities.Doctor\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"doctor not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"doctor find: %w\", err)\n\t}\n\tdto := dtos.DoctorDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *DoctorRepositoryImpl) FindByCRM(crm string) (*dtos.DoctorDTO, error) {\n\tvar entity entities.Doctor\n\tif err := r.db.Where(\"crm = ?\", crm).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"doctor with crm=%s not found\", crm)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"doctor find by crm: %w\", err)\n\t}\n\tdto := dtos.DoctorDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *DoctorRepositoryImpl) List(page, limit int) ([]dtos.DoctorDTO, error) {\n\tvar entities []entities.Doctor\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"doctor list: %w\", err)\n\t}\n\tdtos := make([]dtos.DoctorDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *DoctorRepositoryImpl) Update(id uuid.UUID, dto dtos.DoctorDTO) error {\n\tresult := r.db.Model(&entities.Doctor{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"doctor update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"doctor not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *DoctorRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Doctor{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"doctor delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"doctor not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> entities\n\n// domain/entities/doctor.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Doctor represents the doctors database table.\ntype Doctor struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tFullName       string    `gorm:\"type:varchar(255);not null\" json:\"full_name\" validate:\"required\"`\n\tCPF            string    `gorm:\"type:varchar(14);uniqueIndex\" json:\"cpf\"`\n\tCRM            string    `gorm:\"type:varchar(20);uniqueIndex\" json:\"crm\"`\n\tSpecialty      string    `gorm:\"type:varchar(100);not null\" json:\"specialty\" validate:\"required\"`\n\tEmail          string    `gorm:\"type:varchar(255);uniqueIndex\" json:\"email\" validate:\"required,email\"`\n\tPhone          string    `gorm:\"type:varchar(20)\" json:\"phone,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Doctor) TableName() string { return \"doctors\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Doctor) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> contracts\n\n// domain/repositories/contracts/doctorRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// DoctorRepository defines the persistence contract for Doctor entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype DoctorRepository interface {\n\tCreate(dto dtos.DoctorDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.DoctorDTO, error)\n\tFindByCRM(crm string) (*dtos.DoctorDTO, error)\n\tList(page, limit int) ([]dtos.DoctorDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.DoctorDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> repositories\n\n// infra/repositories/doctorRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// DoctorRepositoryImpl implements contracts.DoctorRepository using GORM.\ntype DoctorRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewDoctorRepository constructs a new DoctorRepositoryImpl.\nfunc NewDoctorRepository(db *gorm.DB) *DoctorRepositoryImpl {\n\treturn &DoctorRepositoryImpl{db: db}\n}\n\nfunc (r *DoctorRepositoryImpl) Create(dto dtos.DoctorDTO) (uuid.UUID, error) {\n\tentity := entities.Doctor{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"doctor create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *DoctorRepositoryImpl) FindByID(id uuid.UUID) (*dtos.DoctorDTO, error) {\n\tvar entity entities.Doctor\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"doctor not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"doctor find: %w\", err)\n\t}\n\tdto := dtos.DoctorDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *DoctorRepositoryImpl) FindByCRM(crm string) (*dtos.DoctorDTO, error) {\n\tvar entity entities.Doctor\n\tif err := r.db.Where(\"crm = ?\", crm).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"doctor with crm=%s not found\", crm)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"doctor find by crm: %w\", err)\n\t}\n\tdto := dtos.DoctorDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *DoctorRepositoryImpl) List(page, limit int) ([]dtos.DoctorDTO, error) {\n\tvar entities []entities.Doctor\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"doctor list: %w\", err)\n\t}\n\tdtos := make([]dtos.DoctorDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *DoctorRepositoryImpl) Update(id uuid.UUID, dto dtos.DoctorDTO) error {\n\tresult := r.db.Model(&entities.Doctor{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"doctor update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"doctor not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *DoctorRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Doctor{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"doctor delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"doctor not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> entities\n\n// domain/entities/doctor.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Doctor represents the doctors database table.\ntype Doctor struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tFullName       string    `gorm:\"type:varchar(255);not null\" json:\"full_name\" validate:\"required\"`\n\tCPF            string    `gorm:\"type:varchar(14);uniqueIndex\" json:\"cpf\"`\n\tCRM            string    `gorm:\"type:varchar(20);uniqueIndex\" json:\"crm\"`\n\tSpecialty      string    `gorm:\"type:varchar(100);not null\" json:\"specialty\" validate:\"required\"`\n\tEmail          string    `gorm:\"type:varchar(255);uniqueIndex\" json:\"email\" validate:\"required,email\"`\n\tPhone          string    `gorm:\"type:varchar(20)\" json:\"phone,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Doctor) TableName() string { return \"doctors\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Doctor) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> contracts\n\n// domain/repositories/contracts/doctorRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// DoctorRepository defines the persistence contract for Doctor entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype DoctorRepository interface {\n\tCreate(dto dtos.DoctorDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.DoctorDTO, error)\n\tFindByCRM(crm string) (*dtos.DoctorDTO, error)\n\tList(page, limit int) ([]dtos.DoctorDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.DoctorDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> repositories\n\n// infra/repositories/doctorRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// DoctorRepositoryImpl implements contracts.DoctorRepository using GORM.\ntype DoctorRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewDoctorRepository constructs a new DoctorRepositoryImpl.\nfunc NewDoctorRepository(db *gorm.DB) *DoctorRepositoryImpl {\n\treturn &DoctorRepositoryImpl{db: db}\n}\n\nfunc (r *DoctorRepositoryImpl) Create(dto dtos.DoctorDTO) (uuid.UUID, error) {\n\tentity := entities.Doctor{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"doctor create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *DoctorRepositoryImpl) FindByID(id uuid.UUID) (*dtos.DoctorDTO, error) {\n\tvar entity entities.Doctor\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"doctor not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"doctor find: %w\", err)\n\t}\n\tdto := dtos.DoctorDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *DoctorRepositoryImpl) FindByCRM(crm string) (*dtos.DoctorDTO, error) {\n\tvar entity entities.Doctor\n\tif err := r.db.Where(\"crm = ?\", crm).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"doctor with crm=%s not found\", crm)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"doctor find by crm: %w\", err)\n\t}\n\tdto := dtos.DoctorDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *DoctorRepositoryImpl) List(page, limit int) ([]dtos.DoctorDTO, error) {\n\tvar entities []entities.Doctor\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"doctor list: %w\", err)\n\t}\n\tdtos := make([]dtos.DoctorDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *DoctorRepositoryImpl) Update(id uuid.UUID, dto dtos.DoctorDTO) error {\n\tresult := r.db.Model(&entities.Doctor{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"doctor update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"doctor not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *DoctorRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Doctor{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"doctor delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"doctor not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> entities\n\n// domain/entities/appointment.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Appointment represents the appointments database table.\ntype Appointment struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID  uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tPatientID       uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"patient_id\"`\n\tDoctorID        uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"doctor_id\"`\n\tUserID          uuid.UUID  `gorm:\"type:uuid;not null\" json:\"user_id\"`\n\tSpecialization  string     `gorm:\"type:varchar(100);not null\" json:\"specialization\"`\n\tDateTime        time.Time  `gorm:\"type:timestamptz;not null\" json:\"date_time\"`\n\tStatus          string     `gorm:\"type:varchar(50);default:scheduled\" json:\"status\"`\n\tNotes           string     `gorm:\"type:text\" json:\"notes,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Appointment) TableName() string { return \"appointments\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Appointment) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> contracts\n\n// domain/repositories/contracts/appointmentRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// AppointmentRepository defines the persistence contract for Appointment entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype AppointmentRepository interface {\n\tCreate(dto dtos.AppointmentDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.AppointmentDTO, error)\n\tFindByStatus(status string) (*dtos.AppointmentDTO, error)\n\tList(page, limit int) ([]dtos.AppointmentDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.AppointmentDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> repositories\n\n// infra/repositories/appointmentRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// AppointmentRepositoryImpl implements contracts.AppointmentRepository using GORM.\ntype AppointmentRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewAppointmentRepository constructs a new AppointmentRepositoryImpl.\nfunc NewAppointmentRepository(db *gorm.DB) *AppointmentRepositoryImpl {\n\treturn &AppointmentRepositoryImpl{db: db}\n}\n\nfunc (r *AppointmentRepositoryImpl) Create(dto dtos.AppointmentDTO) (uuid.UUID, error) {\n\tentity := entities.Appointment{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"appointment create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) FindByID(id uuid.UUID) (*dtos.AppointmentDTO, error) {\n\tvar entity entities.Appointment\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"appointment not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"appointment find: %w\", err)\n\t}\n\tdto := dtos.AppointmentDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) FindByStatus(status string) (*dtos.AppointmentDTO, error) {\n\tvar entity entities.Appointment\n\tif err := r.db.Where(\"status = ?\", status).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"appointment with status=%s not found\", status)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"appointment find by status: %w\", err)\n\t}\n\tdto := dtos.AppointmentDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) List(page, limit int) ([]dtos.AppointmentDTO, error) {\n\tvar entities []entities.Appointment\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"appointment list: %w\", err)\n\t}\n\tdtos := make([]dtos.AppointmentDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) Update(id uuid.UUID, dto dtos.AppointmentDTO) error {\n\tresult := r.db.Model(&entities.Appointment{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"appointment update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"appointment not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *AppointmentRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Appointment{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"appointment delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"appointment not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> entities\n\n// domain/entities/appointment.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Appointment represents the appointments database table.\ntype Appointment struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID  uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tPatientID       uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"patient_id\"`\n\tDoctorID        uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"doctor_id\"`\n\tUserID          uuid.UUID  `gorm:\"type:uuid;not null\" json:\"user_id\"`\n\tSpecialization  string     `gorm:\"type:varchar(100);not null\" json:\"specialization\"`\n\tDateTime        time.Time  `gorm:\"type:timestamptz;not null\" json:\"date_time\"`\n\tStatus          string     `gorm:\"type:varchar(50);default:scheduled\" json:\"status\"`\n\tNotes           string     `gorm:\"type:text\" json:\"notes,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Appointment) TableName() string { return \"appointments\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Appointment) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> contracts\n\n// domain/repositories/contracts/appointmentRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// AppointmentRepository defines the persistence contract for Appointment entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype AppointmentRepository interface {\n\tCreate(dto dtos.AppointmentDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.AppointmentDTO, error)\n\tFindByStatus(status string) (*dtos.AppointmentDTO, error)\n\tList(page, limit int) ([]dtos.AppointmentDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.AppointmentDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> repositories\n\n// infra/repositories/appointmentRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// AppointmentRepositoryImpl implements contracts.AppointmentRepository using GORM.\ntype AppointmentRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewAppointmentRepository constructs a new AppointmentRepositoryImpl.\nfunc NewAppointmentRepository(db *gorm.DB) *AppointmentRepositoryImpl {\n\treturn &AppointmentRepositoryImpl{db: db}\n}\n\nfunc (r *AppointmentRepositoryImpl) Create(dto dtos.AppointmentDTO) (uuid.UUID, error) {\n\tentity := entities.Appointment{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"appointment create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) FindByID(id uuid.UUID) (*dtos.AppointmentDTO, error) {\n\tvar entity entities.Appointment\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"appointment not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"appointment find: %w\", err)\n\t}\n\tdto := dtos.AppointmentDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) FindByStatus(status string) (*dtos.AppointmentDTO, error) {\n\tvar entity entities.Appointment\n\tif err := r.db.Where(\"status = ?\", status).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"appointment with status=%s not found\", status)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"appointment find by status: %w\", err)\n\t}\n\tdto := dtos.AppointmentDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) List(page, limit int) ([]dtos.AppointmentDTO, error) {\n\tvar entities []entities.Appointment\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"appointment list: %w\", err)\n\t}\n\tdtos := make([]dtos.AppointmentDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) Update(id uuid.UUID, dto dtos.AppointmentDTO) error {\n\tresult := r.db.Model(&entities.Appointment{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"appointment update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"appointment not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *AppointmentRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Appointment{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"appointment delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"appointment not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> entities\n\n// domain/entities/appointment.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Appointment represents the appointments database table.\ntype Appointment struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID  uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tPatientID       uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"patient_id\"`\n\tDoctorID        uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"doctor_id\"`\n\tUserID          uuid.UUID  `gorm:\"type:uuid;not null\" json:\"user_id\"`\n\tSpecialization  string     `gorm:\"type:varchar(100);not null\" json:\"specialization\"`\n\tDateTime        time.Time  `gorm:\"type:timestamptz;not null\" json:\"date_time\"`\n\tStatus          string     `gorm:\"type:varchar(50);default:scheduled\" json:\"status\"`\n\tNotes           string     `gorm:\"type:text\" json:\"notes,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Appointment) TableName() string { return \"appointments\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Appointment) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> contracts\n\n// domain/repositories/contracts/appointmentRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// AppointmentRepository defines the persistence contract for Appointment entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype AppointmentRepository interface {\n\tCreate(dto dtos.AppointmentDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.AppointmentDTO, error)\n\tFindByStatus(status string) (*dtos.AppointmentDTO, error)\n\tList(page, limit int) ([]dtos.AppointmentDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.AppointmentDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> repositories\n\n// infra/repositories/appointmentRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// AppointmentRepositoryImpl implements contracts.AppointmentRepository using GORM.\ntype AppointmentRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewAppointmentRepository constructs a new AppointmentRepositoryImpl.\nfunc NewAppointmentRepository(db *gorm.DB) *AppointmentRepositoryImpl {\n\treturn &AppointmentRepositoryImpl{db: db}\n}\n\nfunc (r *AppointmentRepositoryImpl) Create(dto dtos.AppointmentDTO) (uuid.UUID, error) {\n\tentity := entities.Appointment{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"appointment create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) FindByID(id uuid.UUID) (*dtos.AppointmentDTO, error) {\n\tvar entity entities.Appointment\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"appointment not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"appointment find: %w\", err)\n\t}\n\tdto := dtos.AppointmentDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) FindByStatus(status string) (*dtos.AppointmentDTO, error) {\n\tvar entity entities.Appointment\n\tif err := r.db.Where(\"status = ?\", status).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"appointment with status=%s not found\", status)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"appointment find by status: %w\", err)\n\t}\n\tdto := dtos.AppointmentDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) List(page, limit int) ([]dtos.AppointmentDTO, error) {\n\tvar entities []entities.Appointment\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"appointment list: %w\", err)\n\t}\n\tdtos := make([]dtos.AppointmentDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) Update(id uuid.UUID, dto dtos.AppointmentDTO) error {\n\tresult := r.db.Model(&entities.Appointment{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"appointment update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"appointment not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *AppointmentRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Appointment{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"appointment delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"appointment not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> entities\n\n// domain/entities/appointment.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// Appointment represents the appointments database table.\ntype Appointment struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID  uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tPatientID       uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"patient_id\"`\n\tDoctorID        uuid.UUID  `gorm:\"type:uuid;not null;index\" json:\"doctor_id\"`\n\tUserID          uuid.UUID  `gorm:\"type:uuid;not null\" json:\"user_id\"`\n\tSpecialization  string     `gorm:\"type:varchar(100);not null\" json:\"specialization\"`\n\tDateTime        time.Time  `gorm:\"type:timestamptz;not null\" json:\"date_time\"`\n\tStatus          string     `gorm:\"type:varchar(50);default:scheduled\" json:\"status\"`\n\tNotes           string     `gorm:\"type:text\" json:\"notes,omitempty\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (Appointment) TableName() string { return \"appointments\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *Appointment) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> contracts\n\n// domain/repositories/contracts/appointmentRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// AppointmentRepository defines the persistence contract for Appointment entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype AppointmentRepository interface {\n\tCreate(dto dtos.AppointmentDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.AppointmentDTO, error)\n\tFindByStatus(status string) (*dtos.AppointmentDTO, error)\n\tList(page, limit int) ([]dtos.AppointmentDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.AppointmentDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> repositories\n\n// infra/repositories/appointmentRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// AppointmentRepositoryImpl implements contracts.AppointmentRepository using GORM.\ntype AppointmentRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewAppointmentRepository constructs a new AppointmentRepositoryImpl.\nfunc NewAppointmentRepository(db *gorm.DB) *AppointmentRepositoryImpl {\n\treturn &AppointmentRepositoryImpl{db: db}\n}\n\nfunc (r *AppointmentRepositoryImpl) Create(dto dtos.AppointmentDTO) (uuid.UUID, error) {\n\tentity := entities.Appointment{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"appointment create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) FindByID(id uuid.UUID) (*dtos.AppointmentDTO, error) {\n\tvar entity entities.Appointment\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"appointment not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"appointment find: %w\", err)\n\t}\n\tdto := dtos.AppointmentDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) FindByStatus(status string) (*dtos.AppointmentDTO, error) {\n\tvar entity entities.Appointment\n\tif err := r.db.Where(\"status = ?\", status).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"appointment with status=%s not found\", status)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"appointment find by status: %w\", err)\n\t}\n\tdto := dtos.AppointmentDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) List(page, limit int) ([]dtos.AppointmentDTO, error) {\n\tvar entities []entities.Appointment\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"appointment list: %w\", err)\n\t}\n\tdtos := make([]dtos.AppointmentDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *AppointmentRepositoryImpl) Update(id uuid.UUID, dto dtos.AppointmentDTO) error {\n\tresult := r.db.Model(&entities.Appointment{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"appointment update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"appointment not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *AppointmentRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.Appointment{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"appointment delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"appointment not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> entities\n\n// domain/entities/user.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// User represents the users database table.\ntype User struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tName           string    `gorm:\"type:varchar(255);not null\" json:\"name\" validate:\"required\"`\n\tEmail          string    `gorm:\"type:varchar(255);uniqueIndex;not null\" json:\"email\" validate:\"required,email\"`\n\tPassword       string    `gorm:\"type:varchar(255);not null\" json:\"-\"` // never serialised\n\tRole           string    `gorm:\"type:varchar(50);not null;default:user\" json:\"role\" validate:\"required,oneof=admin user doctor nurse\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (User) TableName() string { return \"users\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *User) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> contracts\n\n// domain/repositories/contracts/userRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// UserRepository defines the persistence contract for User entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype UserRepository interface {\n\tCreate(dto dtos.UserDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.UserDTO, error)\n\tFindByEmail(email string) (*dtos.UserDTO, error)\n\tList(page, limit int) ([]dtos.UserDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.UserDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> repositories\n\n// infra/repositories/userRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// UserRepositoryImpl implements contracts.UserRepository using GORM.\ntype UserRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewUserRepository constructs a new UserRepositoryImpl.\nfunc NewUserRepository(db *gorm.DB) *UserRepositoryImpl {\n\treturn &UserRepositoryImpl{db: db}\n}\n\nfunc (r *UserRepositoryImpl) Create(dto dtos.UserDTO) (uuid.UUID, error) {\n\tentity := entities.User{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"user create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *UserRepositoryImpl) FindByID(id uuid.UUID) (*dtos.UserDTO, error) {\n\tvar entity entities.User\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"user not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"user find: %w\", err)\n\t}\n\tdto := dtos.UserDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *UserRepositoryImpl) FindByEmail(email string) (*dtos.UserDTO, error) {\n\tvar entity entities.User\n\tif err := r.db.Where(\"email = ?\", email).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"user with email=%s not found\", email)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"user find by email: %w\", err)\n\t}\n\tdto := dtos.UserDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *UserRepositoryImpl) List(page, limit int) ([]dtos.UserDTO, error) {\n\tvar entities []entities.User\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"user list: %w\", err)\n\t}\n\tdtos := make([]dtos.UserDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *UserRepositoryImpl) Update(id uuid.UUID, dto dtos.UserDTO) error {\n\tresult := r.db.Model(&entities.User{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"user update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"user not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *UserRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.User{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"user delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"user not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> entities\n\n// domain/entities/user.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// User represents the users database table.\ntype User struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tName           string    `gorm:\"type:varchar(255);not null\" json:\"name\" validate:\"required\"`\n\tEmail          string    `gorm:\"type:varchar(255);uniqueIndex;not null\" json:\"email\" validate:\"required,email\"`\n\tPassword       string    `gorm:\"type:varchar(255);not null\" json:\"-\"` // never serialised\n\tRole           string    `gorm:\"type:varchar(50);not null;default:user\" json:\"role\" validate:\"required,oneof=admin user doctor nurse\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (User) TableName() string { return \"users\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *User) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> contracts\n\n// domain/repositories/contracts/userRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// UserRepository defines the persistence contract for User entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype UserRepository interface {\n\tCreate(dto dtos.UserDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.UserDTO, error)\n\tFindByEmail(email string) (*dtos.UserDTO, error)\n\tList(page, limit int) ([]dtos.UserDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.UserDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> repositories\n\n// infra/repositories/userRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// UserRepositoryImpl implements contracts.UserRepository using GORM.\ntype UserRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewUserRepository constructs a new UserRepositoryImpl.\nfunc NewUserRepository(db *gorm.DB) *UserRepositoryImpl {\n\treturn &UserRepositoryImpl{db: db}\n}\n\nfunc (r *UserRepositoryImpl) Create(dto dtos.UserDTO) (uuid.UUID, error) {\n\tentity := entities.User{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"user create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *UserRepositoryImpl) FindByID(id uuid.UUID) (*dtos.UserDTO, error) {\n\tvar entity entities.User\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"user not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"user find: %w\", err)\n\t}\n\tdto := dtos.UserDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *UserRepositoryImpl) FindByEmail(email string) (*dtos.UserDTO, error) {\n\tvar entity entities.User\n\tif err := r.db.Where(\"email = ?\", email).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"user with email=%s not found\", email)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"user find by email: %w\", err)\n\t}\n\tdto := dtos.UserDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *UserRepositoryImpl) List(page, limit int) ([]dtos.UserDTO, error) {\n\tvar entities []entities.User\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"user list: %w\", err)\n\t}\n\tdtos := make([]dtos.UserDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *UserRepositoryImpl) Update(id uuid.UUID, dto dtos.UserDTO) error {\n\tresult := r.db.Model(&entities.User{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"user update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"user not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *UserRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.User{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"user delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"user not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> entities\n\n// domain/entities/user.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// User represents the users database table.\ntype User struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tName           string    `gorm:\"type:varchar(255);not null\" json:\"name\" validate:\"required\"`\n\tEmail          string    `gorm:\"type:varchar(255);uniqueIndex;not null\" json:\"email\" validate:\"required,email\"`\n\tPassword       string    `gorm:\"type:varchar(255);not null\" json:\"-\"` // never serialised\n\tRole           string    `gorm:\"type:varchar(50);not null;default:user\" json:\"role\" validate:\"required,oneof=admin user doctor nurse\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (User) TableName() string { return \"users\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *User) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> contracts\n\n// domain/repositories/contracts/userRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// UserRepository defines the persistence contract for User entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype UserRepository interface {\n\tCreate(dto dtos.UserDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.UserDTO, error)\n\tFindByEmail(email string) (*dtos.UserDTO, error)\n\tList(page, limit int) ([]dtos.UserDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.UserDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> repositories\n\n// infra/repositories/userRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// UserRepositoryImpl implements contracts.UserRepository using GORM.\ntype UserRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewUserRepository constructs a new UserRepositoryImpl.\nfunc NewUserRepository(db *gorm.DB) *UserRepositoryImpl {\n\treturn &UserRepositoryImpl{db: db}\n}\n\nfunc (r *UserRepositoryImpl) Create(dto dtos.UserDTO) (uuid.UUID, error) {\n\tentity := entities.User{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"user create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *UserRepositoryImpl) FindByID(id uuid.UUID) (*dtos.UserDTO, error) {\n\tvar entity entities.User\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"user not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"user find: %w\", err)\n\t}\n\tdto := dtos.UserDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *UserRepositoryImpl) FindByEmail(email string) (*dtos.UserDTO, error) {\n\tvar entity entities.User\n\tif err := r.db.Where(\"email = ?\", email).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"user with email=%s not found\", email)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"user find by email: %w\", err)\n\t}\n\tdto := dtos.UserDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *UserRepositoryImpl) List(page, limit int) ([]dtos.UserDTO, error) {\n\tvar entities []entities.User\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"user list: %w\", err)\n\t}\n\tdtos := make([]dtos.UserDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *UserRepositoryImpl) Update(id uuid.UUID, dto dtos.UserDTO) error {\n\tresult := r.db.Model(&entities.User{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"user update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"user not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *UserRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.User{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"user delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"user not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> entities\n\n// domain/entities/user.go\n// Pattern: GORM entity with UUID PK + soft delete + JSON/validate tags\n// Observed in: Medical-App-Core/domain/entities/\npackage entities\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// User represents the users database table.\ntype User struct {\n\tID        uuid.UUID      `gorm:\"type:uuid;primaryKey;default:gen_random_uuid()\" json:\"id\"`\n\tCreatedAt time.Time      `gorm:\"autoCreateTime\" json:\"created_at\"`\n\tUpdatedAt time.Time      `gorm:\"autoUpdateTime\" json:\"updated_at\"`\n\tDeletedAt gorm.DeletedAt `gorm:\"index\" json:\"-\"` // soft delete\n\tOrganizationID uuid.UUID `gorm:\"type:uuid;not null;index\" json:\"organization_id\"`\n\tName           string    `gorm:\"type:varchar(255);not null\" json:\"name\" validate:\"required\"`\n\tEmail          string    `gorm:\"type:varchar(255);uniqueIndex;not null\" json:\"email\" validate:\"required,email\"`\n\tPassword       string    `gorm:\"type:varchar(255);not null\" json:\"-\"` // never serialised\n\tRole           string    `gorm:\"type:varchar(50);not null;default:user\" json:\"role\" validate:\"required,oneof=admin user doctor nurse\"`\n}\n\n// TableName overrides GORM's convention-based table name.\nfunc (User) TableName() string { return \"users\" }\n\n// BeforeCreate sets a UUID before the record is inserted.\nfunc (e *User) BeforeCreate(tx *gorm.DB) error {\n\tif e.ID == uuid.Nil {\n\t\te.ID = uuid.New()\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> contracts\n\n// domain/repositories/contracts/userRepository.go\n// Pattern: repository interface (contract) β€” domain layer knows nothing about GORM\n// Observed in: Medical-App-Core/domain/repositories/contracts/\npackage contracts\n\nimport (\n\t\"medical-sas-api/domain/dtos\"\n\t\"github.com/google/uuid\"\n)\n\n// UserRepository defines the persistence contract for User entities.\n// Implementations live in infra/repositories/ and depend on GORM or any other ORM.\ntype UserRepository interface {\n\tCreate(dto dtos.UserDTO) (uuid.UUID, error)\n\tFindByID(id uuid.UUID) (*dtos.UserDTO, error)\n\tFindByEmail(email string) (*dtos.UserDTO, error)\n\tList(page, limit int) ([]dtos.UserDTO, error)\n\tUpdate(id uuid.UUID, dto dtos.UserDTO) error\n\tDelete(id uuid.UUID) error // soft delete\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> repositories\n\n// infra/repositories/userRepository.go\n// Pattern: GORM implementation of the repository interface\n// Observed in: Medical-App-Core/infra/repositories/\npackage repositories\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/dtos\"\n\t\"medical-sas-api/domain/entities\"\n\t\"github.com/google/uuid\"\n\t\"gorm.io/gorm\"\n)\n\n// UserRepositoryImpl implements contracts.UserRepository using GORM.\ntype UserRepositoryImpl struct {\n\tdb *gorm.DB\n}\n\n// NewUserRepository constructs a new UserRepositoryImpl.\nfunc NewUserRepository(db *gorm.DB) *UserRepositoryImpl {\n\treturn &UserRepositoryImpl{db: db}\n}\n\nfunc (r *UserRepositoryImpl) Create(dto dtos.UserDTO) (uuid.UUID, error) {\n\tentity := entities.User{} // map DTO β†’ entity fields\n\t// (field mapping omitted for brevity β€” use a mapper or manual assignment)\n\tif err := r.db.Create(&entity).Error; err != nil {\n\t\treturn uuid.Nil, fmt.Errorf(\"user create: %w\", err)\n\t}\n\treturn entity.ID, nil\n}\n\nfunc (r *UserRepositoryImpl) FindByID(id uuid.UUID) (*dtos.UserDTO, error) {\n\tvar entity entities.User\n\tif err := r.db.First(&entity, \"id = ?\", id).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"user not found: %s\", id)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"user find: %w\", err)\n\t}\n\tdto := dtos.UserDTO{} // map entity β†’ DTO\n\treturn &dto, nil\n}\n\nfunc (r *UserRepositoryImpl) FindByEmail(email string) (*dtos.UserDTO, error) {\n\tvar entity entities.User\n\tif err := r.db.Where(\"email = ?\", email).First(&entity).Error; err != nil {\n\t\tif err == gorm.ErrRecordNotFound {\n\t\t\treturn nil, fmt.Errorf(\"user with email=%s not found\", email)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"user find by email: %w\", err)\n\t}\n\tdto := dtos.UserDTO{}\n\treturn &dto, nil\n}\n\nfunc (r *UserRepositoryImpl) List(page, limit int) ([]dtos.UserDTO, error) {\n\tvar entities []entities.User\n\toffset := (page - 1) * limit\n\tif err := r.db.Offset(offset).Limit(limit).Find(&entities).Error; err != nil {\n\t\treturn nil, fmt.Errorf(\"user list: %w\", err)\n\t}\n\tdtos := make([]dtos.UserDTO, 0, len(entities))\n\t// map each entity to DTO\n\treturn dtos, nil\n}\n\nfunc (r *UserRepositoryImpl) Update(id uuid.UUID, dto dtos.UserDTO) error {\n\tresult := r.db.Model(&entities.User{}).Where(\"id = ?\", id).Updates(dto)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"user update: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"user not found: %s\", id)\n\t}\n\treturn nil\n}\n\nfunc (r *UserRepositoryImpl) Delete(id uuid.UUID) error {\n\t// GORM soft delete: sets deleted_at instead of removing the row\n\tresult := r.db.Delete(&entities.User{}, \"id = ?\", id)\n\tif result.Error != nil {\n\t\treturn fmt.Errorf(\"user delete: %w\", result.Error)\n\t}\n\tif result.RowsAffected == 0 {\n\t\treturn fmt.Errorf(\"user not found: %s\", id)\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> initializers\n\n// initializers/database.go\n// Pattern: GORM + PostgreSQL connection with pool config + env-based DSN\n// Observed in: Medical-App-Core/initializers/database.go\npackage initializers\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n\t\"gorm.io/gorm/logger\"\n)\n\n// InitialDB opens a PostgreSQL connection using environment variables.\n// Panics on failure β€” the app cannot run without a database.\nfunc InitialDB() *gorm.DB {\n\tdsn := buildDSN()\n\n\tdb, err := gorm.Open(postgres.Open(dsn), &gorm.Config{\n\t\tLogger: logger.Default.LogMode(logger.Info),\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"database connection failed: %v\", err)\n\t}\n\n\tsqlDB, err := db.DB()\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to get underlying sql.DB: %v\", err)\n\t}\n\tsqlDB.SetMaxOpenConns(25)\n\tsqlDB.SetMaxIdleConns(10)\n\tsqlDB.SetConnMaxLifetime(5 * time.Minute)\n\n\tlog.Println(\"database connected:\", maskDSN(dsn))\n\treturn db\n}\n\nfunc buildDSN() string {\n\treturn fmt.Sprintf(\n\t\t\"host=%s port=%s user=%s password=%s dbname=%s sslmode=%s TimeZone=%s\",\n\t\tgetEnv(\"DB_HOST\",     \"localhost\"),\n\t\tgetEnv(\"DB_PORT\",     \"5432\"),\n\t\tgetEnv(\"DB_USER\",     \"postgres\"),\n\t\tos.Getenv(\"DB_PASSWORD\"),\n\t\tgetEnv(\"DB_NAME\",     \"appdb\"),\n\t\tgetEnv(\"DB_SSLMODE\",  \"disable\"),\n\t\tgetEnv(\"DB_TIMEZONE\", \"UTC\"),\n\t)\n}\n\nfunc getEnv(key, fallback string) string {\n\tif v := os.Getenv(key); v != \"\" {\n\t\treturn v\n\t}\n\treturn fallback\n}\n\nfunc maskDSN(dsn string) string {\n\tpassword := os.Getenv(\"DB_PASSWORD\")\n\tif password == \"\" {\n\t\treturn dsn\n\t}\n\treturn strings.ReplaceAll(dsn, password, \"*****\")\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> initializers\n\n// initializers/database.go\n// Pattern: GORM + PostgreSQL connection with pool config + env-based DSN\n// Observed in: Medical-App-Core/initializers/database.go\npackage initializers\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n\t\"gorm.io/gorm/logger\"\n)\n\n// InitialDB opens a PostgreSQL connection using environment variables.\n// Panics on failure β€” the app cannot run without a database.\nfunc InitialDB() *gorm.DB {\n\tdsn := buildDSN()\n\n\tdb, err := gorm.Open(postgres.Open(dsn), &gorm.Config{\n\t\tLogger: logger.Default.LogMode(logger.Info),\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"database connection failed: %v\", err)\n\t}\n\n\tsqlDB, err := db.DB()\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to get underlying sql.DB: %v\", err)\n\t}\n\tsqlDB.SetMaxOpenConns(25)\n\tsqlDB.SetMaxIdleConns(10)\n\tsqlDB.SetConnMaxLifetime(5 * time.Minute)\n\n\tlog.Println(\"database connected:\", maskDSN(dsn))\n\treturn db\n}\n\nfunc buildDSN() string {\n\treturn fmt.Sprintf(\n\t\t\"host=%s port=%s user=%s password=%s dbname=%s sslmode=%s TimeZone=%s\",\n\t\tgetEnv(\"DB_HOST\",     \"localhost\"),\n\t\tgetEnv(\"DB_PORT\",     \"5432\"),\n\t\tgetEnv(\"DB_USER\",     \"postgres\"),\n\t\tos.Getenv(\"DB_PASSWORD\"),\n\t\tgetEnv(\"DB_NAME\",     \"appdb\"),\n\t\tgetEnv(\"DB_SSLMODE\",  \"disable\"),\n\t\tgetEnv(\"DB_TIMEZONE\", \"UTC\"),\n\t)\n}\n\nfunc getEnv(key, fallback string) string {\n\tif v := os.Getenv(key); v != \"\" {\n\t\treturn v\n\t}\n\treturn fallback\n}\n\nfunc maskDSN(dsn string) string {\n\tpassword := os.Getenv(\"DB_PASSWORD\")\n\tif password == \"\" {\n\t\treturn dsn\n\t}\n\treturn strings.ReplaceAll(dsn, password, \"*****\")\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> initializers\n\n// initializers/database.go\n// Pattern: GORM + PostgreSQL connection with pool config + env-based DSN\n// Observed in: Medical-App-Core/initializers/database.go\npackage initializers\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n\t\"gorm.io/gorm/logger\"\n)\n\n// InitialDB opens a PostgreSQL connection using environment variables.\n// Panics on failure β€” the app cannot run without a database.\nfunc InitialDB() *gorm.DB {\n\tdsn := buildDSN()\n\n\tdb, err := gorm.Open(postgres.Open(dsn), &gorm.Config{\n\t\tLogger: logger.Default.LogMode(logger.Info),\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"database connection failed: %v\", err)\n\t}\n\n\tsqlDB, err := db.DB()\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to get underlying sql.DB: %v\", err)\n\t}\n\tsqlDB.SetMaxOpenConns(25)\n\tsqlDB.SetMaxIdleConns(10)\n\tsqlDB.SetConnMaxLifetime(5 * time.Minute)\n\n\tlog.Println(\"database connected:\", maskDSN(dsn))\n\treturn db\n}\n\nfunc buildDSN() string {\n\treturn fmt.Sprintf(\n\t\t\"host=%s port=%s user=%s password=%s dbname=%s sslmode=%s TimeZone=%s\",\n\t\tgetEnv(\"DB_HOST\",     \"localhost\"),\n\t\tgetEnv(\"DB_PORT\",     \"5432\"),\n\t\tgetEnv(\"DB_USER\",     \"postgres\"),\n\t\tos.Getenv(\"DB_PASSWORD\"),\n\t\tgetEnv(\"DB_NAME\",     \"appdb\"),\n\t\tgetEnv(\"DB_SSLMODE\",  \"disable\"),\n\t\tgetEnv(\"DB_TIMEZONE\", \"UTC\"),\n\t)\n}\n\nfunc getEnv(key, fallback string) string {\n\tif v := os.Getenv(key); v != \"\" {\n\t\treturn v\n\t}\n\treturn fallback\n}\n\nfunc maskDSN(dsn string) string {\n\tpassword := os.Getenv(\"DB_PASSWORD\")\n\tif password == \"\" {\n\t\treturn dsn\n\t}\n\treturn strings.ReplaceAll(dsn, password, \"*****\")\n}\n</go_file>\n"}
{"category": "gorm", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> initializers\n\n// initializers/database.go\n// Pattern: GORM + PostgreSQL connection with pool config + env-based DSN\n// Observed in: Medical-App-Core/initializers/database.go\npackage initializers\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n\t\"gorm.io/gorm/logger\"\n)\n\n// InitialDB opens a PostgreSQL connection using environment variables.\n// Panics on failure β€” the app cannot run without a database.\nfunc InitialDB() *gorm.DB {\n\tdsn := buildDSN()\n\n\tdb, err := gorm.Open(postgres.Open(dsn), &gorm.Config{\n\t\tLogger: logger.Default.LogMode(logger.Info),\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"database connection failed: %v\", err)\n\t}\n\n\tsqlDB, err := db.DB()\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to get underlying sql.DB: %v\", err)\n\t}\n\tsqlDB.SetMaxOpenConns(25)\n\tsqlDB.SetMaxIdleConns(10)\n\tsqlDB.SetConnMaxLifetime(5 * time.Minute)\n\n\tlog.Println(\"database connected:\", maskDSN(dsn))\n\treturn db\n}\n\nfunc buildDSN() string {\n\treturn fmt.Sprintf(\n\t\t\"host=%s port=%s user=%s password=%s dbname=%s sslmode=%s TimeZone=%s\",\n\t\tgetEnv(\"DB_HOST\",     \"localhost\"),\n\t\tgetEnv(\"DB_PORT\",     \"5432\"),\n\t\tgetEnv(\"DB_USER\",     \"postgres\"),\n\t\tos.Getenv(\"DB_PASSWORD\"),\n\t\tgetEnv(\"DB_NAME\",     \"appdb\"),\n\t\tgetEnv(\"DB_SSLMODE\",  \"disable\"),\n\t\tgetEnv(\"DB_TIMEZONE\", \"UTC\"),\n\t)\n}\n\nfunc getEnv(key, fallback string) string {\n\tif v := os.Getenv(key); v != \"\" {\n\t\treturn v\n\t}\n\treturn fallback\n}\n\nfunc maskDSN(dsn string) string {\n\tpassword := os.Getenv(\"DB_PASSWORD\")\n\tif password == \"\" {\n\t\treturn dsn\n\t}\n\treturn strings.ReplaceAll(dsn, password, \"*****\")\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> contracts\n\n// services/contracts/patientServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// PatientServiceContract is the interface every Patient service implementation must satisfy.\ntype PatientServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input PatientInputDTO) (uuid.UUID, error)\n\n\tFindByCPF(cpf string) (*PatientDTO, error)\n\n\tList(page, limit int) ([]PatientDTO, error)\n\n\tUpdate(id uuid.UUID, dto PatientDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// PatientInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype PatientInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tName    string `json:\"name\"`\n\tContact string `json:\"contact\"`\n\tCPF     string `json:\"cpf,omitempty\"`\n}\n\n// PatientDTO is the canonical data transfer object passed between layers.\ntype PatientDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tName    string `json:\"name\"`\n\tContact string `json:\"contact\"`\n\tCPF     string `json:\"cpf,omitempty\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> implementations\n\n// services/implementations/patientService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// PatientService implements sc.PatientServiceContract.\ntype PatientService struct {\n\trepo         contracts.PatientRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewPatientService constructs a PatientService with all required repositories.\nfunc NewPatientService(\n\trepo    contracts.PatientRepository,\n\torgRepo contracts.OrganizationRepository,\n) *PatientService {\n\treturn &PatientService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *PatientService) CreateFromInput(input sc.PatientInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.PatientDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *PatientService) FindByCPF(cpf string) (*sc.PatientDTO, error) {\n\tresult, err := s.repo.FindByCPF(cpf)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"patient find by cpf: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *PatientService) List(page, limit int) ([]sc.PatientDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *PatientService) Update(id uuid.UUID, dto sc.PatientDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *PatientService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> contracts\n\n// services/contracts/patientServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// PatientServiceContract is the interface every Patient service implementation must satisfy.\ntype PatientServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input PatientInputDTO) (uuid.UUID, error)\n\n\tFindByCPF(cpf string) (*PatientDTO, error)\n\n\tList(page, limit int) ([]PatientDTO, error)\n\n\tUpdate(id uuid.UUID, dto PatientDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// PatientInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype PatientInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tName    string `json:\"name\"`\n\tContact string `json:\"contact\"`\n\tCPF     string `json:\"cpf,omitempty\"`\n}\n\n// PatientDTO is the canonical data transfer object passed between layers.\ntype PatientDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tName    string `json:\"name\"`\n\tContact string `json:\"contact\"`\n\tCPF     string `json:\"cpf,omitempty\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> implementations\n\n// services/implementations/patientService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// PatientService implements sc.PatientServiceContract.\ntype PatientService struct {\n\trepo         contracts.PatientRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewPatientService constructs a PatientService with all required repositories.\nfunc NewPatientService(\n\trepo    contracts.PatientRepository,\n\torgRepo contracts.OrganizationRepository,\n) *PatientService {\n\treturn &PatientService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *PatientService) CreateFromInput(input sc.PatientInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.PatientDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *PatientService) FindByCPF(cpf string) (*sc.PatientDTO, error) {\n\tresult, err := s.repo.FindByCPF(cpf)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"patient find by cpf: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *PatientService) List(page, limit int) ([]sc.PatientDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *PatientService) Update(id uuid.UUID, dto sc.PatientDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *PatientService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> contracts\n\n// services/contracts/patientServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// PatientServiceContract is the interface every Patient service implementation must satisfy.\ntype PatientServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input PatientInputDTO) (uuid.UUID, error)\n\n\tFindByCPF(cpf string) (*PatientDTO, error)\n\n\tList(page, limit int) ([]PatientDTO, error)\n\n\tUpdate(id uuid.UUID, dto PatientDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// PatientInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype PatientInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tName    string `json:\"name\"`\n\tContact string `json:\"contact\"`\n\tCPF     string `json:\"cpf,omitempty\"`\n}\n\n// PatientDTO is the canonical data transfer object passed between layers.\ntype PatientDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tName    string `json:\"name\"`\n\tContact string `json:\"contact\"`\n\tCPF     string `json:\"cpf,omitempty\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> implementations\n\n// services/implementations/patientService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// PatientService implements sc.PatientServiceContract.\ntype PatientService struct {\n\trepo         contracts.PatientRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewPatientService constructs a PatientService with all required repositories.\nfunc NewPatientService(\n\trepo    contracts.PatientRepository,\n\torgRepo contracts.OrganizationRepository,\n) *PatientService {\n\treturn &PatientService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *PatientService) CreateFromInput(input sc.PatientInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.PatientDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *PatientService) FindByCPF(cpf string) (*sc.PatientDTO, error) {\n\tresult, err := s.repo.FindByCPF(cpf)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"patient find by cpf: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *PatientService) List(page, limit int) ([]sc.PatientDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *PatientService) Update(id uuid.UUID, dto sc.PatientDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *PatientService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> contracts\n\n// services/contracts/patientServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// PatientServiceContract is the interface every Patient service implementation must satisfy.\ntype PatientServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input PatientInputDTO) (uuid.UUID, error)\n\n\tFindByCPF(cpf string) (*PatientDTO, error)\n\n\tList(page, limit int) ([]PatientDTO, error)\n\n\tUpdate(id uuid.UUID, dto PatientDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// PatientInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype PatientInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tName    string `json:\"name\"`\n\tContact string `json:\"contact\"`\n\tCPF     string `json:\"cpf,omitempty\"`\n}\n\n// PatientDTO is the canonical data transfer object passed between layers.\ntype PatientDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tName    string `json:\"name\"`\n\tContact string `json:\"contact\"`\n\tCPF     string `json:\"cpf,omitempty\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> implementations\n\n// services/implementations/patientService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// PatientService implements sc.PatientServiceContract.\ntype PatientService struct {\n\trepo         contracts.PatientRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewPatientService constructs a PatientService with all required repositories.\nfunc NewPatientService(\n\trepo    contracts.PatientRepository,\n\torgRepo contracts.OrganizationRepository,\n) *PatientService {\n\treturn &PatientService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *PatientService) CreateFromInput(input sc.PatientInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.PatientDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *PatientService) FindByCPF(cpf string) (*sc.PatientDTO, error) {\n\tresult, err := s.repo.FindByCPF(cpf)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"patient find by cpf: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *PatientService) List(page, limit int) ([]sc.PatientDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *PatientService) Update(id uuid.UUID, dto sc.PatientDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *PatientService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> contracts\n\n// services/contracts/doctorServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// DoctorServiceContract is the interface every Doctor service implementation must satisfy.\ntype DoctorServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input DoctorInputDTO) (uuid.UUID, error)\n\n\tFindByCRM(crm string) (*DoctorDTO, error)\n\n\tList(page, limit int) ([]DoctorDTO, error)\n\n\tUpdate(id uuid.UUID, dto DoctorDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// DoctorInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype DoctorInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tFullName   string `json:\"full_name\"`\n\tCPF        string `json:\"cpf\"`\n\tCRM        string `json:\"crm\"`\n\tSpecialty  string `json:\"specialty\"`\n}\n\n// DoctorDTO is the canonical data transfer object passed between layers.\ntype DoctorDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tFullName   string `json:\"full_name\"`\n\tCRM        string `json:\"crm\"`\n\tSpecialty  string `json:\"specialty\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> implementations\n\n// services/implementations/doctorService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// DoctorService implements sc.DoctorServiceContract.\ntype DoctorService struct {\n\trepo         contracts.DoctorRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewDoctorService constructs a DoctorService with all required repositories.\nfunc NewDoctorService(\n\trepo    contracts.DoctorRepository,\n\torgRepo contracts.OrganizationRepository,\n) *DoctorService {\n\treturn &DoctorService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *DoctorService) CreateFromInput(input sc.DoctorInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.DoctorDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *DoctorService) FindByCRM(crm string) (*sc.DoctorDTO, error) {\n\tresult, err := s.repo.FindByCRM(crm)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"doctor find by crm: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *DoctorService) List(page, limit int) ([]sc.DoctorDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *DoctorService) Update(id uuid.UUID, dto sc.DoctorDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *DoctorService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> contracts\n\n// services/contracts/doctorServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// DoctorServiceContract is the interface every Doctor service implementation must satisfy.\ntype DoctorServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input DoctorInputDTO) (uuid.UUID, error)\n\n\tFindByCRM(crm string) (*DoctorDTO, error)\n\n\tList(page, limit int) ([]DoctorDTO, error)\n\n\tUpdate(id uuid.UUID, dto DoctorDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// DoctorInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype DoctorInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tFullName   string `json:\"full_name\"`\n\tCPF        string `json:\"cpf\"`\n\tCRM        string `json:\"crm\"`\n\tSpecialty  string `json:\"specialty\"`\n}\n\n// DoctorDTO is the canonical data transfer object passed between layers.\ntype DoctorDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tFullName   string `json:\"full_name\"`\n\tCRM        string `json:\"crm\"`\n\tSpecialty  string `json:\"specialty\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> implementations\n\n// services/implementations/doctorService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// DoctorService implements sc.DoctorServiceContract.\ntype DoctorService struct {\n\trepo         contracts.DoctorRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewDoctorService constructs a DoctorService with all required repositories.\nfunc NewDoctorService(\n\trepo    contracts.DoctorRepository,\n\torgRepo contracts.OrganizationRepository,\n) *DoctorService {\n\treturn &DoctorService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *DoctorService) CreateFromInput(input sc.DoctorInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.DoctorDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *DoctorService) FindByCRM(crm string) (*sc.DoctorDTO, error) {\n\tresult, err := s.repo.FindByCRM(crm)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"doctor find by crm: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *DoctorService) List(page, limit int) ([]sc.DoctorDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *DoctorService) Update(id uuid.UUID, dto sc.DoctorDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *DoctorService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> contracts\n\n// services/contracts/doctorServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// DoctorServiceContract is the interface every Doctor service implementation must satisfy.\ntype DoctorServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input DoctorInputDTO) (uuid.UUID, error)\n\n\tFindByCRM(crm string) (*DoctorDTO, error)\n\n\tList(page, limit int) ([]DoctorDTO, error)\n\n\tUpdate(id uuid.UUID, dto DoctorDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// DoctorInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype DoctorInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tFullName   string `json:\"full_name\"`\n\tCPF        string `json:\"cpf\"`\n\tCRM        string `json:\"crm\"`\n\tSpecialty  string `json:\"specialty\"`\n}\n\n// DoctorDTO is the canonical data transfer object passed between layers.\ntype DoctorDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tFullName   string `json:\"full_name\"`\n\tCRM        string `json:\"crm\"`\n\tSpecialty  string `json:\"specialty\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> implementations\n\n// services/implementations/doctorService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// DoctorService implements sc.DoctorServiceContract.\ntype DoctorService struct {\n\trepo         contracts.DoctorRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewDoctorService constructs a DoctorService with all required repositories.\nfunc NewDoctorService(\n\trepo    contracts.DoctorRepository,\n\torgRepo contracts.OrganizationRepository,\n) *DoctorService {\n\treturn &DoctorService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *DoctorService) CreateFromInput(input sc.DoctorInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.DoctorDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *DoctorService) FindByCRM(crm string) (*sc.DoctorDTO, error) {\n\tresult, err := s.repo.FindByCRM(crm)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"doctor find by crm: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *DoctorService) List(page, limit int) ([]sc.DoctorDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *DoctorService) Update(id uuid.UUID, dto sc.DoctorDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *DoctorService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> contracts\n\n// services/contracts/doctorServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// DoctorServiceContract is the interface every Doctor service implementation must satisfy.\ntype DoctorServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input DoctorInputDTO) (uuid.UUID, error)\n\n\tFindByCRM(crm string) (*DoctorDTO, error)\n\n\tList(page, limit int) ([]DoctorDTO, error)\n\n\tUpdate(id uuid.UUID, dto DoctorDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// DoctorInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype DoctorInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tFullName   string `json:\"full_name\"`\n\tCPF        string `json:\"cpf\"`\n\tCRM        string `json:\"crm\"`\n\tSpecialty  string `json:\"specialty\"`\n}\n\n// DoctorDTO is the canonical data transfer object passed between layers.\ntype DoctorDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tFullName   string `json:\"full_name\"`\n\tCRM        string `json:\"crm\"`\n\tSpecialty  string `json:\"specialty\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> implementations\n\n// services/implementations/doctorService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// DoctorService implements sc.DoctorServiceContract.\ntype DoctorService struct {\n\trepo         contracts.DoctorRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewDoctorService constructs a DoctorService with all required repositories.\nfunc NewDoctorService(\n\trepo    contracts.DoctorRepository,\n\torgRepo contracts.OrganizationRepository,\n) *DoctorService {\n\treturn &DoctorService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *DoctorService) CreateFromInput(input sc.DoctorInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.DoctorDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *DoctorService) FindByCRM(crm string) (*sc.DoctorDTO, error) {\n\tresult, err := s.repo.FindByCRM(crm)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"doctor find by crm: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *DoctorService) List(page, limit int) ([]sc.DoctorDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *DoctorService) Update(id uuid.UUID, dto sc.DoctorDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *DoctorService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> contracts\n\n// services/contracts/appointmentServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// AppointmentServiceContract is the interface every Appointment service implementation must satisfy.\ntype AppointmentServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input AppointmentInputDTO) (uuid.UUID, error)\n\n\tFindByStatus(status string) (*AppointmentDTO, error)\n\n\tList(page, limit int) ([]AppointmentDTO, error)\n\n\tUpdate(id uuid.UUID, dto AppointmentDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// AppointmentInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype AppointmentInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tPatientName    string    `json:\"patient_name\"`\n\tDoctorFullName string    `json:\"doctor_full_name\"`\n\tSpecialization string    `json:\"specialization\"`\n\tDateTime       time.Time `json:\"date_time\"`\n}\n\n// AppointmentDTO is the canonical data transfer object passed between layers.\ntype AppointmentDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tPatientID      string    `json:\"patient_id\"`\n\tDoctorID       string    `json:\"doctor_id\"`\n\tSpecialization string    `json:\"specialization\"`\n\tDateTime       time.Time `json:\"date_time\"`\n\tStatus         string    `json:\"status\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> implementations\n\n// services/implementations/appointmentService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// AppointmentService implements sc.AppointmentServiceContract.\ntype AppointmentService struct {\n\trepo         contracts.AppointmentRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewAppointmentService constructs a AppointmentService with all required repositories.\nfunc NewAppointmentService(\n\trepo    contracts.AppointmentRepository,\n\torgRepo contracts.OrganizationRepository,\n) *AppointmentService {\n\treturn &AppointmentService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *AppointmentService) CreateFromInput(input sc.AppointmentInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.AppointmentDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *AppointmentService) FindByStatus(status string) (*sc.AppointmentDTO, error) {\n\tresult, err := s.repo.FindByStatus(status)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"appointment find by status: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *AppointmentService) List(page, limit int) ([]sc.AppointmentDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *AppointmentService) Update(id uuid.UUID, dto sc.AppointmentDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *AppointmentService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> contracts\n\n// services/contracts/appointmentServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// AppointmentServiceContract is the interface every Appointment service implementation must satisfy.\ntype AppointmentServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input AppointmentInputDTO) (uuid.UUID, error)\n\n\tFindByStatus(status string) (*AppointmentDTO, error)\n\n\tList(page, limit int) ([]AppointmentDTO, error)\n\n\tUpdate(id uuid.UUID, dto AppointmentDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// AppointmentInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype AppointmentInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tPatientName    string    `json:\"patient_name\"`\n\tDoctorFullName string    `json:\"doctor_full_name\"`\n\tSpecialization string    `json:\"specialization\"`\n\tDateTime       time.Time `json:\"date_time\"`\n}\n\n// AppointmentDTO is the canonical data transfer object passed between layers.\ntype AppointmentDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tPatientID      string    `json:\"patient_id\"`\n\tDoctorID       string    `json:\"doctor_id\"`\n\tSpecialization string    `json:\"specialization\"`\n\tDateTime       time.Time `json:\"date_time\"`\n\tStatus         string    `json:\"status\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> implementations\n\n// services/implementations/appointmentService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// AppointmentService implements sc.AppointmentServiceContract.\ntype AppointmentService struct {\n\trepo         contracts.AppointmentRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewAppointmentService constructs a AppointmentService with all required repositories.\nfunc NewAppointmentService(\n\trepo    contracts.AppointmentRepository,\n\torgRepo contracts.OrganizationRepository,\n) *AppointmentService {\n\treturn &AppointmentService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *AppointmentService) CreateFromInput(input sc.AppointmentInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.AppointmentDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *AppointmentService) FindByStatus(status string) (*sc.AppointmentDTO, error) {\n\tresult, err := s.repo.FindByStatus(status)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"appointment find by status: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *AppointmentService) List(page, limit int) ([]sc.AppointmentDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *AppointmentService) Update(id uuid.UUID, dto sc.AppointmentDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *AppointmentService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> contracts\n\n// services/contracts/appointmentServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// AppointmentServiceContract is the interface every Appointment service implementation must satisfy.\ntype AppointmentServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input AppointmentInputDTO) (uuid.UUID, error)\n\n\tFindByStatus(status string) (*AppointmentDTO, error)\n\n\tList(page, limit int) ([]AppointmentDTO, error)\n\n\tUpdate(id uuid.UUID, dto AppointmentDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// AppointmentInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype AppointmentInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tPatientName    string    `json:\"patient_name\"`\n\tDoctorFullName string    `json:\"doctor_full_name\"`\n\tSpecialization string    `json:\"specialization\"`\n\tDateTime       time.Time `json:\"date_time\"`\n}\n\n// AppointmentDTO is the canonical data transfer object passed between layers.\ntype AppointmentDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tPatientID      string    `json:\"patient_id\"`\n\tDoctorID       string    `json:\"doctor_id\"`\n\tSpecialization string    `json:\"specialization\"`\n\tDateTime       time.Time `json:\"date_time\"`\n\tStatus         string    `json:\"status\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> implementations\n\n// services/implementations/appointmentService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// AppointmentService implements sc.AppointmentServiceContract.\ntype AppointmentService struct {\n\trepo         contracts.AppointmentRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewAppointmentService constructs a AppointmentService with all required repositories.\nfunc NewAppointmentService(\n\trepo    contracts.AppointmentRepository,\n\torgRepo contracts.OrganizationRepository,\n) *AppointmentService {\n\treturn &AppointmentService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *AppointmentService) CreateFromInput(input sc.AppointmentInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.AppointmentDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *AppointmentService) FindByStatus(status string) (*sc.AppointmentDTO, error) {\n\tresult, err := s.repo.FindByStatus(status)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"appointment find by status: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *AppointmentService) List(page, limit int) ([]sc.AppointmentDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *AppointmentService) Update(id uuid.UUID, dto sc.AppointmentDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *AppointmentService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> contracts\n\n// services/contracts/appointmentServiceContract.go\n// Pattern: service interface decouples controller from implementation\n// Observed in: Medical-App-Core/services/contracts/\npackage contracts\n\nimport \"github.com/google/uuid\"\n\n// AppointmentServiceContract is the interface every Appointment service implementation must satisfy.\ntype AppointmentServiceContract interface {\n\t// CreateFromInput resolves human-readable names in the InputDTO to UUIDs,\n\t// then delegates persistence to the repository.\n\tCreateFromInput(input AppointmentInputDTO) (uuid.UUID, error)\n\n\tFindByStatus(status string) (*AppointmentDTO, error)\n\n\tList(page, limit int) ([]AppointmentDTO, error)\n\n\tUpdate(id uuid.UUID, dto AppointmentDTO) error\n\n\tDelete(id uuid.UUID) error\n}\n\n// AppointmentInputDTO carries fields exactly as received from the HTTP layer.\n// Name-based fields (OrganizationName, etc.) are resolved in the service.\ntype AppointmentInputDTO struct {\n\tOrganizationName string `json:\"organization_name\"`\n\tPatientName    string    `json:\"patient_name\"`\n\tDoctorFullName string    `json:\"doctor_full_name\"`\n\tSpecialization string    `json:\"specialization\"`\n\tDateTime       time.Time `json:\"date_time\"`\n}\n\n// AppointmentDTO is the canonical data transfer object passed between layers.\ntype AppointmentDTO struct {\n\tOrganizationID string `json:\"organization_id\"`\n\tPatientID      string    `json:\"patient_id\"`\n\tDoctorID       string    `json:\"doctor_id\"`\n\tSpecialization string    `json:\"specialization\"`\n\tDateTime       time.Time `json:\"date_time\"`\n\tStatus         string    `json:\"status\"`\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> implementations\n\n// services/implementations/appointmentService.go\n// Pattern: service implementation resolves names→IDs, validates, then calls repo\n// Observed in: Medical-App-Core/services/implementations/\npackage implementations\n\nimport (\n\t\"fmt\"\n\n\t\"medical-sas-api/domain/repositories/contracts\"\n\tsc \"$module/services/contracts\"\n\t\"github.com/google/uuid\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// AppointmentService implements sc.AppointmentServiceContract.\ntype AppointmentService struct {\n\trepo         contracts.AppointmentRepository\n\torgRepo      contracts.OrganizationRepository\n}\n\n// NewAppointmentService constructs a AppointmentService with all required repositories.\nfunc NewAppointmentService(\n\trepo    contracts.AppointmentRepository,\n\torgRepo contracts.OrganizationRepository,\n) *AppointmentService {\n\treturn &AppointmentService{repo: repo, orgRepo: orgRepo}\n}\n\n// CreateFromInput resolves organization name to UUID in parallel with any other\n// lookups, validates the result, then inserts via the repository.\nfunc (s *AppointmentService) CreateFromInput(input sc.AppointmentInputDTO) (uuid.UUID, error) {\n\tvar (\n\t\torgID uuid.UUID\n\t)\n\n\t// Parallel resolution of related entities\n\tg := &errgroup.Group{}\n\tg.Go(func() error {\n\t\torg, err := s.orgRepo.FindByName(input.OrganizationName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"organization %q not found: %w\", input.OrganizationName, err)\n\t\t}\n\t\torgID = org.ID\n\t\treturn nil\n\t})\n\tif err := g.Wait(); err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tdto := sc.AppointmentDTO{\n\t\tOrganizationID: orgID.String(),\n\t\t// map remaining input fields\n\t}\n\treturn s.repo.Create(dto)\n}\n\nfunc (s *AppointmentService) FindByStatus(status string) (*sc.AppointmentDTO, error) {\n\tresult, err := s.repo.FindByStatus(status)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"appointment find by status: %w\", err)\n\t}\n\treturn result, nil\n}\n\nfunc (s *AppointmentService) List(page, limit int) ([]sc.AppointmentDTO, error) {\n\treturn s.repo.List(page, limit)\n}\n\nfunc (s *AppointmentService) Update(id uuid.UUID, dto sc.AppointmentDTO) error {\n\treturn s.repo.Update(id, dto)\n}\n\nfunc (s *AppointmentService) Delete(id uuid.UUID) error {\n\treturn s.repo.Delete(id)\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> initializers\n\n// initializers/services.go\n// Pattern: dependency injection container β€” wires repositories β†’ services\n// Observed in: Medical-App-Core/initializers/services.go\npackage initializers\n\nimport (\n\t\"medical-sas-api/domain/repositories/contracts\"\n\timplrepos \"medical-sas-api/infra/repositories\"\n\tsc \"medical-sas-api/services/contracts\"\n\tsi \"medical-sas-api/services/implementations\"\n\n\t\"gorm.io/gorm\"\n)\n\n// Services is the application-wide DI container.\n// It is constructed once in main() and passed to controllers/middleware.\ntype Services struct {\n\tAuthTokenService  sc.AuthTokenServiceContract\n\tOrganizationService sc.OrganizationServiceContract\n\tUserService       sc.UserServiceContract\n\tPatientService    sc.PatientServiceContract\n\tDoctorService     sc.DoctorServiceContract\n\tAppointmentService sc.AppointmentServiceContract\n\tChargeService     sc.ChargeServiceContract\n\tMedicalRecordService sc.MedicalRecordServiceContract\n}\n\n// InitServices builds and wires all repositories and services.\nfunc InitServices(db *gorm.DB) *Services {\n\t// Repositories\n\torgRepo         := implrepos.NewOrganizationRepository(db)\n\tuserRepo        := implrepos.NewUserRepository(db)\n\tpatientRepo     := implrepos.NewPatientRepository(db)\n\tdoctorRepo      := implrepos.NewDoctorRepository(db)\n\tappointmentRepo := implrepos.NewAppointmentRepository(db)\n\n\t// Services (inject repos as interface values)\n\tauthSvc  := si.NewAuthTokenService()\n\torgSvc   := si.NewOrganizationService(orgRepo)\n\tuserSvc  := si.NewUserService(userRepo, orgRepo)\n\tpatSvc   := si.NewPatientService(patientRepo, orgRepo)\n\tdocSvc   := si.NewDoctorService(doctorRepo, orgRepo)\n\tapptSvc  := si.NewAppointmentService(\n\t\tappointmentRepo, orgRepo, patientRepo, userRepo, doctorRepo,\n\t)\n\tchargeSvc := si.NewChargeService(orgRepo)\n\n\treturn &Services{\n\t\tAuthTokenService:      authSvc,\n\t\tOrganizationService:   orgSvc,\n\t\tUserService:           userSvc,\n\t\tPatientService:        patSvc,\n\t\tDoctorService:         docSvc,\n\t\tAppointmentService:    apptSvc,\n\t\tChargeService:         chargeSvc,\n\t}\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> events\n\n// services/events/doctors/doctorEventConsumer.go\n// Pattern: RabbitMQ consumer with reconnect loop + JSON unmarshaling\n// Observed in: Medical-App-Core/services/events/\npackage events\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/streadway/amqp\"\n)\n\n// DoctorCreatedEvent is the message payload published when a doctor is registered.\ntype DoctorCreatedEvent struct {\n\tDoctorID   string    `json:\"doctor_id\"`\n\tFullName   string    `json:\"full_name\"`\n\tSpecialty  string    `json:\"specialty\"`\n\tCreatedAt  time.Time `json:\"created_at\"`\n}\n\n// DoctorEventConsumer subscribes to the doctors.created queue.\ntype DoctorEventConsumer struct {\n\tconn    *amqp.Connection\n\tch      *amqp.Channel\n\tqueue   string\n\thandler func(DoctorCreatedEvent) error\n}\n\n// NewDoctorEventConsumer dials RabbitMQ and declares the queue.\nfunc NewDoctorEventConsumer(handler func(DoctorCreatedEvent) error) (*DoctorEventConsumer, error) {\n\turl := os.Getenv(\"RABBITMQ_BASE_URL\")\n\tif url == \"\" {\n\t\treturn nil, fmt.Errorf(\"RABBITMQ_BASE_URL is not set\")\n\t}\n\n\tconn, err := amqp.Dial(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rabbitmq dial: %w\", err)\n\t}\n\n\tch, err := conn.Channel()\n\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, fmt.Errorf(\"rabbitmq channel: %w\", err)\n\t}\n\n\tqueue := \"doctors.created\"\n\t_, err = ch.QueueDeclare(queue, true, false, false, false, nil)\n\tif err != nil {\n\t\tch.Close(); conn.Close()\n\t\treturn nil, fmt.Errorf(\"queue declare: %w\", err)\n\t}\n\n\treturn &DoctorEventConsumer{conn: conn, ch: ch, queue: queue, handler: handler}, nil\n}\n\n// Consume starts consuming messages and blocks until ctx is cancelled.\nfunc (c *DoctorEventConsumer) Consume() error {\n\tmsgs, err := c.ch.Consume(c.queue, \"\", false, false, false, false, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"consume: %w\", err)\n\t}\n\n\tlog.Printf(\"consuming from %s\", c.queue)\n\tfor msg := range msgs {\n\t\tvar event DoctorCreatedEvent\n\t\tif err := json.Unmarshal(msg.Body, &event); err != nil {\n\t\t\tlog.Printf(\"unmarshal error: %v β€” nacking\", err)\n\t\t\tmsg.Nack(false, false) // dead-letter\n\t\t\tcontinue\n\t\t}\n\t\tif err := c.handler(event); err != nil {\n\t\t\tlog.Printf(\"handler error: %v β€” nacking with requeue\", err)\n\t\t\tmsg.Nack(false, true)\n\t\t\tcontinue\n\t\t}\n\t\tmsg.Ack(false)\n\t}\n\treturn nil\n}\n\n// Close releases RabbitMQ resources.\nfunc (c *DoctorEventConsumer) Close() {\n\tc.ch.Close()\n\tc.conn.Close()\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> initializers\n\n// initializers/services.go\n// Pattern: dependency injection container β€” wires repositories β†’ services\n// Observed in: Medical-App-Core/initializers/services.go\npackage initializers\n\nimport (\n\t\"medical-sas-api/domain/repositories/contracts\"\n\timplrepos \"medical-sas-api/infra/repositories\"\n\tsc \"medical-sas-api/services/contracts\"\n\tsi \"medical-sas-api/services/implementations\"\n\n\t\"gorm.io/gorm\"\n)\n\n// Services is the application-wide DI container.\n// It is constructed once in main() and passed to controllers/middleware.\ntype Services struct {\n\tAuthTokenService  sc.AuthTokenServiceContract\n\tOrganizationService sc.OrganizationServiceContract\n\tUserService       sc.UserServiceContract\n\tPatientService    sc.PatientServiceContract\n\tDoctorService     sc.DoctorServiceContract\n\tAppointmentService sc.AppointmentServiceContract\n\tChargeService     sc.ChargeServiceContract\n\tMedicalRecordService sc.MedicalRecordServiceContract\n}\n\n// InitServices builds and wires all repositories and services.\nfunc InitServices(db *gorm.DB) *Services {\n\t// Repositories\n\torgRepo         := implrepos.NewOrganizationRepository(db)\n\tuserRepo        := implrepos.NewUserRepository(db)\n\tpatientRepo     := implrepos.NewPatientRepository(db)\n\tdoctorRepo      := implrepos.NewDoctorRepository(db)\n\tappointmentRepo := implrepos.NewAppointmentRepository(db)\n\n\t// Services (inject repos as interface values)\n\tauthSvc  := si.NewAuthTokenService()\n\torgSvc   := si.NewOrganizationService(orgRepo)\n\tuserSvc  := si.NewUserService(userRepo, orgRepo)\n\tpatSvc   := si.NewPatientService(patientRepo, orgRepo)\n\tdocSvc   := si.NewDoctorService(doctorRepo, orgRepo)\n\tapptSvc  := si.NewAppointmentService(\n\t\tappointmentRepo, orgRepo, patientRepo, userRepo, doctorRepo,\n\t)\n\tchargeSvc := si.NewChargeService(orgRepo)\n\n\treturn &Services{\n\t\tAuthTokenService:      authSvc,\n\t\tOrganizationService:   orgSvc,\n\t\tUserService:           userSvc,\n\t\tPatientService:        patSvc,\n\t\tDoctorService:         docSvc,\n\t\tAppointmentService:    apptSvc,\n\t\tChargeService:         chargeSvc,\n\t}\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> events\n\n// services/events/doctors/doctorEventConsumer.go\n// Pattern: RabbitMQ consumer with reconnect loop + JSON unmarshaling\n// Observed in: Medical-App-Core/services/events/\npackage events\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/streadway/amqp\"\n)\n\n// DoctorCreatedEvent is the message payload published when a doctor is registered.\ntype DoctorCreatedEvent struct {\n\tDoctorID   string    `json:\"doctor_id\"`\n\tFullName   string    `json:\"full_name\"`\n\tSpecialty  string    `json:\"specialty\"`\n\tCreatedAt  time.Time `json:\"created_at\"`\n}\n\n// DoctorEventConsumer subscribes to the doctors.created queue.\ntype DoctorEventConsumer struct {\n\tconn    *amqp.Connection\n\tch      *amqp.Channel\n\tqueue   string\n\thandler func(DoctorCreatedEvent) error\n}\n\n// NewDoctorEventConsumer dials RabbitMQ and declares the queue.\nfunc NewDoctorEventConsumer(handler func(DoctorCreatedEvent) error) (*DoctorEventConsumer, error) {\n\turl := os.Getenv(\"RABBITMQ_BASE_URL\")\n\tif url == \"\" {\n\t\treturn nil, fmt.Errorf(\"RABBITMQ_BASE_URL is not set\")\n\t}\n\n\tconn, err := amqp.Dial(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rabbitmq dial: %w\", err)\n\t}\n\n\tch, err := conn.Channel()\n\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, fmt.Errorf(\"rabbitmq channel: %w\", err)\n\t}\n\n\tqueue := \"doctors.created\"\n\t_, err = ch.QueueDeclare(queue, true, false, false, false, nil)\n\tif err != nil {\n\t\tch.Close(); conn.Close()\n\t\treturn nil, fmt.Errorf(\"queue declare: %w\", err)\n\t}\n\n\treturn &DoctorEventConsumer{conn: conn, ch: ch, queue: queue, handler: handler}, nil\n}\n\n// Consume starts consuming messages and blocks until ctx is cancelled.\nfunc (c *DoctorEventConsumer) Consume() error {\n\tmsgs, err := c.ch.Consume(c.queue, \"\", false, false, false, false, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"consume: %w\", err)\n\t}\n\n\tlog.Printf(\"consuming from %s\", c.queue)\n\tfor msg := range msgs {\n\t\tvar event DoctorCreatedEvent\n\t\tif err := json.Unmarshal(msg.Body, &event); err != nil {\n\t\t\tlog.Printf(\"unmarshal error: %v β€” nacking\", err)\n\t\t\tmsg.Nack(false, false) // dead-letter\n\t\t\tcontinue\n\t\t}\n\t\tif err := c.handler(event); err != nil {\n\t\t\tlog.Printf(\"handler error: %v β€” nacking with requeue\", err)\n\t\t\tmsg.Nack(false, true)\n\t\t\tcontinue\n\t\t}\n\t\tmsg.Ack(false)\n\t}\n\treturn nil\n}\n\n// Close releases RabbitMQ resources.\nfunc (c *DoctorEventConsumer) Close() {\n\tc.ch.Close()\n\tc.conn.Close()\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> initializers\n\n// initializers/services.go\n// Pattern: dependency injection container β€” wires repositories β†’ services\n// Observed in: Medical-App-Core/initializers/services.go\npackage initializers\n\nimport (\n\t\"medical-sas-api/domain/repositories/contracts\"\n\timplrepos \"medical-sas-api/infra/repositories\"\n\tsc \"medical-sas-api/services/contracts\"\n\tsi \"medical-sas-api/services/implementations\"\n\n\t\"gorm.io/gorm\"\n)\n\n// Services is the application-wide DI container.\n// It is constructed once in main() and passed to controllers/middleware.\ntype Services struct {\n\tAuthTokenService  sc.AuthTokenServiceContract\n\tOrganizationService sc.OrganizationServiceContract\n\tUserService       sc.UserServiceContract\n\tPatientService    sc.PatientServiceContract\n\tDoctorService     sc.DoctorServiceContract\n\tAppointmentService sc.AppointmentServiceContract\n\tChargeService     sc.ChargeServiceContract\n\tMedicalRecordService sc.MedicalRecordServiceContract\n}\n\n// InitServices builds and wires all repositories and services.\nfunc InitServices(db *gorm.DB) *Services {\n\t// Repositories\n\torgRepo         := implrepos.NewOrganizationRepository(db)\n\tuserRepo        := implrepos.NewUserRepository(db)\n\tpatientRepo     := implrepos.NewPatientRepository(db)\n\tdoctorRepo      := implrepos.NewDoctorRepository(db)\n\tappointmentRepo := implrepos.NewAppointmentRepository(db)\n\n\t// Services (inject repos as interface values)\n\tauthSvc  := si.NewAuthTokenService()\n\torgSvc   := si.NewOrganizationService(orgRepo)\n\tuserSvc  := si.NewUserService(userRepo, orgRepo)\n\tpatSvc   := si.NewPatientService(patientRepo, orgRepo)\n\tdocSvc   := si.NewDoctorService(doctorRepo, orgRepo)\n\tapptSvc  := si.NewAppointmentService(\n\t\tappointmentRepo, orgRepo, patientRepo, userRepo, doctorRepo,\n\t)\n\tchargeSvc := si.NewChargeService(orgRepo)\n\n\treturn &Services{\n\t\tAuthTokenService:      authSvc,\n\t\tOrganizationService:   orgSvc,\n\t\tUserService:           userSvc,\n\t\tPatientService:        patSvc,\n\t\tDoctorService:         docSvc,\n\t\tAppointmentService:    apptSvc,\n\t\tChargeService:         chargeSvc,\n\t}\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> events\n\n// services/events/doctors/doctorEventConsumer.go\n// Pattern: RabbitMQ consumer with reconnect loop + JSON unmarshaling\n// Observed in: Medical-App-Core/services/events/\npackage events\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/streadway/amqp\"\n)\n\n// DoctorCreatedEvent is the message payload published when a doctor is registered.\ntype DoctorCreatedEvent struct {\n\tDoctorID   string    `json:\"doctor_id\"`\n\tFullName   string    `json:\"full_name\"`\n\tSpecialty  string    `json:\"specialty\"`\n\tCreatedAt  time.Time `json:\"created_at\"`\n}\n\n// DoctorEventConsumer subscribes to the doctors.created queue.\ntype DoctorEventConsumer struct {\n\tconn    *amqp.Connection\n\tch      *amqp.Channel\n\tqueue   string\n\thandler func(DoctorCreatedEvent) error\n}\n\n// NewDoctorEventConsumer dials RabbitMQ and declares the queue.\nfunc NewDoctorEventConsumer(handler func(DoctorCreatedEvent) error) (*DoctorEventConsumer, error) {\n\turl := os.Getenv(\"RABBITMQ_BASE_URL\")\n\tif url == \"\" {\n\t\treturn nil, fmt.Errorf(\"RABBITMQ_BASE_URL is not set\")\n\t}\n\n\tconn, err := amqp.Dial(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rabbitmq dial: %w\", err)\n\t}\n\n\tch, err := conn.Channel()\n\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, fmt.Errorf(\"rabbitmq channel: %w\", err)\n\t}\n\n\tqueue := \"doctors.created\"\n\t_, err = ch.QueueDeclare(queue, true, false, false, false, nil)\n\tif err != nil {\n\t\tch.Close(); conn.Close()\n\t\treturn nil, fmt.Errorf(\"queue declare: %w\", err)\n\t}\n\n\treturn &DoctorEventConsumer{conn: conn, ch: ch, queue: queue, handler: handler}, nil\n}\n\n// Consume starts consuming messages and blocks until ctx is cancelled.\nfunc (c *DoctorEventConsumer) Consume() error {\n\tmsgs, err := c.ch.Consume(c.queue, \"\", false, false, false, false, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"consume: %w\", err)\n\t}\n\n\tlog.Printf(\"consuming from %s\", c.queue)\n\tfor msg := range msgs {\n\t\tvar event DoctorCreatedEvent\n\t\tif err := json.Unmarshal(msg.Body, &event); err != nil {\n\t\t\tlog.Printf(\"unmarshal error: %v β€” nacking\", err)\n\t\t\tmsg.Nack(false, false) // dead-letter\n\t\t\tcontinue\n\t\t}\n\t\tif err := c.handler(event); err != nil {\n\t\t\tlog.Printf(\"handler error: %v β€” nacking with requeue\", err)\n\t\t\tmsg.Nack(false, true)\n\t\t\tcontinue\n\t\t}\n\t\tmsg.Ack(false)\n\t}\n\treturn nil\n}\n\n// Close releases RabbitMQ resources.\nfunc (c *DoctorEventConsumer) Close() {\n\tc.ch.Close()\n\tc.conn.Close()\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> initializers\n\n// initializers/services.go\n// Pattern: dependency injection container β€” wires repositories β†’ services\n// Observed in: Medical-App-Core/initializers/services.go\npackage initializers\n\nimport (\n\t\"medical-sas-api/domain/repositories/contracts\"\n\timplrepos \"medical-sas-api/infra/repositories\"\n\tsc \"medical-sas-api/services/contracts\"\n\tsi \"medical-sas-api/services/implementations\"\n\n\t\"gorm.io/gorm\"\n)\n\n// Services is the application-wide DI container.\n// It is constructed once in main() and passed to controllers/middleware.\ntype Services struct {\n\tAuthTokenService  sc.AuthTokenServiceContract\n\tOrganizationService sc.OrganizationServiceContract\n\tUserService       sc.UserServiceContract\n\tPatientService    sc.PatientServiceContract\n\tDoctorService     sc.DoctorServiceContract\n\tAppointmentService sc.AppointmentServiceContract\n\tChargeService     sc.ChargeServiceContract\n\tMedicalRecordService sc.MedicalRecordServiceContract\n}\n\n// InitServices builds and wires all repositories and services.\nfunc InitServices(db *gorm.DB) *Services {\n\t// Repositories\n\torgRepo         := implrepos.NewOrganizationRepository(db)\n\tuserRepo        := implrepos.NewUserRepository(db)\n\tpatientRepo     := implrepos.NewPatientRepository(db)\n\tdoctorRepo      := implrepos.NewDoctorRepository(db)\n\tappointmentRepo := implrepos.NewAppointmentRepository(db)\n\n\t// Services (inject repos as interface values)\n\tauthSvc  := si.NewAuthTokenService()\n\torgSvc   := si.NewOrganizationService(orgRepo)\n\tuserSvc  := si.NewUserService(userRepo, orgRepo)\n\tpatSvc   := si.NewPatientService(patientRepo, orgRepo)\n\tdocSvc   := si.NewDoctorService(doctorRepo, orgRepo)\n\tapptSvc  := si.NewAppointmentService(\n\t\tappointmentRepo, orgRepo, patientRepo, userRepo, doctorRepo,\n\t)\n\tchargeSvc := si.NewChargeService(orgRepo)\n\n\treturn &Services{\n\t\tAuthTokenService:      authSvc,\n\t\tOrganizationService:   orgSvc,\n\t\tUserService:           userSvc,\n\t\tPatientService:        patSvc,\n\t\tDoctorService:         docSvc,\n\t\tAppointmentService:    apptSvc,\n\t\tChargeService:         chargeSvc,\n\t}\n}\n</go_file>\n"}
{"category": "service", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> events\n\n// services/events/doctors/doctorEventConsumer.go\n// Pattern: RabbitMQ consumer with reconnect loop + JSON unmarshaling\n// Observed in: Medical-App-Core/services/events/\npackage events\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/streadway/amqp\"\n)\n\n// DoctorCreatedEvent is the message payload published when a doctor is registered.\ntype DoctorCreatedEvent struct {\n\tDoctorID   string    `json:\"doctor_id\"`\n\tFullName   string    `json:\"full_name\"`\n\tSpecialty  string    `json:\"specialty\"`\n\tCreatedAt  time.Time `json:\"created_at\"`\n}\n\n// DoctorEventConsumer subscribes to the doctors.created queue.\ntype DoctorEventConsumer struct {\n\tconn    *amqp.Connection\n\tch      *amqp.Channel\n\tqueue   string\n\thandler func(DoctorCreatedEvent) error\n}\n\n// NewDoctorEventConsumer dials RabbitMQ and declares the queue.\nfunc NewDoctorEventConsumer(handler func(DoctorCreatedEvent) error) (*DoctorEventConsumer, error) {\n\turl := os.Getenv(\"RABBITMQ_BASE_URL\")\n\tif url == \"\" {\n\t\treturn nil, fmt.Errorf(\"RABBITMQ_BASE_URL is not set\")\n\t}\n\n\tconn, err := amqp.Dial(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rabbitmq dial: %w\", err)\n\t}\n\n\tch, err := conn.Channel()\n\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, fmt.Errorf(\"rabbitmq channel: %w\", err)\n\t}\n\n\tqueue := \"doctors.created\"\n\t_, err = ch.QueueDeclare(queue, true, false, false, false, nil)\n\tif err != nil {\n\t\tch.Close(); conn.Close()\n\t\treturn nil, fmt.Errorf(\"queue declare: %w\", err)\n\t}\n\n\treturn &DoctorEventConsumer{conn: conn, ch: ch, queue: queue, handler: handler}, nil\n}\n\n// Consume starts consuming messages and blocks until ctx is cancelled.\nfunc (c *DoctorEventConsumer) Consume() error {\n\tmsgs, err := c.ch.Consume(c.queue, \"\", false, false, false, false, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"consume: %w\", err)\n\t}\n\n\tlog.Printf(\"consuming from %s\", c.queue)\n\tfor msg := range msgs {\n\t\tvar event DoctorCreatedEvent\n\t\tif err := json.Unmarshal(msg.Body, &event); err != nil {\n\t\t\tlog.Printf(\"unmarshal error: %v β€” nacking\", err)\n\t\t\tmsg.Nack(false, false) // dead-letter\n\t\t\tcontinue\n\t\t}\n\t\tif err := c.handler(event); err != nil {\n\t\t\tlog.Printf(\"handler error: %v β€” nacking with requeue\", err)\n\t\t\tmsg.Nack(false, true)\n\t\t\tcontinue\n\t\t}\n\t\tmsg.Ack(false)\n\t}\n\treturn nil\n}\n\n// Close releases RabbitMQ resources.\nfunc (c *DoctorEventConsumer) Close() {\n\tc.ch.Close()\n\tc.conn.Close()\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> implementations\n\n// services/implementations/auth_service.go\n// Pattern: JWT HS256 token generation + validation service\n// Observed in: Medical-App-Core/services/implementations/auth_service.go\npackage implementations\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/golang-jwt/jwt/v4\"\n\t\"golang.org/x/crypto/bcrypt\"\n)\n\n// Claims holds the JWT payload.\ntype Claims struct {\n\tUserID string `json:\"user_id\"`\n\tEmail  string `json:\"email\"`\n\tRole   string `json:\"role\"`\n\tjwt.RegisteredClaims\n}\n\n// AuthTokenServiceImpl handles JWT creation and validation.\ntype AuthTokenServiceImpl struct {\n\tsecret []byte\n\tttl    time.Duration\n}\n\n// NewAuthTokenService reads JWT_SECRET from the environment and constructs the service.\nfunc NewAuthTokenService() *AuthTokenServiceImpl {\n\tsecret := os.Getenv(\"JWT_SECRET\")\n\tif secret == \"\" {\n\t\tpanic(\"JWT_SECRET environment variable must be set\")\n\t}\n\treturn &AuthTokenServiceImpl{\n\t\tsecret: []byte(secret),\n\t\tttl:    24 * time.Hour,\n\t}\n}\n\n// GenerateToken creates a signed HS256 JWT for the given user attributes.\nfunc (s *AuthTokenServiceImpl) GenerateToken(userID, email, role string) (string, error) {\n\tclaims := &Claims{\n\t\tUserID: userID,\n\t\tEmail:  email,\n\t\tRole:   role,\n\t\tRegisteredClaims: jwt.RegisteredClaims{\n\t\t\tExpiresAt: jwt.NewNumericDate(time.Now().Add(s.ttl)),\n\t\t\tIssuedAt:  jwt.NewNumericDate(time.Now()),\n\t\t\tIssuer:    \"medical-sas-api\",\n\t\t},\n\t}\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\tsigned, err := token.SignedString(s.secret)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"sign token: %w\", err)\n\t}\n\treturn signed, nil\n}\n\n// ValidateToken parses and validates a JWT string. Returns nil on success.\nfunc (s *AuthTokenServiceImpl) ValidateToken(tokenString string) error {\n\ttoken, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(t *jwt.Token) (any, error) {\n\t\tif _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected signing method: %v\", t.Header[\"alg\"])\n\t\t}\n\t\treturn s.secret, nil\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid token: %w\", err)\n\t}\n\tif !token.Valid {\n\t\treturn fmt.Errorf(\"token is not valid\")\n\t}\n\treturn nil\n}\n\n// ParseClaims extracts the Claims from a valid JWT string.\nfunc (s *AuthTokenServiceImpl) ParseClaims(tokenString string) (*Claims, error) {\n\tclaims := &Claims{}\n\t_, err := jwt.ParseWithClaims(tokenString, claims, func(t *jwt.Token) (any, error) {\n\t\treturn s.secret, nil\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse claims: %w\", err)\n\t}\n\treturn claims, nil\n}\n\n// HashPassword returns a bcrypt hash of the plain-text password.\nfunc HashPassword(plain string) (string, error) {\n\thashed, err := bcrypt.GenerateFromPassword([]byte(plain), bcrypt.DefaultCost)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"hash password: %w\", err)\n\t}\n\treturn string(hashed), nil\n}\n\n// CheckPassword returns nil if plain matches the bcrypt hash.\nfunc CheckPassword(plain, hash string) error {\n\tif err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(plain)); err != nil {\n\t\treturn fmt.Errorf(\"invalid credentials\")\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> middleware\n\n// middleware/auth.go\n// Pattern: Fiber JWT bearer middleware with claims propagation via Locals\n// Observed pattern from: Medical-App-Core/cmd/main.go AuthMiddleware\npackage middleware\n\nimport (\n\t\"strings\"\n\n\t\"medical-sas-api/services/implementations\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// BearerAuth validates the Authorization: Bearer header and stores parsed\n// claims in fiber.Ctx.Locals(\"claims\") for downstream handlers.\nfunc BearerAuth(authSvc *implementations.AuthTokenServiceImpl) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif !strings.HasPrefix(header, \"Bearer \") {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\n\t\ttokenStr := strings.TrimPrefix(header, \"Bearer \")\n\t\tclaims, err := authSvc.ParseClaims(tokenStr)\n\t\tif err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\n\t\t// Make claims available to all downstream handlers\n\t\tc.Locals(\"claims\", claims)\n\t\tc.Locals(\"user_id\", claims.UserID)\n\t\tc.Locals(\"role\", claims.Role)\n\t\treturn c.Next()\n\t}\n}\n\n// RoleRequired returns a middleware that allows only the specified roles.\n// Must be chained after BearerAuth.\nfunc RoleRequired(roles ...string) fiber.Handler {\n\tallowed := make(map[string]struct{}, len(roles))\n\tfor _, r := range roles {\n\t\tallowed[r] = struct{}{}\n\t}\n\treturn func(c *fiber.Ctx) error {\n\t\trole, _ := c.Locals(\"role\").(string)\n\t\tif _, ok := allowed[role]; !ok {\n\t\t\treturn c.Status(fiber.StatusForbidden).JSON(fiber.Map{\n\t\t\t\t\"error\": \"insufficient permissions\",\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> controllers\n\n// controllers/auth_controller.go\n// Pattern: login + token generation handler\n// Observed in: Medical-App-Core/controllers/auth_controller.go\npackage controllers\n\nimport (\n\t\"net/http\"\n\n\t\"medical-sas-api/services/implementations\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// AuthController handles token generation and validation endpoints.\ntype AuthController struct {\n\tauthSvc *implementations.AuthTokenServiceImpl\n}\n\nfunc NewAuthController(svc *implementations.AuthTokenServiceImpl) *AuthController {\n\treturn &AuthController{authSvc: svc}\n}\n\ntype generateTokenRequest struct {\n\tUserID string `json:\"user_id\" validate:\"required,uuid4\"`\n\tEmail  string `json:\"email\"   validate:\"required,email\"`\n\tRole   string `json:\"role\"    validate:\"required\"`\n}\n\n// GenerateToken godoc\n// @Summary     Issue a JWT token\n// @Description Generates a signed JWT for the given user credentials\n// @Tags        Auth\n// @Accept      json\n// @Produce     json\n// @Param       body body generateTokenRequest true \"Token request\"\n// @Success     200 {object} fiber.Map{token=string}\n// @Failure     400 {object} fiber.Map\n// @Failure     500 {object} fiber.Map\n// @Router      /auth/token [post]\nfunc (ac *AuthController) GenerateToken(c *fiber.Ctx) error {\n\tvar req generateTokenRequest\n\tif err := c.BodyParser(&req); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\tif req.UserID == \"\" || req.Email == \"\" || req.Role == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"user_id, email, and role are required\"})\n\t}\n\n\ttoken, err := ac.authSvc.GenerateToken(req.UserID, req.Email, req.Role)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to generate token\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\"token\": token})\n}\n\n// ValidateToken godoc\n// @Summary     Validate a JWT token\n// @Description Returns 200 if the token is valid, 401 otherwise\n// @Tags        Auth\n// @Accept      json\n// @Produce     json\n// @Param       body body fiber.Map{token=string} true \"Token to validate\"\n// @Success     200 {object} fiber.Map{valid=bool}\n// @Failure     401 {object} fiber.Map\n// @Router      /auth/validate [post]\nfunc (ac *AuthController) ValidateToken(c *fiber.Ctx) error {\n\tvar body struct {\n\t\tToken string `json:\"token\"`\n\t}\n\tif err := c.BodyParser(&body); err != nil || body.Token == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"token is required\"})\n\t}\n\n\tif err := ac.authSvc.ValidateToken(body.Token); err != nil {\n\t\treturn c.Status(http.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\"valid\":  false,\n\t\t\t\"reason\": err.Error(),\n\t\t})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\"valid\": true})\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> initializers\n\n// initializers/validators.go\n// Pattern: custom validator registration with go-playground/validator\n// Observed in: Medical-App-Core/initializers/validators.go\npackage initializers\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/go-playground/validator/v10\"\n)\n\n// RegisterCustomValidators adds domain-specific validation rules.\nfunc RegisterCustomValidators(v *validator.Validate) {\n\t_ = v.RegisterValidation(\"cpf\",  validateCPF)\n\t_ = v.RegisterValidation(\"cnpj\", validateCNPJ)\n\t_ = v.RegisterValidation(\"crm\",  validateCRM)\n}\n\n// validateCPF validates a Brazilian CPF number (11 digits, checksum).\nfunc validateCPF(fl validator.FieldLevel) bool {\n\tcpf := strings.ReplaceAll(fl.Field().String(), \".\", \"\")\n\tcpf  = strings.ReplaceAll(cpf, \"-\", \"\")\n\tif len(cpf) != 11 || allEqual(cpf) {\n\t\treturn false\n\t}\n\treturn cpfChecksum(cpf)\n}\n\nfunc cpfChecksum(cpf string) bool {\n\tdigits := make([]int, 11)\n\tfor i, ch := range cpf {\n\t\tdigits[i], _ = strconv.Atoi(string(ch))\n\t}\n\tfor pass := 0; pass < 2; pass++ {\n\t\tweight := 10 + pass\n\t\tsum    := 0\n\t\tfor i := 0; i < 9+pass; i++ {\n\t\t\tsum += digits[i] * (weight - i)\n\t\t}\n\t\trem := (sum * 10) % 11\n\t\tif rem == 10 || rem == 11 {\n\t\t\trem = 0\n\t\t}\n\t\tif rem != digits[9+pass] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// validateCNPJ validates a Brazilian CNPJ number (14 digits, checksum).\nfunc validateCNPJ(fl validator.FieldLevel) bool {\n\tcnpj := strings.Map(func(r rune) rune {\n\t\tif r >= '0' && r <= '9' { return r }\n\t\treturn -1\n\t}, fl.Field().String())\n\tif len(cnpj) != 14 || allEqual(cnpj) {\n\t\treturn false\n\t}\n\treturn cnpjChecksum(cnpj)\n}\n\nfunc cnpjChecksum(cnpj string) bool {\n\tweights1 := []int{5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}\n\tweights2 := []int{6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}\n\tfor pass, weights := range [][]int{weights1, weights2} {\n\t\tsum := 0\n\t\tfor i, w := range weights {\n\t\t\td, _ := strconv.Atoi(string(cnpj[i]))\n\t\t\tsum += d * w\n\t\t}\n\t\trem := sum % 11\n\t\texpected := byte('0')\n\t\tif rem >= 2 {\n\t\t\texpected = byte('0' + (11 - rem))\n\t\t}\n\t\tif cnpj[12+pass] != expected {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// validateCRM validates a Brazilian CRM number (digits optionally followed by UF code).\nfunc validateCRM(fl validator.FieldLevel) bool {\n\tcrm := fl.Field().String()\n\treturn len(crm) >= 4 && len(crm) <= 10\n}\n\nfunc allEqual(s string) bool {\n\tif s == \"\" { return false }\n\tfor _, c := range s[1:] {\n\t\tif byte(c) != s[0] { return false }\n\t}\n\treturn true\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> implementations\n\n// services/implementations/auth_service.go\n// Pattern: JWT HS256 token generation + validation service\n// Observed in: Medical-App-Core/services/implementations/auth_service.go\npackage implementations\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/golang-jwt/jwt/v4\"\n\t\"golang.org/x/crypto/bcrypt\"\n)\n\n// Claims holds the JWT payload.\ntype Claims struct {\n\tUserID string `json:\"user_id\"`\n\tEmail  string `json:\"email\"`\n\tRole   string `json:\"role\"`\n\tjwt.RegisteredClaims\n}\n\n// AuthTokenServiceImpl handles JWT creation and validation.\ntype AuthTokenServiceImpl struct {\n\tsecret []byte\n\tttl    time.Duration\n}\n\n// NewAuthTokenService reads JWT_SECRET from the environment and constructs the service.\nfunc NewAuthTokenService() *AuthTokenServiceImpl {\n\tsecret := os.Getenv(\"JWT_SECRET\")\n\tif secret == \"\" {\n\t\tpanic(\"JWT_SECRET environment variable must be set\")\n\t}\n\treturn &AuthTokenServiceImpl{\n\t\tsecret: []byte(secret),\n\t\tttl:    24 * time.Hour,\n\t}\n}\n\n// GenerateToken creates a signed HS256 JWT for the given user attributes.\nfunc (s *AuthTokenServiceImpl) GenerateToken(userID, email, role string) (string, error) {\n\tclaims := &Claims{\n\t\tUserID: userID,\n\t\tEmail:  email,\n\t\tRole:   role,\n\t\tRegisteredClaims: jwt.RegisteredClaims{\n\t\t\tExpiresAt: jwt.NewNumericDate(time.Now().Add(s.ttl)),\n\t\t\tIssuedAt:  jwt.NewNumericDate(time.Now()),\n\t\t\tIssuer:    \"medical-sas-api\",\n\t\t},\n\t}\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\tsigned, err := token.SignedString(s.secret)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"sign token: %w\", err)\n\t}\n\treturn signed, nil\n}\n\n// ValidateToken parses and validates a JWT string. Returns nil on success.\nfunc (s *AuthTokenServiceImpl) ValidateToken(tokenString string) error {\n\ttoken, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(t *jwt.Token) (any, error) {\n\t\tif _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected signing method: %v\", t.Header[\"alg\"])\n\t\t}\n\t\treturn s.secret, nil\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid token: %w\", err)\n\t}\n\tif !token.Valid {\n\t\treturn fmt.Errorf(\"token is not valid\")\n\t}\n\treturn nil\n}\n\n// ParseClaims extracts the Claims from a valid JWT string.\nfunc (s *AuthTokenServiceImpl) ParseClaims(tokenString string) (*Claims, error) {\n\tclaims := &Claims{}\n\t_, err := jwt.ParseWithClaims(tokenString, claims, func(t *jwt.Token) (any, error) {\n\t\treturn s.secret, nil\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse claims: %w\", err)\n\t}\n\treturn claims, nil\n}\n\n// HashPassword returns a bcrypt hash of the plain-text password.\nfunc HashPassword(plain string) (string, error) {\n\thashed, err := bcrypt.GenerateFromPassword([]byte(plain), bcrypt.DefaultCost)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"hash password: %w\", err)\n\t}\n\treturn string(hashed), nil\n}\n\n// CheckPassword returns nil if plain matches the bcrypt hash.\nfunc CheckPassword(plain, hash string) error {\n\tif err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(plain)); err != nil {\n\t\treturn fmt.Errorf(\"invalid credentials\")\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> middleware\n\n// middleware/auth.go\n// Pattern: Fiber JWT bearer middleware with claims propagation via Locals\n// Observed pattern from: Medical-App-Core/cmd/main.go AuthMiddleware\npackage middleware\n\nimport (\n\t\"strings\"\n\n\t\"medical-sas-api/services/implementations\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// BearerAuth validates the Authorization: Bearer header and stores parsed\n// claims in fiber.Ctx.Locals(\"claims\") for downstream handlers.\nfunc BearerAuth(authSvc *implementations.AuthTokenServiceImpl) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif !strings.HasPrefix(header, \"Bearer \") {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\n\t\ttokenStr := strings.TrimPrefix(header, \"Bearer \")\n\t\tclaims, err := authSvc.ParseClaims(tokenStr)\n\t\tif err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\n\t\t// Make claims available to all downstream handlers\n\t\tc.Locals(\"claims\", claims)\n\t\tc.Locals(\"user_id\", claims.UserID)\n\t\tc.Locals(\"role\", claims.Role)\n\t\treturn c.Next()\n\t}\n}\n\n// RoleRequired returns a middleware that allows only the specified roles.\n// Must be chained after BearerAuth.\nfunc RoleRequired(roles ...string) fiber.Handler {\n\tallowed := make(map[string]struct{}, len(roles))\n\tfor _, r := range roles {\n\t\tallowed[r] = struct{}{}\n\t}\n\treturn func(c *fiber.Ctx) error {\n\t\trole, _ := c.Locals(\"role\").(string)\n\t\tif _, ok := allowed[role]; !ok {\n\t\t\treturn c.Status(fiber.StatusForbidden).JSON(fiber.Map{\n\t\t\t\t\"error\": \"insufficient permissions\",\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> controllers\n\n// controllers/auth_controller.go\n// Pattern: login + token generation handler\n// Observed in: Medical-App-Core/controllers/auth_controller.go\npackage controllers\n\nimport (\n\t\"net/http\"\n\n\t\"medical-sas-api/services/implementations\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// AuthController handles token generation and validation endpoints.\ntype AuthController struct {\n\tauthSvc *implementations.AuthTokenServiceImpl\n}\n\nfunc NewAuthController(svc *implementations.AuthTokenServiceImpl) *AuthController {\n\treturn &AuthController{authSvc: svc}\n}\n\ntype generateTokenRequest struct {\n\tUserID string `json:\"user_id\" validate:\"required,uuid4\"`\n\tEmail  string `json:\"email\"   validate:\"required,email\"`\n\tRole   string `json:\"role\"    validate:\"required\"`\n}\n\n// GenerateToken godoc\n// @Summary     Issue a JWT token\n// @Description Generates a signed JWT for the given user credentials\n// @Tags        Auth\n// @Accept      json\n// @Produce     json\n// @Param       body body generateTokenRequest true \"Token request\"\n// @Success     200 {object} fiber.Map{token=string}\n// @Failure     400 {object} fiber.Map\n// @Failure     500 {object} fiber.Map\n// @Router      /auth/token [post]\nfunc (ac *AuthController) GenerateToken(c *fiber.Ctx) error {\n\tvar req generateTokenRequest\n\tif err := c.BodyParser(&req); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\tif req.UserID == \"\" || req.Email == \"\" || req.Role == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"user_id, email, and role are required\"})\n\t}\n\n\ttoken, err := ac.authSvc.GenerateToken(req.UserID, req.Email, req.Role)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to generate token\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\"token\": token})\n}\n\n// ValidateToken godoc\n// @Summary     Validate a JWT token\n// @Description Returns 200 if the token is valid, 401 otherwise\n// @Tags        Auth\n// @Accept      json\n// @Produce     json\n// @Param       body body fiber.Map{token=string} true \"Token to validate\"\n// @Success     200 {object} fiber.Map{valid=bool}\n// @Failure     401 {object} fiber.Map\n// @Router      /auth/validate [post]\nfunc (ac *AuthController) ValidateToken(c *fiber.Ctx) error {\n\tvar body struct {\n\t\tToken string `json:\"token\"`\n\t}\n\tif err := c.BodyParser(&body); err != nil || body.Token == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"token is required\"})\n\t}\n\n\tif err := ac.authSvc.ValidateToken(body.Token); err != nil {\n\t\treturn c.Status(http.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\"valid\":  false,\n\t\t\t\"reason\": err.Error(),\n\t\t})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\"valid\": true})\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> initializers\n\n// initializers/validators.go\n// Pattern: custom validator registration with go-playground/validator\n// Observed in: Medical-App-Core/initializers/validators.go\npackage initializers\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/go-playground/validator/v10\"\n)\n\n// RegisterCustomValidators adds domain-specific validation rules.\nfunc RegisterCustomValidators(v *validator.Validate) {\n\t_ = v.RegisterValidation(\"cpf\",  validateCPF)\n\t_ = v.RegisterValidation(\"cnpj\", validateCNPJ)\n\t_ = v.RegisterValidation(\"crm\",  validateCRM)\n}\n\n// validateCPF validates a Brazilian CPF number (11 digits, checksum).\nfunc validateCPF(fl validator.FieldLevel) bool {\n\tcpf := strings.ReplaceAll(fl.Field().String(), \".\", \"\")\n\tcpf  = strings.ReplaceAll(cpf, \"-\", \"\")\n\tif len(cpf) != 11 || allEqual(cpf) {\n\t\treturn false\n\t}\n\treturn cpfChecksum(cpf)\n}\n\nfunc cpfChecksum(cpf string) bool {\n\tdigits := make([]int, 11)\n\tfor i, ch := range cpf {\n\t\tdigits[i], _ = strconv.Atoi(string(ch))\n\t}\n\tfor pass := 0; pass < 2; pass++ {\n\t\tweight := 10 + pass\n\t\tsum    := 0\n\t\tfor i := 0; i < 9+pass; i++ {\n\t\t\tsum += digits[i] * (weight - i)\n\t\t}\n\t\trem := (sum * 10) % 11\n\t\tif rem == 10 || rem == 11 {\n\t\t\trem = 0\n\t\t}\n\t\tif rem != digits[9+pass] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// validateCNPJ validates a Brazilian CNPJ number (14 digits, checksum).\nfunc validateCNPJ(fl validator.FieldLevel) bool {\n\tcnpj := strings.Map(func(r rune) rune {\n\t\tif r >= '0' && r <= '9' { return r }\n\t\treturn -1\n\t}, fl.Field().String())\n\tif len(cnpj) != 14 || allEqual(cnpj) {\n\t\treturn false\n\t}\n\treturn cnpjChecksum(cnpj)\n}\n\nfunc cnpjChecksum(cnpj string) bool {\n\tweights1 := []int{5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}\n\tweights2 := []int{6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}\n\tfor pass, weights := range [][]int{weights1, weights2} {\n\t\tsum := 0\n\t\tfor i, w := range weights {\n\t\t\td, _ := strconv.Atoi(string(cnpj[i]))\n\t\t\tsum += d * w\n\t\t}\n\t\trem := sum % 11\n\t\texpected := byte('0')\n\t\tif rem >= 2 {\n\t\t\texpected = byte('0' + (11 - rem))\n\t\t}\n\t\tif cnpj[12+pass] != expected {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// validateCRM validates a Brazilian CRM number (digits optionally followed by UF code).\nfunc validateCRM(fl validator.FieldLevel) bool {\n\tcrm := fl.Field().String()\n\treturn len(crm) >= 4 && len(crm) <= 10\n}\n\nfunc allEqual(s string) bool {\n\tif s == \"\" { return false }\n\tfor _, c := range s[1:] {\n\t\tif byte(c) != s[0] { return false }\n\t}\n\treturn true\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> implementations\n\n// services/implementations/auth_service.go\n// Pattern: JWT HS256 token generation + validation service\n// Observed in: Medical-App-Core/services/implementations/auth_service.go\npackage implementations\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/golang-jwt/jwt/v4\"\n\t\"golang.org/x/crypto/bcrypt\"\n)\n\n// Claims holds the JWT payload.\ntype Claims struct {\n\tUserID string `json:\"user_id\"`\n\tEmail  string `json:\"email\"`\n\tRole   string `json:\"role\"`\n\tjwt.RegisteredClaims\n}\n\n// AuthTokenServiceImpl handles JWT creation and validation.\ntype AuthTokenServiceImpl struct {\n\tsecret []byte\n\tttl    time.Duration\n}\n\n// NewAuthTokenService reads JWT_SECRET from the environment and constructs the service.\nfunc NewAuthTokenService() *AuthTokenServiceImpl {\n\tsecret := os.Getenv(\"JWT_SECRET\")\n\tif secret == \"\" {\n\t\tpanic(\"JWT_SECRET environment variable must be set\")\n\t}\n\treturn &AuthTokenServiceImpl{\n\t\tsecret: []byte(secret),\n\t\tttl:    24 * time.Hour,\n\t}\n}\n\n// GenerateToken creates a signed HS256 JWT for the given user attributes.\nfunc (s *AuthTokenServiceImpl) GenerateToken(userID, email, role string) (string, error) {\n\tclaims := &Claims{\n\t\tUserID: userID,\n\t\tEmail:  email,\n\t\tRole:   role,\n\t\tRegisteredClaims: jwt.RegisteredClaims{\n\t\t\tExpiresAt: jwt.NewNumericDate(time.Now().Add(s.ttl)),\n\t\t\tIssuedAt:  jwt.NewNumericDate(time.Now()),\n\t\t\tIssuer:    \"medical-sas-api\",\n\t\t},\n\t}\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\tsigned, err := token.SignedString(s.secret)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"sign token: %w\", err)\n\t}\n\treturn signed, nil\n}\n\n// ValidateToken parses and validates a JWT string. Returns nil on success.\nfunc (s *AuthTokenServiceImpl) ValidateToken(tokenString string) error {\n\ttoken, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(t *jwt.Token) (any, error) {\n\t\tif _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected signing method: %v\", t.Header[\"alg\"])\n\t\t}\n\t\treturn s.secret, nil\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid token: %w\", err)\n\t}\n\tif !token.Valid {\n\t\treturn fmt.Errorf(\"token is not valid\")\n\t}\n\treturn nil\n}\n\n// ParseClaims extracts the Claims from a valid JWT string.\nfunc (s *AuthTokenServiceImpl) ParseClaims(tokenString string) (*Claims, error) {\n\tclaims := &Claims{}\n\t_, err := jwt.ParseWithClaims(tokenString, claims, func(t *jwt.Token) (any, error) {\n\t\treturn s.secret, nil\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse claims: %w\", err)\n\t}\n\treturn claims, nil\n}\n\n// HashPassword returns a bcrypt hash of the plain-text password.\nfunc HashPassword(plain string) (string, error) {\n\thashed, err := bcrypt.GenerateFromPassword([]byte(plain), bcrypt.DefaultCost)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"hash password: %w\", err)\n\t}\n\treturn string(hashed), nil\n}\n\n// CheckPassword returns nil if plain matches the bcrypt hash.\nfunc CheckPassword(plain, hash string) error {\n\tif err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(plain)); err != nil {\n\t\treturn fmt.Errorf(\"invalid credentials\")\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> middleware\n\n// middleware/auth.go\n// Pattern: Fiber JWT bearer middleware with claims propagation via Locals\n// Observed pattern from: Medical-App-Core/cmd/main.go AuthMiddleware\npackage middleware\n\nimport (\n\t\"strings\"\n\n\t\"medical-sas-api/services/implementations\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// BearerAuth validates the Authorization: Bearer header and stores parsed\n// claims in fiber.Ctx.Locals(\"claims\") for downstream handlers.\nfunc BearerAuth(authSvc *implementations.AuthTokenServiceImpl) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif !strings.HasPrefix(header, \"Bearer \") {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\n\t\ttokenStr := strings.TrimPrefix(header, \"Bearer \")\n\t\tclaims, err := authSvc.ParseClaims(tokenStr)\n\t\tif err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\n\t\t// Make claims available to all downstream handlers\n\t\tc.Locals(\"claims\", claims)\n\t\tc.Locals(\"user_id\", claims.UserID)\n\t\tc.Locals(\"role\", claims.Role)\n\t\treturn c.Next()\n\t}\n}\n\n// RoleRequired returns a middleware that allows only the specified roles.\n// Must be chained after BearerAuth.\nfunc RoleRequired(roles ...string) fiber.Handler {\n\tallowed := make(map[string]struct{}, len(roles))\n\tfor _, r := range roles {\n\t\tallowed[r] = struct{}{}\n\t}\n\treturn func(c *fiber.Ctx) error {\n\t\trole, _ := c.Locals(\"role\").(string)\n\t\tif _, ok := allowed[role]; !ok {\n\t\t\treturn c.Status(fiber.StatusForbidden).JSON(fiber.Map{\n\t\t\t\t\"error\": \"insufficient permissions\",\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> controllers\n\n// controllers/auth_controller.go\n// Pattern: login + token generation handler\n// Observed in: Medical-App-Core/controllers/auth_controller.go\npackage controllers\n\nimport (\n\t\"net/http\"\n\n\t\"medical-sas-api/services/implementations\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// AuthController handles token generation and validation endpoints.\ntype AuthController struct {\n\tauthSvc *implementations.AuthTokenServiceImpl\n}\n\nfunc NewAuthController(svc *implementations.AuthTokenServiceImpl) *AuthController {\n\treturn &AuthController{authSvc: svc}\n}\n\ntype generateTokenRequest struct {\n\tUserID string `json:\"user_id\" validate:\"required,uuid4\"`\n\tEmail  string `json:\"email\"   validate:\"required,email\"`\n\tRole   string `json:\"role\"    validate:\"required\"`\n}\n\n// GenerateToken godoc\n// @Summary     Issue a JWT token\n// @Description Generates a signed JWT for the given user credentials\n// @Tags        Auth\n// @Accept      json\n// @Produce     json\n// @Param       body body generateTokenRequest true \"Token request\"\n// @Success     200 {object} fiber.Map{token=string}\n// @Failure     400 {object} fiber.Map\n// @Failure     500 {object} fiber.Map\n// @Router      /auth/token [post]\nfunc (ac *AuthController) GenerateToken(c *fiber.Ctx) error {\n\tvar req generateTokenRequest\n\tif err := c.BodyParser(&req); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\tif req.UserID == \"\" || req.Email == \"\" || req.Role == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"user_id, email, and role are required\"})\n\t}\n\n\ttoken, err := ac.authSvc.GenerateToken(req.UserID, req.Email, req.Role)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to generate token\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\"token\": token})\n}\n\n// ValidateToken godoc\n// @Summary     Validate a JWT token\n// @Description Returns 200 if the token is valid, 401 otherwise\n// @Tags        Auth\n// @Accept      json\n// @Produce     json\n// @Param       body body fiber.Map{token=string} true \"Token to validate\"\n// @Success     200 {object} fiber.Map{valid=bool}\n// @Failure     401 {object} fiber.Map\n// @Router      /auth/validate [post]\nfunc (ac *AuthController) ValidateToken(c *fiber.Ctx) error {\n\tvar body struct {\n\t\tToken string `json:\"token\"`\n\t}\n\tif err := c.BodyParser(&body); err != nil || body.Token == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"token is required\"})\n\t}\n\n\tif err := ac.authSvc.ValidateToken(body.Token); err != nil {\n\t\treturn c.Status(http.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\"valid\":  false,\n\t\t\t\"reason\": err.Error(),\n\t\t})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\"valid\": true})\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> initializers\n\n// initializers/validators.go\n// Pattern: custom validator registration with go-playground/validator\n// Observed in: Medical-App-Core/initializers/validators.go\npackage initializers\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/go-playground/validator/v10\"\n)\n\n// RegisterCustomValidators adds domain-specific validation rules.\nfunc RegisterCustomValidators(v *validator.Validate) {\n\t_ = v.RegisterValidation(\"cpf\",  validateCPF)\n\t_ = v.RegisterValidation(\"cnpj\", validateCNPJ)\n\t_ = v.RegisterValidation(\"crm\",  validateCRM)\n}\n\n// validateCPF validates a Brazilian CPF number (11 digits, checksum).\nfunc validateCPF(fl validator.FieldLevel) bool {\n\tcpf := strings.ReplaceAll(fl.Field().String(), \".\", \"\")\n\tcpf  = strings.ReplaceAll(cpf, \"-\", \"\")\n\tif len(cpf) != 11 || allEqual(cpf) {\n\t\treturn false\n\t}\n\treturn cpfChecksum(cpf)\n}\n\nfunc cpfChecksum(cpf string) bool {\n\tdigits := make([]int, 11)\n\tfor i, ch := range cpf {\n\t\tdigits[i], _ = strconv.Atoi(string(ch))\n\t}\n\tfor pass := 0; pass < 2; pass++ {\n\t\tweight := 10 + pass\n\t\tsum    := 0\n\t\tfor i := 0; i < 9+pass; i++ {\n\t\t\tsum += digits[i] * (weight - i)\n\t\t}\n\t\trem := (sum * 10) % 11\n\t\tif rem == 10 || rem == 11 {\n\t\t\trem = 0\n\t\t}\n\t\tif rem != digits[9+pass] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// validateCNPJ validates a Brazilian CNPJ number (14 digits, checksum).\nfunc validateCNPJ(fl validator.FieldLevel) bool {\n\tcnpj := strings.Map(func(r rune) rune {\n\t\tif r >= '0' && r <= '9' { return r }\n\t\treturn -1\n\t}, fl.Field().String())\n\tif len(cnpj) != 14 || allEqual(cnpj) {\n\t\treturn false\n\t}\n\treturn cnpjChecksum(cnpj)\n}\n\nfunc cnpjChecksum(cnpj string) bool {\n\tweights1 := []int{5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}\n\tweights2 := []int{6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}\n\tfor pass, weights := range [][]int{weights1, weights2} {\n\t\tsum := 0\n\t\tfor i, w := range weights {\n\t\t\td, _ := strconv.Atoi(string(cnpj[i]))\n\t\t\tsum += d * w\n\t\t}\n\t\trem := sum % 11\n\t\texpected := byte('0')\n\t\tif rem >= 2 {\n\t\t\texpected = byte('0' + (11 - rem))\n\t\t}\n\t\tif cnpj[12+pass] != expected {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// validateCRM validates a Brazilian CRM number (digits optionally followed by UF code).\nfunc validateCRM(fl validator.FieldLevel) bool {\n\tcrm := fl.Field().String()\n\treturn len(crm) >= 4 && len(crm) <= 10\n}\n\nfunc allEqual(s string) bool {\n\tif s == \"\" { return false }\n\tfor _, c := range s[1:] {\n\t\tif byte(c) != s[0] { return false }\n\t}\n\treturn true\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> implementations\n\n// services/implementations/auth_service.go\n// Pattern: JWT HS256 token generation + validation service\n// Observed in: Medical-App-Core/services/implementations/auth_service.go\npackage implementations\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/golang-jwt/jwt/v4\"\n\t\"golang.org/x/crypto/bcrypt\"\n)\n\n// Claims holds the JWT payload.\ntype Claims struct {\n\tUserID string `json:\"user_id\"`\n\tEmail  string `json:\"email\"`\n\tRole   string `json:\"role\"`\n\tjwt.RegisteredClaims\n}\n\n// AuthTokenServiceImpl handles JWT creation and validation.\ntype AuthTokenServiceImpl struct {\n\tsecret []byte\n\tttl    time.Duration\n}\n\n// NewAuthTokenService reads JWT_SECRET from the environment and constructs the service.\nfunc NewAuthTokenService() *AuthTokenServiceImpl {\n\tsecret := os.Getenv(\"JWT_SECRET\")\n\tif secret == \"\" {\n\t\tpanic(\"JWT_SECRET environment variable must be set\")\n\t}\n\treturn &AuthTokenServiceImpl{\n\t\tsecret: []byte(secret),\n\t\tttl:    24 * time.Hour,\n\t}\n}\n\n// GenerateToken creates a signed HS256 JWT for the given user attributes.\nfunc (s *AuthTokenServiceImpl) GenerateToken(userID, email, role string) (string, error) {\n\tclaims := &Claims{\n\t\tUserID: userID,\n\t\tEmail:  email,\n\t\tRole:   role,\n\t\tRegisteredClaims: jwt.RegisteredClaims{\n\t\t\tExpiresAt: jwt.NewNumericDate(time.Now().Add(s.ttl)),\n\t\t\tIssuedAt:  jwt.NewNumericDate(time.Now()),\n\t\t\tIssuer:    \"medical-sas-api\",\n\t\t},\n\t}\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\tsigned, err := token.SignedString(s.secret)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"sign token: %w\", err)\n\t}\n\treturn signed, nil\n}\n\n// ValidateToken parses and validates a JWT string. Returns nil on success.\nfunc (s *AuthTokenServiceImpl) ValidateToken(tokenString string) error {\n\ttoken, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(t *jwt.Token) (any, error) {\n\t\tif _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected signing method: %v\", t.Header[\"alg\"])\n\t\t}\n\t\treturn s.secret, nil\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid token: %w\", err)\n\t}\n\tif !token.Valid {\n\t\treturn fmt.Errorf(\"token is not valid\")\n\t}\n\treturn nil\n}\n\n// ParseClaims extracts the Claims from a valid JWT string.\nfunc (s *AuthTokenServiceImpl) ParseClaims(tokenString string) (*Claims, error) {\n\tclaims := &Claims{}\n\t_, err := jwt.ParseWithClaims(tokenString, claims, func(t *jwt.Token) (any, error) {\n\t\treturn s.secret, nil\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse claims: %w\", err)\n\t}\n\treturn claims, nil\n}\n\n// HashPassword returns a bcrypt hash of the plain-text password.\nfunc HashPassword(plain string) (string, error) {\n\thashed, err := bcrypt.GenerateFromPassword([]byte(plain), bcrypt.DefaultCost)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"hash password: %w\", err)\n\t}\n\treturn string(hashed), nil\n}\n\n// CheckPassword returns nil if plain matches the bcrypt hash.\nfunc CheckPassword(plain, hash string) error {\n\tif err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(plain)); err != nil {\n\t\treturn fmt.Errorf(\"invalid credentials\")\n\t}\n\treturn nil\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> middleware\n\n// middleware/auth.go\n// Pattern: Fiber JWT bearer middleware with claims propagation via Locals\n// Observed pattern from: Medical-App-Core/cmd/main.go AuthMiddleware\npackage middleware\n\nimport (\n\t\"strings\"\n\n\t\"medical-sas-api/services/implementations\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// BearerAuth validates the Authorization: Bearer header and stores parsed\n// claims in fiber.Ctx.Locals(\"claims\") for downstream handlers.\nfunc BearerAuth(authSvc *implementations.AuthTokenServiceImpl) fiber.Handler {\n\treturn func(c *fiber.Ctx) error {\n\t\theader := c.Get(\"Authorization\")\n\t\tif !strings.HasPrefix(header, \"Bearer \") {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\": \"missing or malformed Authorization header\",\n\t\t\t})\n\t\t}\n\n\t\ttokenStr := strings.TrimPrefix(header, \"Bearer \")\n\t\tclaims, err := authSvc.ParseClaims(tokenStr)\n\t\tif err != nil {\n\t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\t\"error\":  \"invalid or expired token\",\n\t\t\t\t\"reason\": err.Error(),\n\t\t\t})\n\t\t}\n\n\t\t// Make claims available to all downstream handlers\n\t\tc.Locals(\"claims\", claims)\n\t\tc.Locals(\"user_id\", claims.UserID)\n\t\tc.Locals(\"role\", claims.Role)\n\t\treturn c.Next()\n\t}\n}\n\n// RoleRequired returns a middleware that allows only the specified roles.\n// Must be chained after BearerAuth.\nfunc RoleRequired(roles ...string) fiber.Handler {\n\tallowed := make(map[string]struct{}, len(roles))\n\tfor _, r := range roles {\n\t\tallowed[r] = struct{}{}\n\t}\n\treturn func(c *fiber.Ctx) error {\n\t\trole, _ := c.Locals(\"role\").(string)\n\t\tif _, ok := allowed[role]; !ok {\n\t\t\treturn c.Status(fiber.StatusForbidden).JSON(fiber.Map{\n\t\t\t\t\"error\": \"insufficient permissions\",\n\t\t\t})\n\t\t}\n\t\treturn c.Next()\n\t}\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> controllers\n\n// controllers/auth_controller.go\n// Pattern: login + token generation handler\n// Observed in: Medical-App-Core/controllers/auth_controller.go\npackage controllers\n\nimport (\n\t\"net/http\"\n\n\t\"medical-sas-api/services/implementations\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\n// AuthController handles token generation and validation endpoints.\ntype AuthController struct {\n\tauthSvc *implementations.AuthTokenServiceImpl\n}\n\nfunc NewAuthController(svc *implementations.AuthTokenServiceImpl) *AuthController {\n\treturn &AuthController{authSvc: svc}\n}\n\ntype generateTokenRequest struct {\n\tUserID string `json:\"user_id\" validate:\"required,uuid4\"`\n\tEmail  string `json:\"email\"   validate:\"required,email\"`\n\tRole   string `json:\"role\"    validate:\"required\"`\n}\n\n// GenerateToken godoc\n// @Summary     Issue a JWT token\n// @Description Generates a signed JWT for the given user credentials\n// @Tags        Auth\n// @Accept      json\n// @Produce     json\n// @Param       body body generateTokenRequest true \"Token request\"\n// @Success     200 {object} fiber.Map{token=string}\n// @Failure     400 {object} fiber.Map\n// @Failure     500 {object} fiber.Map\n// @Router      /auth/token [post]\nfunc (ac *AuthController) GenerateToken(c *fiber.Ctx) error {\n\tvar req generateTokenRequest\n\tif err := c.BodyParser(&req); err != nil {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"invalid request payload\"})\n\t}\n\tif req.UserID == \"\" || req.Email == \"\" || req.Role == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"user_id, email, and role are required\"})\n\t}\n\n\ttoken, err := ac.authSvc.GenerateToken(req.UserID, req.Email, req.Role)\n\tif err != nil {\n\t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{\"error\": \"failed to generate token\"})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\"token\": token})\n}\n\n// ValidateToken godoc\n// @Summary     Validate a JWT token\n// @Description Returns 200 if the token is valid, 401 otherwise\n// @Tags        Auth\n// @Accept      json\n// @Produce     json\n// @Param       body body fiber.Map{token=string} true \"Token to validate\"\n// @Success     200 {object} fiber.Map{valid=bool}\n// @Failure     401 {object} fiber.Map\n// @Router      /auth/validate [post]\nfunc (ac *AuthController) ValidateToken(c *fiber.Ctx) error {\n\tvar body struct {\n\t\tToken string `json:\"token\"`\n\t}\n\tif err := c.BodyParser(&body); err != nil || body.Token == \"\" {\n\t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{\"error\": \"token is required\"})\n\t}\n\n\tif err := ac.authSvc.ValidateToken(body.Token); err != nil {\n\t\treturn c.Status(http.StatusUnauthorized).JSON(fiber.Map{\n\t\t\t\"valid\":  false,\n\t\t\t\"reason\": err.Error(),\n\t\t})\n\t}\n\n\treturn c.Status(http.StatusOK).JSON(fiber.Map{\"valid\": true})\n}\n</go_file>\n"}
{"category": "auth", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> initializers\n\n// initializers/validators.go\n// Pattern: custom validator registration with go-playground/validator\n// Observed in: Medical-App-Core/initializers/validators.go\npackage initializers\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/go-playground/validator/v10\"\n)\n\n// RegisterCustomValidators adds domain-specific validation rules.\nfunc RegisterCustomValidators(v *validator.Validate) {\n\t_ = v.RegisterValidation(\"cpf\",  validateCPF)\n\t_ = v.RegisterValidation(\"cnpj\", validateCNPJ)\n\t_ = v.RegisterValidation(\"crm\",  validateCRM)\n}\n\n// validateCPF validates a Brazilian CPF number (11 digits, checksum).\nfunc validateCPF(fl validator.FieldLevel) bool {\n\tcpf := strings.ReplaceAll(fl.Field().String(), \".\", \"\")\n\tcpf  = strings.ReplaceAll(cpf, \"-\", \"\")\n\tif len(cpf) != 11 || allEqual(cpf) {\n\t\treturn false\n\t}\n\treturn cpfChecksum(cpf)\n}\n\nfunc cpfChecksum(cpf string) bool {\n\tdigits := make([]int, 11)\n\tfor i, ch := range cpf {\n\t\tdigits[i], _ = strconv.Atoi(string(ch))\n\t}\n\tfor pass := 0; pass < 2; pass++ {\n\t\tweight := 10 + pass\n\t\tsum    := 0\n\t\tfor i := 0; i < 9+pass; i++ {\n\t\t\tsum += digits[i] * (weight - i)\n\t\t}\n\t\trem := (sum * 10) % 11\n\t\tif rem == 10 || rem == 11 {\n\t\t\trem = 0\n\t\t}\n\t\tif rem != digits[9+pass] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// validateCNPJ validates a Brazilian CNPJ number (14 digits, checksum).\nfunc validateCNPJ(fl validator.FieldLevel) bool {\n\tcnpj := strings.Map(func(r rune) rune {\n\t\tif r >= '0' && r <= '9' { return r }\n\t\treturn -1\n\t}, fl.Field().String())\n\tif len(cnpj) != 14 || allEqual(cnpj) {\n\t\treturn false\n\t}\n\treturn cnpjChecksum(cnpj)\n}\n\nfunc cnpjChecksum(cnpj string) bool {\n\tweights1 := []int{5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}\n\tweights2 := []int{6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2}\n\tfor pass, weights := range [][]int{weights1, weights2} {\n\t\tsum := 0\n\t\tfor i, w := range weights {\n\t\t\td, _ := strconv.Atoi(string(cnpj[i]))\n\t\t\tsum += d * w\n\t\t}\n\t\trem := sum % 11\n\t\texpected := byte('0')\n\t\tif rem >= 2 {\n\t\t\texpected = byte('0' + (11 - rem))\n\t\t}\n\t\tif cnpj[12+pass] != expected {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// validateCRM validates a Brazilian CRM number (digits optionally followed by UF code).\nfunc validateCRM(fl validator.FieldLevel) bool {\n\tcrm := fl.Field().String()\n\treturn len(crm) >= 4 && len(crm) <= 10\n}\n\nfunc allEqual(s string) bool {\n\tif s == \"\" { return false }\n\tfor _, c := range s[1:] {\n\t\tif byte(c) != s[0] { return false }\n\t}\n\treturn true\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> implementations_test\n\n// services/implementations/appointment_service_test.go\n// Pattern: sqlmock + GORM + testify β€” success and error paths\n// Observed in: Medical-App-Core/services/implementations/appointment_service_test.go\npackage implementations_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"medical-sas-api/services/implementations\"\n\n\t\"github.com/DATA-DOG/go-sqlmock\"\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\n// setupTestDB creates an in-memory mock database for service tests.\n// Returns the GORM DB and the sqlmock controller for expectation setup.\nfunc setupTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {\n\tt.Helper()\n\tdb, mock, err := sqlmock.New()\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create mock DB: %v\", err)\n\t}\n\tgormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})\n\tif err != nil {\n\t\tt.Fatalf(\"failed to open GORM DB: %v\", err)\n\t}\n\tt.Cleanup(func() { db.Close() })\n\treturn gormDB, mock\n}\n\n// TestCreate_Success verifies that a valid DTO produces a non-nil UUID.\nfunc TestAppointmentService_Create_Success(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tdto := contracts.AppointmentDTO{\n\t\tOrganizationID: uuid.New(),\n\t\tPatientID:      uuid.New(),\n\t\tDoctorID:       uuid.New(),\n\t\tDateTime:       time.Now(),\n\t\tStatus:         \"scheduled\",\n\t}\n\n\tnewID := uuid.New()\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"appointments\" .* RETURNING \"id\"`).\n\t\tWithArgs(\n\t\t\tsqlmock.AnyArg(), // created_at\n\t\t\tsqlmock.AnyArg(), // updated_at\n\t\t\tnil,              // deleted_at\n\t\t\tsqlmock.AnyArg(), // organization_id\n\t\t\tsqlmock.AnyArg(), // patient_id\n\t\t\tsqlmock.AnyArg(), // doctor_id\n\t\t\tsqlmock.AnyArg(), // date_time\n\t\t\t\"scheduled\",      // status\n\t\t\tsqlmock.AnyArg(), // id\n\t\t).\n\t\tWillReturnRows(sqlmock.NewRows([]string{\"id\"}).AddRow(newID))\n\tmock.ExpectCommit()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, newID, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestAppointmentService_Create_DBError verifies the service surfaces DB errors.\nfunc TestAppointmentService_Create_DBError(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tdto := contracts.AppointmentDTO{\n\t\tOrganizationID: uuid.New(),\n\t\tPatientID:      uuid.New(),\n\t\tDoctorID:       uuid.New(),\n\t\tDateTime:       time.Now(),\n\t\tStatus:         \"scheduled\",\n\t}\n\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"appointments\" .* RETURNING \"id\"`).\n\t\tWillReturnError(errors.New(\"connection refused\"))\n\tmock.ExpectRollback()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.Error(t, err)\n\tassert.Equal(t, uuid.Nil, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestAppointmentService_FindByStatus_NotFound verifies gorm.ErrRecordNotFound is surfaced.\nfunc TestAppointmentService_FindByStatus_NotFound(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tmock.ExpectQuery(`SELECT .* FROM \"appointments\"`).\n\t\tWithArgs(\"NOTEXIST\", sqlmock.AnyArg()).\n\t\tWillReturnError(gorm.ErrRecordNotFound)\n\n\tresult, err := svc.FindByStatus(\"NOTEXIST\")\n\n\tassert.Error(t, err)\n\tassert.Nil(t, result)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> controllers_test\n\n// controllers/appointment_controller_test.go\n// Pattern: Fiber app.Test() for HTTP handler unit testing\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage controllers_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/controllers\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// mockAppointmentService implements contracts.AppointmentServiceContract for testing.\ntype mockAppointmentService struct {\n\tcreateResult string\n\tcreateErr    error\n}\n\nfunc (m *mockAppointmentService) CreateFromInput(input any) (any, error) {\n\treturn m.createResult, m.createErr\n}\n\nfunc TestAppointmentController_Create_Success(t *testing.T) {\n\tapp := fiber.New()\n\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{\n\t\tcreateResult: \"test-uuid\",\n\t})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\tbody, _ := json.Marshal(map[string]any{\n\t\t\"organization_name\": \"Test Org\",\n\t\t\"patient_name\":    \"JoΓ£o Silva\",\n\t\t\"doctor_full_name\": \"Dr. Maria\",\n\t\t\"specialization\":  \"Cardiology\",\n\t\t\"date_time\":       \"2024-03-01T10:00:00Z\",\n\t})\n\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusCreated, resp.StatusCode)\n\n\tvar result map[string]any\n\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&result))\n\trequire.Equal(t, \"Appointment created successfully\", result[\"message\"])\n}\n\nfunc TestAppointmentController_Create_MissingField(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\t// Send empty body β€” required fields missing\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader([]byte(\"{}\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n\nfunc TestAppointmentController_Create_InvalidJSON(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader([]byte(\"not json\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> implementations_test\n\n// services/implementations/appointment_service_test.go\n// Pattern: sqlmock + GORM + testify β€” success and error paths\n// Observed in: Medical-App-Core/services/implementations/appointment_service_test.go\npackage implementations_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"medical-sas-api/services/implementations\"\n\n\t\"github.com/DATA-DOG/go-sqlmock\"\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\n// setupTestDB creates an in-memory mock database for service tests.\n// Returns the GORM DB and the sqlmock controller for expectation setup.\nfunc setupTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {\n\tt.Helper()\n\tdb, mock, err := sqlmock.New()\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create mock DB: %v\", err)\n\t}\n\tgormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})\n\tif err != nil {\n\t\tt.Fatalf(\"failed to open GORM DB: %v\", err)\n\t}\n\tt.Cleanup(func() { db.Close() })\n\treturn gormDB, mock\n}\n\n// TestCreate_Success verifies that a valid DTO produces a non-nil UUID.\nfunc TestAppointmentService_Create_Success(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tdto := contracts.AppointmentDTO{\n\t\tOrganizationID: uuid.New(),\n\t\tPatientID:      uuid.New(),\n\t\tDoctorID:       uuid.New(),\n\t\tDateTime:       time.Now(),\n\t\tStatus:         \"scheduled\",\n\t}\n\n\tnewID := uuid.New()\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"appointments\" .* RETURNING \"id\"`).\n\t\tWithArgs(\n\t\t\tsqlmock.AnyArg(), // created_at\n\t\t\tsqlmock.AnyArg(), // updated_at\n\t\t\tnil,              // deleted_at\n\t\t\tsqlmock.AnyArg(), // organization_id\n\t\t\tsqlmock.AnyArg(), // patient_id\n\t\t\tsqlmock.AnyArg(), // doctor_id\n\t\t\tsqlmock.AnyArg(), // date_time\n\t\t\t\"scheduled\",      // status\n\t\t\tsqlmock.AnyArg(), // id\n\t\t).\n\t\tWillReturnRows(sqlmock.NewRows([]string{\"id\"}).AddRow(newID))\n\tmock.ExpectCommit()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, newID, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestAppointmentService_Create_DBError verifies the service surfaces DB errors.\nfunc TestAppointmentService_Create_DBError(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tdto := contracts.AppointmentDTO{\n\t\tOrganizationID: uuid.New(),\n\t\tPatientID:      uuid.New(),\n\t\tDoctorID:       uuid.New(),\n\t\tDateTime:       time.Now(),\n\t\tStatus:         \"scheduled\",\n\t}\n\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"appointments\" .* RETURNING \"id\"`).\n\t\tWillReturnError(errors.New(\"connection refused\"))\n\tmock.ExpectRollback()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.Error(t, err)\n\tassert.Equal(t, uuid.Nil, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestAppointmentService_FindByStatus_NotFound verifies gorm.ErrRecordNotFound is surfaced.\nfunc TestAppointmentService_FindByStatus_NotFound(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tmock.ExpectQuery(`SELECT .* FROM \"appointments\"`).\n\t\tWithArgs(\"NOTEXIST\", sqlmock.AnyArg()).\n\t\tWillReturnError(gorm.ErrRecordNotFound)\n\n\tresult, err := svc.FindByStatus(\"NOTEXIST\")\n\n\tassert.Error(t, err)\n\tassert.Nil(t, result)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> controllers_test\n\n// controllers/appointment_controller_test.go\n// Pattern: Fiber app.Test() for HTTP handler unit testing\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage controllers_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/controllers\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// mockAppointmentService implements contracts.AppointmentServiceContract for testing.\ntype mockAppointmentService struct {\n\tcreateResult string\n\tcreateErr    error\n}\n\nfunc (m *mockAppointmentService) CreateFromInput(input any) (any, error) {\n\treturn m.createResult, m.createErr\n}\n\nfunc TestAppointmentController_Create_Success(t *testing.T) {\n\tapp := fiber.New()\n\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{\n\t\tcreateResult: \"test-uuid\",\n\t})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\tbody, _ := json.Marshal(map[string]any{\n\t\t\"organization_name\": \"Test Org\",\n\t\t\"patient_name\":    \"JoΓ£o Silva\",\n\t\t\"doctor_full_name\": \"Dr. Maria\",\n\t\t\"specialization\":  \"Cardiology\",\n\t\t\"date_time\":       \"2024-03-01T10:00:00Z\",\n\t})\n\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusCreated, resp.StatusCode)\n\n\tvar result map[string]any\n\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&result))\n\trequire.Equal(t, \"Appointment created successfully\", result[\"message\"])\n}\n\nfunc TestAppointmentController_Create_MissingField(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\t// Send empty body β€” required fields missing\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader([]byte(\"{}\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n\nfunc TestAppointmentController_Create_InvalidJSON(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader([]byte(\"not json\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> implementations_test\n\n// services/implementations/appointment_service_test.go\n// Pattern: sqlmock + GORM + testify β€” success and error paths\n// Observed in: Medical-App-Core/services/implementations/appointment_service_test.go\npackage implementations_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"medical-sas-api/services/implementations\"\n\n\t\"github.com/DATA-DOG/go-sqlmock\"\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\n// setupTestDB creates an in-memory mock database for service tests.\n// Returns the GORM DB and the sqlmock controller for expectation setup.\nfunc setupTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {\n\tt.Helper()\n\tdb, mock, err := sqlmock.New()\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create mock DB: %v\", err)\n\t}\n\tgormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})\n\tif err != nil {\n\t\tt.Fatalf(\"failed to open GORM DB: %v\", err)\n\t}\n\tt.Cleanup(func() { db.Close() })\n\treturn gormDB, mock\n}\n\n// TestCreate_Success verifies that a valid DTO produces a non-nil UUID.\nfunc TestAppointmentService_Create_Success(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tdto := contracts.AppointmentDTO{\n\t\tOrganizationID: uuid.New(),\n\t\tPatientID:      uuid.New(),\n\t\tDoctorID:       uuid.New(),\n\t\tDateTime:       time.Now(),\n\t\tStatus:         \"scheduled\",\n\t}\n\n\tnewID := uuid.New()\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"appointments\" .* RETURNING \"id\"`).\n\t\tWithArgs(\n\t\t\tsqlmock.AnyArg(), // created_at\n\t\t\tsqlmock.AnyArg(), // updated_at\n\t\t\tnil,              // deleted_at\n\t\t\tsqlmock.AnyArg(), // organization_id\n\t\t\tsqlmock.AnyArg(), // patient_id\n\t\t\tsqlmock.AnyArg(), // doctor_id\n\t\t\tsqlmock.AnyArg(), // date_time\n\t\t\t\"scheduled\",      // status\n\t\t\tsqlmock.AnyArg(), // id\n\t\t).\n\t\tWillReturnRows(sqlmock.NewRows([]string{\"id\"}).AddRow(newID))\n\tmock.ExpectCommit()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, newID, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestAppointmentService_Create_DBError verifies the service surfaces DB errors.\nfunc TestAppointmentService_Create_DBError(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tdto := contracts.AppointmentDTO{\n\t\tOrganizationID: uuid.New(),\n\t\tPatientID:      uuid.New(),\n\t\tDoctorID:       uuid.New(),\n\t\tDateTime:       time.Now(),\n\t\tStatus:         \"scheduled\",\n\t}\n\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"appointments\" .* RETURNING \"id\"`).\n\t\tWillReturnError(errors.New(\"connection refused\"))\n\tmock.ExpectRollback()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.Error(t, err)\n\tassert.Equal(t, uuid.Nil, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestAppointmentService_FindByStatus_NotFound verifies gorm.ErrRecordNotFound is surfaced.\nfunc TestAppointmentService_FindByStatus_NotFound(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tmock.ExpectQuery(`SELECT .* FROM \"appointments\"`).\n\t\tWithArgs(\"NOTEXIST\", sqlmock.AnyArg()).\n\t\tWillReturnError(gorm.ErrRecordNotFound)\n\n\tresult, err := svc.FindByStatus(\"NOTEXIST\")\n\n\tassert.Error(t, err)\n\tassert.Nil(t, result)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> controllers_test\n\n// controllers/appointment_controller_test.go\n// Pattern: Fiber app.Test() for HTTP handler unit testing\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage controllers_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/controllers\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// mockAppointmentService implements contracts.AppointmentServiceContract for testing.\ntype mockAppointmentService struct {\n\tcreateResult string\n\tcreateErr    error\n}\n\nfunc (m *mockAppointmentService) CreateFromInput(input any) (any, error) {\n\treturn m.createResult, m.createErr\n}\n\nfunc TestAppointmentController_Create_Success(t *testing.T) {\n\tapp := fiber.New()\n\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{\n\t\tcreateResult: \"test-uuid\",\n\t})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\tbody, _ := json.Marshal(map[string]any{\n\t\t\"organization_name\": \"Test Org\",\n\t\t\"patient_name\":    \"JoΓ£o Silva\",\n\t\t\"doctor_full_name\": \"Dr. Maria\",\n\t\t\"specialization\":  \"Cardiology\",\n\t\t\"date_time\":       \"2024-03-01T10:00:00Z\",\n\t})\n\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusCreated, resp.StatusCode)\n\n\tvar result map[string]any\n\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&result))\n\trequire.Equal(t, \"Appointment created successfully\", result[\"message\"])\n}\n\nfunc TestAppointmentController_Create_MissingField(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\t// Send empty body β€” required fields missing\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader([]byte(\"{}\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n\nfunc TestAppointmentController_Create_InvalidJSON(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader([]byte(\"not json\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> implementations_test\n\n// services/implementations/appointment_service_test.go\n// Pattern: sqlmock + GORM + testify β€” success and error paths\n// Observed in: Medical-App-Core/services/implementations/appointment_service_test.go\npackage implementations_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"medical-sas-api/services/implementations\"\n\n\t\"github.com/DATA-DOG/go-sqlmock\"\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\n// setupTestDB creates an in-memory mock database for service tests.\n// Returns the GORM DB and the sqlmock controller for expectation setup.\nfunc setupTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {\n\tt.Helper()\n\tdb, mock, err := sqlmock.New()\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create mock DB: %v\", err)\n\t}\n\tgormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})\n\tif err != nil {\n\t\tt.Fatalf(\"failed to open GORM DB: %v\", err)\n\t}\n\tt.Cleanup(func() { db.Close() })\n\treturn gormDB, mock\n}\n\n// TestCreate_Success verifies that a valid DTO produces a non-nil UUID.\nfunc TestAppointmentService_Create_Success(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tdto := contracts.AppointmentDTO{\n\t\tOrganizationID: uuid.New(),\n\t\tPatientID:      uuid.New(),\n\t\tDoctorID:       uuid.New(),\n\t\tDateTime:       time.Now(),\n\t\tStatus:         \"scheduled\",\n\t}\n\n\tnewID := uuid.New()\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"appointments\" .* RETURNING \"id\"`).\n\t\tWithArgs(\n\t\t\tsqlmock.AnyArg(), // created_at\n\t\t\tsqlmock.AnyArg(), // updated_at\n\t\t\tnil,              // deleted_at\n\t\t\tsqlmock.AnyArg(), // organization_id\n\t\t\tsqlmock.AnyArg(), // patient_id\n\t\t\tsqlmock.AnyArg(), // doctor_id\n\t\t\tsqlmock.AnyArg(), // date_time\n\t\t\t\"scheduled\",      // status\n\t\t\tsqlmock.AnyArg(), // id\n\t\t).\n\t\tWillReturnRows(sqlmock.NewRows([]string{\"id\"}).AddRow(newID))\n\tmock.ExpectCommit()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, newID, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestAppointmentService_Create_DBError verifies the service surfaces DB errors.\nfunc TestAppointmentService_Create_DBError(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tdto := contracts.AppointmentDTO{\n\t\tOrganizationID: uuid.New(),\n\t\tPatientID:      uuid.New(),\n\t\tDoctorID:       uuid.New(),\n\t\tDateTime:       time.Now(),\n\t\tStatus:         \"scheduled\",\n\t}\n\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"appointments\" .* RETURNING \"id\"`).\n\t\tWillReturnError(errors.New(\"connection refused\"))\n\tmock.ExpectRollback()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.Error(t, err)\n\tassert.Equal(t, uuid.Nil, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestAppointmentService_FindByStatus_NotFound verifies gorm.ErrRecordNotFound is surfaced.\nfunc TestAppointmentService_FindByStatus_NotFound(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewAppointmentService(db)\n\n\tmock.ExpectQuery(`SELECT .* FROM \"appointments\"`).\n\t\tWithArgs(\"NOTEXIST\", sqlmock.AnyArg()).\n\t\tWillReturnError(gorm.ErrRecordNotFound)\n\n\tresult, err := svc.FindByStatus(\"NOTEXIST\")\n\n\tassert.Error(t, err)\n\tassert.Nil(t, result)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> controllers_test\n\n// controllers/appointment_controller_test.go\n// Pattern: Fiber app.Test() for HTTP handler unit testing\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage controllers_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/controllers\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// mockAppointmentService implements contracts.AppointmentServiceContract for testing.\ntype mockAppointmentService struct {\n\tcreateResult string\n\tcreateErr    error\n}\n\nfunc (m *mockAppointmentService) CreateFromInput(input any) (any, error) {\n\treturn m.createResult, m.createErr\n}\n\nfunc TestAppointmentController_Create_Success(t *testing.T) {\n\tapp := fiber.New()\n\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{\n\t\tcreateResult: \"test-uuid\",\n\t})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\tbody, _ := json.Marshal(map[string]any{\n\t\t\"organization_name\": \"Test Org\",\n\t\t\"patient_name\":    \"JoΓ£o Silva\",\n\t\t\"doctor_full_name\": \"Dr. Maria\",\n\t\t\"specialization\":  \"Cardiology\",\n\t\t\"date_time\":       \"2024-03-01T10:00:00Z\",\n\t})\n\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusCreated, resp.StatusCode)\n\n\tvar result map[string]any\n\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&result))\n\trequire.Equal(t, \"Appointment created successfully\", result[\"message\"])\n}\n\nfunc TestAppointmentController_Create_MissingField(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\t// Send empty body β€” required fields missing\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader([]byte(\"{}\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n\nfunc TestAppointmentController_Create_InvalidJSON(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewAppointmentController(&mockAppointmentService{})\n\tapp.Post(\"/appointments\", ctrl.CreateAppointment)\n\n\treq := httptest.NewRequest(http.MethodPost, \"/appointments\", bytes.NewReader([]byte(\"not json\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> implementations_test\n\n// services/implementations/patient_service_test.go\n// Pattern: sqlmock + GORM + testify β€” success and error paths\n// Observed in: Medical-App-Core/services/implementations/appointment_service_test.go\npackage implementations_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"medical-sas-api/services/implementations\"\n\n\t\"github.com/DATA-DOG/go-sqlmock\"\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\n// setupTestDB creates an in-memory mock database for service tests.\n// Returns the GORM DB and the sqlmock controller for expectation setup.\nfunc setupTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {\n\tt.Helper()\n\tdb, mock, err := sqlmock.New()\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create mock DB: %v\", err)\n\t}\n\tgormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})\n\tif err != nil {\n\t\tt.Fatalf(\"failed to open GORM DB: %v\", err)\n\t}\n\tt.Cleanup(func() { db.Close() })\n\treturn gormDB, mock\n}\n\n// TestCreate_Success verifies that a valid DTO produces a non-nil UUID.\nfunc TestPatientService_Create_Success(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tdto := contracts.PatientDTO{\n\t\tOrganizationID: uuid.New().String(),\n\t\tName:           \"JoΓ£o Silva\",\n\t\tContact:        \"+55 11 99999-9999\",\n\t}\n\n\tnewID := uuid.New()\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"patients\" .* RETURNING \"id\"`).\n\t\tWithArgs(\n\t\t\tsqlmock.AnyArg(), // created_at\n\t\t\tsqlmock.AnyArg(), // updated_at\n\t\t\tnil,              // deleted_at\n\t\t\tsqlmock.AnyArg(), // organization_id\n\t\t\t\"JoΓ£o Silva\",     // name\n\t\t\t\"+55 11 99999-9999\", // contact\n\t\t\tsqlmock.AnyArg(), // id\n\t\t).\n\t\tWillReturnRows(sqlmock.NewRows([]string{\"id\"}).AddRow(newID))\n\tmock.ExpectCommit()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, newID, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestPatientService_Create_DBError verifies the service surfaces DB errors.\nfunc TestPatientService_Create_DBError(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tdto := contracts.PatientDTO{\n\t\tOrganizationID: uuid.New().String(),\n\t\tName:           \"JoΓ£o Silva\",\n\t\tContact:        \"+55 11 99999-9999\",\n\t}\n\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"patients\" .* RETURNING \"id\"`).\n\t\tWillReturnError(errors.New(\"connection refused\"))\n\tmock.ExpectRollback()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.Error(t, err)\n\tassert.Equal(t, uuid.Nil, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestPatientService_FindByCPF_NotFound verifies gorm.ErrRecordNotFound is surfaced.\nfunc TestPatientService_FindByCPF_NotFound(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tmock.ExpectQuery(`SELECT .* FROM \"patients\"`).\n\t\tWithArgs(\"NOTEXIST\", sqlmock.AnyArg()).\n\t\tWillReturnError(gorm.ErrRecordNotFound)\n\n\tresult, err := svc.FindByCPF(\"NOTEXIST\")\n\n\tassert.Error(t, err)\n\tassert.Nil(t, result)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> controllers_test\n\n// controllers/patient_controller_test.go\n// Pattern: Fiber app.Test() for HTTP handler unit testing\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage controllers_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/controllers\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// mockPatientService implements contracts.PatientServiceContract for testing.\ntype mockPatientService struct {\n\tcreateResult string\n\tcreateErr    error\n}\n\nfunc (m *mockPatientService) CreateFromInput(input any) (any, error) {\n\treturn m.createResult, m.createErr\n}\n\nfunc TestPatientController_Create_Success(t *testing.T) {\n\tapp := fiber.New()\n\n\tctrl := controllers.NewPatientController(&mockPatientService{\n\t\tcreateResult: \"test-uuid\",\n\t})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\tbody, _ := json.Marshal(map[string]any{\n\t\t\"organization_name\": \"Test Org\",\n\t\t\"name\":    \"JoΓ£o Silva\",\n\t\t\"contact\": \"+55 11 99999-9999\",\n\t})\n\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusCreated, resp.StatusCode)\n\n\tvar result map[string]any\n\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&result))\n\trequire.Equal(t, \"Patient created successfully\", result[\"message\"])\n}\n\nfunc TestPatientController_Create_MissingField(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewPatientController(&mockPatientService{})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\t// Send empty body β€” required fields missing\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader([]byte(\"{}\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n\nfunc TestPatientController_Create_InvalidJSON(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewPatientController(&mockPatientService{})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader([]byte(\"not json\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> implementations_test\n\n// services/implementations/patient_service_test.go\n// Pattern: sqlmock + GORM + testify β€” success and error paths\n// Observed in: Medical-App-Core/services/implementations/appointment_service_test.go\npackage implementations_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"medical-sas-api/services/implementations\"\n\n\t\"github.com/DATA-DOG/go-sqlmock\"\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\n// setupTestDB creates an in-memory mock database for service tests.\n// Returns the GORM DB and the sqlmock controller for expectation setup.\nfunc setupTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {\n\tt.Helper()\n\tdb, mock, err := sqlmock.New()\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create mock DB: %v\", err)\n\t}\n\tgormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})\n\tif err != nil {\n\t\tt.Fatalf(\"failed to open GORM DB: %v\", err)\n\t}\n\tt.Cleanup(func() { db.Close() })\n\treturn gormDB, mock\n}\n\n// TestCreate_Success verifies that a valid DTO produces a non-nil UUID.\nfunc TestPatientService_Create_Success(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tdto := contracts.PatientDTO{\n\t\tOrganizationID: uuid.New().String(),\n\t\tName:           \"JoΓ£o Silva\",\n\t\tContact:        \"+55 11 99999-9999\",\n\t}\n\n\tnewID := uuid.New()\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"patients\" .* RETURNING \"id\"`).\n\t\tWithArgs(\n\t\t\tsqlmock.AnyArg(), // created_at\n\t\t\tsqlmock.AnyArg(), // updated_at\n\t\t\tnil,              // deleted_at\n\t\t\tsqlmock.AnyArg(), // organization_id\n\t\t\t\"JoΓ£o Silva\",     // name\n\t\t\t\"+55 11 99999-9999\", // contact\n\t\t\tsqlmock.AnyArg(), // id\n\t\t).\n\t\tWillReturnRows(sqlmock.NewRows([]string{\"id\"}).AddRow(newID))\n\tmock.ExpectCommit()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, newID, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestPatientService_Create_DBError verifies the service surfaces DB errors.\nfunc TestPatientService_Create_DBError(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tdto := contracts.PatientDTO{\n\t\tOrganizationID: uuid.New().String(),\n\t\tName:           \"JoΓ£o Silva\",\n\t\tContact:        \"+55 11 99999-9999\",\n\t}\n\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"patients\" .* RETURNING \"id\"`).\n\t\tWillReturnError(errors.New(\"connection refused\"))\n\tmock.ExpectRollback()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.Error(t, err)\n\tassert.Equal(t, uuid.Nil, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestPatientService_FindByCPF_NotFound verifies gorm.ErrRecordNotFound is surfaced.\nfunc TestPatientService_FindByCPF_NotFound(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tmock.ExpectQuery(`SELECT .* FROM \"patients\"`).\n\t\tWithArgs(\"NOTEXIST\", sqlmock.AnyArg()).\n\t\tWillReturnError(gorm.ErrRecordNotFound)\n\n\tresult, err := svc.FindByCPF(\"NOTEXIST\")\n\n\tassert.Error(t, err)\n\tassert.Nil(t, result)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> controllers_test\n\n// controllers/patient_controller_test.go\n// Pattern: Fiber app.Test() for HTTP handler unit testing\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage controllers_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/controllers\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// mockPatientService implements contracts.PatientServiceContract for testing.\ntype mockPatientService struct {\n\tcreateResult string\n\tcreateErr    error\n}\n\nfunc (m *mockPatientService) CreateFromInput(input any) (any, error) {\n\treturn m.createResult, m.createErr\n}\n\nfunc TestPatientController_Create_Success(t *testing.T) {\n\tapp := fiber.New()\n\n\tctrl := controllers.NewPatientController(&mockPatientService{\n\t\tcreateResult: \"test-uuid\",\n\t})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\tbody, _ := json.Marshal(map[string]any{\n\t\t\"organization_name\": \"Test Org\",\n\t\t\"name\":    \"JoΓ£o Silva\",\n\t\t\"contact\": \"+55 11 99999-9999\",\n\t})\n\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusCreated, resp.StatusCode)\n\n\tvar result map[string]any\n\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&result))\n\trequire.Equal(t, \"Patient created successfully\", result[\"message\"])\n}\n\nfunc TestPatientController_Create_MissingField(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewPatientController(&mockPatientService{})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\t// Send empty body β€” required fields missing\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader([]byte(\"{}\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n\nfunc TestPatientController_Create_InvalidJSON(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewPatientController(&mockPatientService{})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader([]byte(\"not json\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> implementations_test\n\n// services/implementations/patient_service_test.go\n// Pattern: sqlmock + GORM + testify β€” success and error paths\n// Observed in: Medical-App-Core/services/implementations/appointment_service_test.go\npackage implementations_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"medical-sas-api/services/implementations\"\n\n\t\"github.com/DATA-DOG/go-sqlmock\"\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\n// setupTestDB creates an in-memory mock database for service tests.\n// Returns the GORM DB and the sqlmock controller for expectation setup.\nfunc setupTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {\n\tt.Helper()\n\tdb, mock, err := sqlmock.New()\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create mock DB: %v\", err)\n\t}\n\tgormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})\n\tif err != nil {\n\t\tt.Fatalf(\"failed to open GORM DB: %v\", err)\n\t}\n\tt.Cleanup(func() { db.Close() })\n\treturn gormDB, mock\n}\n\n// TestCreate_Success verifies that a valid DTO produces a non-nil UUID.\nfunc TestPatientService_Create_Success(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tdto := contracts.PatientDTO{\n\t\tOrganizationID: uuid.New().String(),\n\t\tName:           \"JoΓ£o Silva\",\n\t\tContact:        \"+55 11 99999-9999\",\n\t}\n\n\tnewID := uuid.New()\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"patients\" .* RETURNING \"id\"`).\n\t\tWithArgs(\n\t\t\tsqlmock.AnyArg(), // created_at\n\t\t\tsqlmock.AnyArg(), // updated_at\n\t\t\tnil,              // deleted_at\n\t\t\tsqlmock.AnyArg(), // organization_id\n\t\t\t\"JoΓ£o Silva\",     // name\n\t\t\t\"+55 11 99999-9999\", // contact\n\t\t\tsqlmock.AnyArg(), // id\n\t\t).\n\t\tWillReturnRows(sqlmock.NewRows([]string{\"id\"}).AddRow(newID))\n\tmock.ExpectCommit()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, newID, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestPatientService_Create_DBError verifies the service surfaces DB errors.\nfunc TestPatientService_Create_DBError(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tdto := contracts.PatientDTO{\n\t\tOrganizationID: uuid.New().String(),\n\t\tName:           \"JoΓ£o Silva\",\n\t\tContact:        \"+55 11 99999-9999\",\n\t}\n\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"patients\" .* RETURNING \"id\"`).\n\t\tWillReturnError(errors.New(\"connection refused\"))\n\tmock.ExpectRollback()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.Error(t, err)\n\tassert.Equal(t, uuid.Nil, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestPatientService_FindByCPF_NotFound verifies gorm.ErrRecordNotFound is surfaced.\nfunc TestPatientService_FindByCPF_NotFound(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tmock.ExpectQuery(`SELECT .* FROM \"patients\"`).\n\t\tWithArgs(\"NOTEXIST\", sqlmock.AnyArg()).\n\t\tWillReturnError(gorm.ErrRecordNotFound)\n\n\tresult, err := svc.FindByCPF(\"NOTEXIST\")\n\n\tassert.Error(t, err)\n\tassert.Nil(t, result)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> controllers_test\n\n// controllers/patient_controller_test.go\n// Pattern: Fiber app.Test() for HTTP handler unit testing\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage controllers_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/controllers\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// mockPatientService implements contracts.PatientServiceContract for testing.\ntype mockPatientService struct {\n\tcreateResult string\n\tcreateErr    error\n}\n\nfunc (m *mockPatientService) CreateFromInput(input any) (any, error) {\n\treturn m.createResult, m.createErr\n}\n\nfunc TestPatientController_Create_Success(t *testing.T) {\n\tapp := fiber.New()\n\n\tctrl := controllers.NewPatientController(&mockPatientService{\n\t\tcreateResult: \"test-uuid\",\n\t})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\tbody, _ := json.Marshal(map[string]any{\n\t\t\"organization_name\": \"Test Org\",\n\t\t\"name\":    \"JoΓ£o Silva\",\n\t\t\"contact\": \"+55 11 99999-9999\",\n\t})\n\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusCreated, resp.StatusCode)\n\n\tvar result map[string]any\n\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&result))\n\trequire.Equal(t, \"Patient created successfully\", result[\"message\"])\n}\n\nfunc TestPatientController_Create_MissingField(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewPatientController(&mockPatientService{})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\t// Send empty body β€” required fields missing\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader([]byte(\"{}\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n\nfunc TestPatientController_Create_InvalidJSON(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewPatientController(&mockPatientService{})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader([]byte(\"not json\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> implementations_test\n\n// services/implementations/patient_service_test.go\n// Pattern: sqlmock + GORM + testify β€” success and error paths\n// Observed in: Medical-App-Core/services/implementations/appointment_service_test.go\npackage implementations_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"medical-sas-api/services/contracts\"\n\t\"medical-sas-api/services/implementations\"\n\n\t\"github.com/DATA-DOG/go-sqlmock\"\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\n// setupTestDB creates an in-memory mock database for service tests.\n// Returns the GORM DB and the sqlmock controller for expectation setup.\nfunc setupTestDB(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) {\n\tt.Helper()\n\tdb, mock, err := sqlmock.New()\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create mock DB: %v\", err)\n\t}\n\tgormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})\n\tif err != nil {\n\t\tt.Fatalf(\"failed to open GORM DB: %v\", err)\n\t}\n\tt.Cleanup(func() { db.Close() })\n\treturn gormDB, mock\n}\n\n// TestCreate_Success verifies that a valid DTO produces a non-nil UUID.\nfunc TestPatientService_Create_Success(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tdto := contracts.PatientDTO{\n\t\tOrganizationID: uuid.New().String(),\n\t\tName:           \"JoΓ£o Silva\",\n\t\tContact:        \"+55 11 99999-9999\",\n\t}\n\n\tnewID := uuid.New()\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"patients\" .* RETURNING \"id\"`).\n\t\tWithArgs(\n\t\t\tsqlmock.AnyArg(), // created_at\n\t\t\tsqlmock.AnyArg(), // updated_at\n\t\t\tnil,              // deleted_at\n\t\t\tsqlmock.AnyArg(), // organization_id\n\t\t\t\"JoΓ£o Silva\",     // name\n\t\t\t\"+55 11 99999-9999\", // contact\n\t\t\tsqlmock.AnyArg(), // id\n\t\t).\n\t\tWillReturnRows(sqlmock.NewRows([]string{\"id\"}).AddRow(newID))\n\tmock.ExpectCommit()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, newID, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestPatientService_Create_DBError verifies the service surfaces DB errors.\nfunc TestPatientService_Create_DBError(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tdto := contracts.PatientDTO{\n\t\tOrganizationID: uuid.New().String(),\n\t\tName:           \"JoΓ£o Silva\",\n\t\tContact:        \"+55 11 99999-9999\",\n\t}\n\n\tmock.ExpectBegin()\n\tmock.ExpectQuery(`INSERT INTO \"patients\" .* RETURNING \"id\"`).\n\t\tWillReturnError(errors.New(\"connection refused\"))\n\tmock.ExpectRollback()\n\n\tgotID, err := svc.Create(dto)\n\n\tassert.Error(t, err)\n\tassert.Equal(t, uuid.Nil, gotID)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n\n// TestPatientService_FindByCPF_NotFound verifies gorm.ErrRecordNotFound is surfaced.\nfunc TestPatientService_FindByCPF_NotFound(t *testing.T) {\n\tdb, mock := setupTestDB(t)\n\tsvc := implementations.NewPatientService(db)\n\n\tmock.ExpectQuery(`SELECT .* FROM \"patients\"`).\n\t\tWithArgs(\"NOTEXIST\", sqlmock.AnyArg()).\n\t\tWillReturnError(gorm.ErrRecordNotFound)\n\n\tresult, err := svc.FindByCPF(\"NOTEXIST\")\n\n\tassert.Error(t, err)\n\tassert.Nil(t, result)\n\tassert.NoError(t, mock.ExpectationsWereMet())\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> controllers_test\n\n// controllers/patient_controller_test.go\n// Pattern: Fiber app.Test() for HTTP handler unit testing\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage controllers_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/controllers\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// mockPatientService implements contracts.PatientServiceContract for testing.\ntype mockPatientService struct {\n\tcreateResult string\n\tcreateErr    error\n}\n\nfunc (m *mockPatientService) CreateFromInput(input any) (any, error) {\n\treturn m.createResult, m.createErr\n}\n\nfunc TestPatientController_Create_Success(t *testing.T) {\n\tapp := fiber.New()\n\n\tctrl := controllers.NewPatientController(&mockPatientService{\n\t\tcreateResult: \"test-uuid\",\n\t})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\tbody, _ := json.Marshal(map[string]any{\n\t\t\"organization_name\": \"Test Org\",\n\t\t\"name\":    \"JoΓ£o Silva\",\n\t\t\"contact\": \"+55 11 99999-9999\",\n\t})\n\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusCreated, resp.StatusCode)\n\n\tvar result map[string]any\n\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&result))\n\trequire.Equal(t, \"Patient created successfully\", result[\"message\"])\n}\n\nfunc TestPatientController_Create_MissingField(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewPatientController(&mockPatientService{})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\t// Send empty body β€” required fields missing\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader([]byte(\"{}\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n\nfunc TestPatientController_Create_InvalidJSON(t *testing.T) {\n\tapp := fiber.New()\n\tctrl := controllers.NewPatientController(&mockPatientService{})\n\tapp.Post(\"/patients\", ctrl.CreatePatient)\n\n\treq := httptest.NewRequest(http.MethodPost, \"/patients\", bytes.NewReader([]byte(\"not json\")))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := app.Test(req, -1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusBadRequest, resp.StatusCode)\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> utils_test\n\n// utils/response_util_test.go\n// Pattern: table-driven tests with Fiber app.Test()\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage utils_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/utils\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestRespondWithJSON(t *testing.T) {\n\tru := &utils.JSONResponseUtil{}\n\n\ttests := []struct {\n\t\tname       string\n\t\tcode       int\n\t\tpayload    any\n\t\twantStatus int\n\t\twantKey    string\n\t}{\n\t\t{\n\t\t\tname:       \"200 ok with map payload\",\n\t\t\tcode:       http.StatusOK,\n\t\t\tpayload:    map[string]string{\"message\": \"ok\"},\n\t\t\twantStatus: http.StatusOK,\n\t\t\twantKey:    \"message\",\n\t\t},\n\t\t{\n\t\t\tname:       \"201 created\",\n\t\t\tcode:       http.StatusCreated,\n\t\t\tpayload:    map[string]string{\"id\": \"abc-123\"},\n\t\t\twantStatus: http.StatusCreated,\n\t\t\twantKey:    \"id\",\n\t\t},\n\t\t{\n\t\t\tname:       \"400 bad request\",\n\t\t\tcode:       http.StatusBadRequest,\n\t\t\tpayload:    map[string]string{\"error\": \"invalid input\"},\n\t\t\twantStatus: http.StatusBadRequest,\n\t\t\twantKey:    \"error\",\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tapp := fiber.New()\n\t\t\tapp.Get(\"/test\", func(c *fiber.Ctx) error {\n\t\t\t\treturn ru.RespondWithJSON(c, tc.code, tc.payload)\n\t\t\t})\n\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/test\", nil)\n\t\t\tresp, err := app.Test(req, -1)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tc.wantStatus, resp.StatusCode)\n\t\t\trequire.Equal(t, \"application/json\", resp.Header.Get(\"Content-Type\"))\n\n\t\t\tvar body map[string]any\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&body))\n\t\t\t_, ok := body[tc.wantKey]\n\t\t\trequire.True(t, ok, \"expected key %q in response\", tc.wantKey)\n\t\t})\n\t}\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> utils_test\n\n// utils/response_util_test.go\n// Pattern: table-driven tests with Fiber app.Test()\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage utils_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/utils\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestRespondWithJSON(t *testing.T) {\n\tru := &utils.JSONResponseUtil{}\n\n\ttests := []struct {\n\t\tname       string\n\t\tcode       int\n\t\tpayload    any\n\t\twantStatus int\n\t\twantKey    string\n\t}{\n\t\t{\n\t\t\tname:       \"200 ok with map payload\",\n\t\t\tcode:       http.StatusOK,\n\t\t\tpayload:    map[string]string{\"message\": \"ok\"},\n\t\t\twantStatus: http.StatusOK,\n\t\t\twantKey:    \"message\",\n\t\t},\n\t\t{\n\t\t\tname:       \"201 created\",\n\t\t\tcode:       http.StatusCreated,\n\t\t\tpayload:    map[string]string{\"id\": \"abc-123\"},\n\t\t\twantStatus: http.StatusCreated,\n\t\t\twantKey:    \"id\",\n\t\t},\n\t\t{\n\t\t\tname:       \"400 bad request\",\n\t\t\tcode:       http.StatusBadRequest,\n\t\t\tpayload:    map[string]string{\"error\": \"invalid input\"},\n\t\t\twantStatus: http.StatusBadRequest,\n\t\t\twantKey:    \"error\",\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tapp := fiber.New()\n\t\t\tapp.Get(\"/test\", func(c *fiber.Ctx) error {\n\t\t\t\treturn ru.RespondWithJSON(c, tc.code, tc.payload)\n\t\t\t})\n\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/test\", nil)\n\t\t\tresp, err := app.Test(req, -1)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tc.wantStatus, resp.StatusCode)\n\t\t\trequire.Equal(t, \"application/json\", resp.Header.Get(\"Content-Type\"))\n\n\t\t\tvar body map[string]any\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&body))\n\t\t\t_, ok := body[tc.wantKey]\n\t\t\trequire.True(t, ok, \"expected key %q in response\", tc.wantKey)\n\t\t})\n\t}\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> utils_test\n\n// utils/response_util_test.go\n// Pattern: table-driven tests with Fiber app.Test()\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage utils_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/utils\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestRespondWithJSON(t *testing.T) {\n\tru := &utils.JSONResponseUtil{}\n\n\ttests := []struct {\n\t\tname       string\n\t\tcode       int\n\t\tpayload    any\n\t\twantStatus int\n\t\twantKey    string\n\t}{\n\t\t{\n\t\t\tname:       \"200 ok with map payload\",\n\t\t\tcode:       http.StatusOK,\n\t\t\tpayload:    map[string]string{\"message\": \"ok\"},\n\t\t\twantStatus: http.StatusOK,\n\t\t\twantKey:    \"message\",\n\t\t},\n\t\t{\n\t\t\tname:       \"201 created\",\n\t\t\tcode:       http.StatusCreated,\n\t\t\tpayload:    map[string]string{\"id\": \"abc-123\"},\n\t\t\twantStatus: http.StatusCreated,\n\t\t\twantKey:    \"id\",\n\t\t},\n\t\t{\n\t\t\tname:       \"400 bad request\",\n\t\t\tcode:       http.StatusBadRequest,\n\t\t\tpayload:    map[string]string{\"error\": \"invalid input\"},\n\t\t\twantStatus: http.StatusBadRequest,\n\t\t\twantKey:    \"error\",\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tapp := fiber.New()\n\t\t\tapp.Get(\"/test\", func(c *fiber.Ctx) error {\n\t\t\t\treturn ru.RespondWithJSON(c, tc.code, tc.payload)\n\t\t\t})\n\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/test\", nil)\n\t\t\tresp, err := app.Test(req, -1)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tc.wantStatus, resp.StatusCode)\n\t\t\trequire.Equal(t, \"application/json\", resp.Header.Get(\"Content-Type\"))\n\n\t\t\tvar body map[string]any\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&body))\n\t\t\t_, ok := body[tc.wantKey]\n\t\t\trequire.True(t, ok, \"expected key %q in response\", tc.wantKey)\n\t\t})\n\t}\n}\n</go_file>\n"}
{"category": "test", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> utils_test\n\n// utils/response_util_test.go\n// Pattern: table-driven tests with Fiber app.Test()\n// Observed in: Medical-App-Core/utils/response_util_test.go\npackage utils_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"medical-sas-api/utils\"\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestRespondWithJSON(t *testing.T) {\n\tru := &utils.JSONResponseUtil{}\n\n\ttests := []struct {\n\t\tname       string\n\t\tcode       int\n\t\tpayload    any\n\t\twantStatus int\n\t\twantKey    string\n\t}{\n\t\t{\n\t\t\tname:       \"200 ok with map payload\",\n\t\t\tcode:       http.StatusOK,\n\t\t\tpayload:    map[string]string{\"message\": \"ok\"},\n\t\t\twantStatus: http.StatusOK,\n\t\t\twantKey:    \"message\",\n\t\t},\n\t\t{\n\t\t\tname:       \"201 created\",\n\t\t\tcode:       http.StatusCreated,\n\t\t\tpayload:    map[string]string{\"id\": \"abc-123\"},\n\t\t\twantStatus: http.StatusCreated,\n\t\t\twantKey:    \"id\",\n\t\t},\n\t\t{\n\t\t\tname:       \"400 bad request\",\n\t\t\tcode:       http.StatusBadRequest,\n\t\t\tpayload:    map[string]string{\"error\": \"invalid input\"},\n\t\t\twantStatus: http.StatusBadRequest,\n\t\t\twantKey:    \"error\",\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tapp := fiber.New()\n\t\t\tapp.Get(\"/test\", func(c *fiber.Ctx) error {\n\t\t\t\treturn ru.RespondWithJSON(c, tc.code, tc.payload)\n\t\t\t})\n\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/test\", nil)\n\t\t\tresp, err := app.Test(req, -1)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tc.wantStatus, resp.StatusCode)\n\t\t\trequire.Equal(t, \"application/json\", resp.Header.Get(\"Content-Type\"))\n\n\t\t\tvar body map[string]any\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&body))\n\t\t\t_, ok := body[tc.wantKey]\n\t\t\trequire.True(t, ok, \"expected key %q in response\", tc.wantKey)\n\t\t})\n\t}\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.21 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 8080\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"8080\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:8080/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"8080:8080\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=8080\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.21 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 3040\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"3040\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:3040/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"3040:3040\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=3040\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.21 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 3000\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"3000\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:3000/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"3000:3000\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=3000\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> shell\n\n#!/bin/sh\n# docker/api/entrypoint.sh\n# Pattern: validate required env vars before exec'ing the binary\n# Observed in: Medical-App-Core/docker/api/entrypoint.sh\nset -e\n\necho \"Checking required environment variables...\"\n\nMISSING=0\nfor VAR in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_NAME JWT_SECRET; do\n  if [ -z \"$(eval echo \\$${VAR})\" ]; then\n    echo \"ERROR: $VAR is not set\"\n    MISSING=1\n  else\n    echo \"OK: $VAR is set\"\n  fi\ndone\n\nif [ \"$MISSING\" -eq 1 ]; then\n  echo \"One or more required environment variables are missing. Aborting.\"\n  exit 1\nfi\n\necho \"All required variables present. Starting application...\"\nexec ./app\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/my-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.21\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/medical-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.21\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.21\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/ecommerce-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.21\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.22 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 8080\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"8080\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:8080/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"8080:8080\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=8080\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.22 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 3040\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"3040\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:3040/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"3040:3040\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=3040\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.22 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 3000\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"3000\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:3000/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"3000:3000\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=3000\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> shell\n\n#!/bin/sh\n# docker/api/entrypoint.sh\n# Pattern: validate required env vars before exec'ing the binary\n# Observed in: Medical-App-Core/docker/api/entrypoint.sh\nset -e\n\necho \"Checking required environment variables...\"\n\nMISSING=0\nfor VAR in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_NAME JWT_SECRET; do\n  if [ -z \"$(eval echo \\$${VAR})\" ]; then\n    echo \"ERROR: $VAR is not set\"\n    MISSING=1\n  else\n    echo \"OK: $VAR is set\"\n  fi\ndone\n\nif [ \"$MISSING\" -eq 1 ]; then\n  echo \"One or more required environment variables are missing. Aborting.\"\n  exit 1\nfi\n\necho \"All required variables present. Starting application...\"\nexec ./app\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/my-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.22\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/medical-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.22\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.22\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/ecommerce-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.22\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.23 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 8080\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"8080\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:8080/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"8080:8080\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=8080\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.23 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 3040\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"3040\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:3040/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"3040:3040\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=3040\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.23 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 3000\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"3000\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:3000/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"3000:3000\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=3000\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> shell\n\n#!/bin/sh\n# docker/api/entrypoint.sh\n# Pattern: validate required env vars before exec'ing the binary\n# Observed in: Medical-App-Core/docker/api/entrypoint.sh\nset -e\n\necho \"Checking required environment variables...\"\n\nMISSING=0\nfor VAR in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_NAME JWT_SECRET; do\n  if [ -z \"$(eval echo \\$${VAR})\" ]; then\n    echo \"ERROR: $VAR is not set\"\n    MISSING=1\n  else\n    echo \"OK: $VAR is set\"\n  fi\ndone\n\nif [ \"$MISSING\" -eq 1 ]; then\n  echo \"One or more required environment variables are missing. Aborting.\"\n  exit 1\nfi\n\necho \"All required variables present. Starting application...\"\nexec ./app\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/my-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.23\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/medical-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.23\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.23\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/ecommerce-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.23\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.24 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 8080\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"8080\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:8080/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"8080:8080\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=8080\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.24 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 3040\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"3040\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:3040/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"3040:3040\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=3040\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> dockerfile\n\n# Dockerfile β€” multi-stage build for a Go Fiber application\n# Pattern: golang builder + debian:bookworm-slim runtime\n# Observed in: Medical-App-Core/Dockerfile\n\n# ─── Stage 1: Build ────────────────────────────────────────────────────────\nFROM golang:1.24 AS builder\n\nWORKDIR /app\n\n# Copy dependency manifests first for better layer caching.\n# Only re-downloads modules when go.mod or go.sum changes.\nCOPY go.mod go.sum ./\nRUN go mod download\n\n# Copy source and build the binary from cmd/\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -ldflags=\"-s -w\" -o app ./cmd\n\n# ─── Stage 2: Runtime ──────────────────────────────────────────────────────\nFROM debian:bookworm-slim\n\nWORKDIR /app\n\n# CA certificates are required for outbound HTTPS (e.g., Stripe API).\nRUN apt-get update && \\\n    apt-get install -y --no-install-recommends ca-certificates curl && \\\n    rm -rf /var/lib/apt/lists/*\n\nCOPY --from=builder /app/app .\n\nEXPOSE 3000\n\n# Document all required environment variables (values supplied at runtime).\nENV DB_HOST=\"\" \\\n    DB_PORT=\"5432\" \\\n    DB_USER=\"\" \\\n    DB_PASSWORD=\"\" \\\n    DB_NAME=\"\" \\\n    DB_TIMEZONE=\"UTC\" \\\n    JWT_SECRET=\"\" \\\n    RABBITMQ_BASE_URL=\"\" \\\n    SWAGGER_USER=\"\" \\\n    SWAGGER_PASSWORD=\"\" \\\n    PORT=\"3000\"\n\nHEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \\\n  CMD curl -f http://localhost:3000/health || exit 1\n\nCOPY ./docker/api/entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh /app/app\n\nENTRYPOINT [\"/entrypoint.sh\"]\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> docker-compose\n\n# docker-compose.yml β€” local development environment\n# Pattern: app + postgres + rabbitmq services with health checks\n# Observed from: Medical-App-Core infrastructure patterns\nversion: \"3.9\"\n\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    ports:\n      - \"3000:3000\"\n    environment:\n      - DB_HOST=postgres\n      - DB_PORT=5432\n      - DB_USER=postgres\n      - DB_PASSWORD=postgres\n      - DB_NAME=appdb\n      - DB_TIMEZONE=UTC\n      - JWT_SECRET=local-dev-secret-change-in-prod\n      - RABBITMQ_BASE_URL=amqp://guest:guest@rabbitmq:5672/\n      - SWAGGER_USER=admin\n      - SWAGGER_PASSWORD=admin\n      - PORT=3000\n    depends_on:\n      postgres:\n        condition: service_healthy\n      rabbitmq:\n        condition: service_healthy\n    restart: unless-stopped\n\n  postgres:\n    image: postgres:16-alpine\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_PASSWORD: postgres\n      POSTGRES_DB: appdb\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - pg_data:/var/lib/postgresql/data\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  rabbitmq:\n    image: rabbitmq:3.13-management-alpine\n    ports:\n      - \"5672:5672\"\n      - \"15672:15672\"\n    healthcheck:\n      test: [\"CMD\", \"rabbitmq-diagnostics\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\nvolumes:\n  pg_data:\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> shell\n\n#!/bin/sh\n# docker/api/entrypoint.sh\n# Pattern: validate required env vars before exec'ing the binary\n# Observed in: Medical-App-Core/docker/api/entrypoint.sh\nset -e\n\necho \"Checking required environment variables...\"\n\nMISSING=0\nfor VAR in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_NAME JWT_SECRET; do\n  if [ -z \"$(eval echo \\$${VAR})\" ]; then\n    echo \"ERROR: $VAR is not set\"\n    MISSING=1\n  else\n    echo \"OK: $VAR is set\"\n  fi\ndone\n\nif [ \"$MISSING\" -eq 1 ]; then\n  echo \"One or more required environment variables are missing. Aborting.\"\n  exit 1\nfi\n\necho \"All required variables present. Starting application...\"\nexec ./app\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/my-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.24\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/medical-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.24\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}
{"category": "docker", "text": "<go_file>\n<go_version> go1.24\n<go_pkg> jenkins\n\n// Jenkinsfile β€” CI/CD pipeline\n// Pattern: multi-stage pipeline: test β†’ build β†’ docker β†’ deploy\n// Observed in: Medical-App-Core/Jenkinsfile\npipeline {\n    agent any\n\n    environment {\n        DOCKER_IMAGE = \"myorg/ecommerce-api\"\n        DOCKER_TAG   = \"${BUILD_NUMBER}\"\n        GO_VERSION   = \"1.24\"\n    }\n\n    stages {\n        stage('Checkout') {\n            steps {\n                checkout scm\n            }\n        }\n\n        stage('Test') {\n            steps {\n                sh '''\n                    go test ./... -v -coverprofile=coverage.out\n                    go tool cover -html=coverage.out -o coverage.html\n                '''\n            }\n            post {\n                always {\n                    publishHTML(target: [\n                        reportName:  'Go Coverage',\n                        reportDir:   '.',\n                        reportFiles: 'coverage.html',\n                    ])\n                }\n            }\n        }\n\n        stage('Lint') {\n            steps {\n                sh 'go vet ./...'\n            }\n        }\n\n        stage('Build Binary') {\n            steps {\n                sh 'CGO_ENABLED=0 GOOS=linux go build -o app ./cmd'\n            }\n        }\n\n        stage('Docker Build') {\n            steps {\n                sh 'docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .'\n                sh 'docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest'\n            }\n        }\n\n        stage('Docker Push') {\n            steps {\n                withCredentials([usernamePassword(\n                    credentialsId: 'dockerhub-creds',\n                    usernameVariable: 'DOCKER_USER',\n                    passwordVariable: 'DOCKER_PASS'\n                )]) {\n                    sh '''\n                        echo \"$DOCKER_PASS\" | docker login -u \"$DOCKER_USER\" --password-stdin\n                        docker push ${DOCKER_IMAGE}:${DOCKER_TAG}\n                        docker push ${DOCKER_IMAGE}:latest\n                    '''\n                }\n            }\n        }\n    }\n\n    post {\n        always {\n            sh 'docker system prune -f || true'\n        }\n        failure {\n            echo \"Pipeline failed β€” check logs above\"\n        }\n    }\n}\n</go_file>\n"}