Instructions to use LesterCerioli/LLM-GO with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use LesterCerioli/LLM-GO with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="LesterCerioli/LLM-GO")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("LesterCerioli/LLM-GO", dtype="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use LesterCerioli/LLM-GO with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "LesterCerioli/LLM-GO" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "LesterCerioli/LLM-GO", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/LesterCerioli/LLM-GO
- SGLang
How to use LesterCerioli/LLM-GO with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "LesterCerioli/LLM-GO" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "LesterCerioli/LLM-GO", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "LesterCerioli/LLM-GO" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "LesterCerioli/LLM-GO", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use LesterCerioli/LLM-GO with Docker Model Runner:
docker model run hf.co/LesterCerioli/LLM-GO
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"}
|