package api import "git.threesix.ai/jordan/foundary-1770644471/pkg/openapi" // NewServiceSpec builds the OpenAPI specification for the studio-api service. func NewServiceSpec() *openapi.OpenAPISpec { spec := openapi.NewOpenAPISpec("studio-api API", "1.0.0"). WithDescription("REST API for the studio-api service"). WithBearerSecurity("bearer", "JWT authentication token"). WithTag("Health", "Service health endpoints"). WithTag("Examples", "Example CRUD endpoints") // Define reusable schemas spec.WithSchema("Example", openapi.Object(map[string]openapi.Schema{ "id": openapi.UUID().WithDescription("Unique identifier"), "name": openapi.String().WithDescription("Name of the example").WithExample("My Example"), "description": openapi.String().WithDescription("Optional description").WithExample("A description"), "created_at": openapi.DateTime().WithDescription("Creation timestamp"), "updated_at": openapi.DateTime().WithDescription("Last update timestamp"), }, "id", "name")) spec.WithSchema("CreateExampleRequest", openapi.Object(map[string]openapi.Schema{ "name": openapi.StringWithMinMax(1, 100).WithDescription("Name of the example"), "description": openapi.StringWithMinMax(0, 500).WithDescription("Optional description"), }, "name")) spec.WithSchema("UpdateExampleRequest", openapi.Object(map[string]openapi.Schema{ "name": openapi.StringWithMinMax(1, 100).WithDescription("Updated name"), "description": openapi.StringWithMinMax(0, 500).WithDescription("Updated description"), })) // Health spec.AddPath("/api/studio-api/health", "get", map[string]any{ "summary": "Health check", "tags": []string{"Health"}, "responses": map[string]any{ "200": openapi.OpResponse("Service is healthy", openapi.Object(map[string]openapi.Schema{ "service": openapi.String(), "status": openapi.String(), })), }, }) // List examples spec.AddPath("/api/studio-api/examples", "get", map[string]any{ "summary": "List examples", "description": "Returns a paginated list of examples.", "tags": []string{"Examples"}, "parameters": []any{openapi.PageParam(), openapi.PerPageParam()}, "responses": map[string]any{ "200": openapi.OpResponse("Success", openapi.ResponseSchema(openapi.RefArray("Example"))), }, }) // Get example spec.AddPath("/api/studio-api/examples/{id}", "get", map[string]any{ "summary": "Get example by ID", "tags": []string{"Examples"}, "parameters": []any{openapi.IDParam()}, "responses": map[string]any{ "200": openapi.OpResponse("Success", openapi.ResponseSchema(openapi.Ref("Example"))), "404": openapi.OpResponse("Not found", openapi.ErrorResponseSchema()), }, }) // Create example spec.AddPath("/api/studio-api/examples", "post", map[string]any{ "summary": "Create example", "description": "Creates a new example. Requires authentication.", "tags": []string{"Examples"}, "security": []map[string][]string{{"bearer": {}}}, "requestBody": openapi.RequestBody(openapi.Ref("CreateExampleRequest"), true), "responses": map[string]any{ "201": openapi.OpResponse("Created", openapi.ResponseSchema(openapi.Ref("Example"))), "400": openapi.OpResponse("Bad request", openapi.ErrorResponseSchema()), "401": openapi.OpResponse("Unauthorized", openapi.ErrorResponseSchema()), "422": openapi.OpResponse("Validation error", openapi.ErrorResponseSchema()), }, }) // Update example spec.AddPath("/api/studio-api/examples/{id}", "put", map[string]any{ "summary": "Update example", "description": "Updates an existing example. Requires authentication.", "tags": []string{"Examples"}, "security": []map[string][]string{{"bearer": {}}}, "parameters": []any{openapi.IDParam()}, "requestBody": openapi.RequestBody(openapi.Ref("UpdateExampleRequest"), true), "responses": map[string]any{ "200": openapi.OpResponse("Updated", openapi.ResponseSchema(openapi.Ref("Example"))), "400": openapi.OpResponse("Bad request", openapi.ErrorResponseSchema()), "401": openapi.OpResponse("Unauthorized", openapi.ErrorResponseSchema()), "404": openapi.OpResponse("Not found", openapi.ErrorResponseSchema()), }, }) // Delete example spec.AddPath("/api/studio-api/examples/{id}", "delete", map[string]any{ "summary": "Delete example", "description": "Deletes an example by ID. Requires authentication.", "tags": []string{"Examples"}, "security": []map[string][]string{{"bearer": {}}}, "parameters": []any{openapi.IDParam()}, "responses": map[string]any{ "204": openapi.OpResponseNoContent(), "401": openapi.OpResponse("Unauthorized", openapi.ErrorResponseSchema()), "404": openapi.OpResponse("Not found", openapi.ErrorResponseSchema()), }, }) return spec }