176 lines
7.6 KiB
Go
176 lines
7.6 KiB
Go
package api
|
|
|
|
import "git.threesix.ai/jordan/slack-auth-1770277926/pkg/openapi"
|
|
|
|
// NewServiceSpec builds the OpenAPI specification for the auth-api service.
|
|
func NewServiceSpec() *openapi.OpenAPISpec {
|
|
spec := openapi.NewOpenAPISpec("auth-api API", "1.0.0").
|
|
WithDescription("REST API for the auth-api service").
|
|
WithBearerSecurity("bearer", "JWT authentication token").
|
|
WithTag("Health", "Service health endpoints").
|
|
WithTag("Auth", "Authentication 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"),
|
|
}))
|
|
|
|
// Auth schemas
|
|
spec.WithSchema("User", openapi.Object(map[string]openapi.Schema{
|
|
"id": openapi.UUID().WithDescription("Unique user identifier"),
|
|
"email": openapi.String().WithDescription("User email address").WithExample("user@example.com"),
|
|
"created_at": openapi.DateTime().WithDescription("Account creation timestamp"),
|
|
"updated_at": openapi.DateTime().WithDescription("Last update timestamp"),
|
|
}, "id", "email"))
|
|
|
|
spec.WithSchema("RegisterRequest", openapi.Object(map[string]openapi.Schema{
|
|
"email": openapi.StringWithMinMax(3, 254).WithDescription("User email address").WithExample("user@example.com"),
|
|
"password": openapi.StringWithMinMax(8, 72).WithDescription("User password (8-72 characters)"),
|
|
}, "email", "password"))
|
|
|
|
spec.WithSchema("LoginRequest", openapi.Object(map[string]openapi.Schema{
|
|
"email": openapi.String().WithDescription("User email address").WithExample("user@example.com"),
|
|
"password": openapi.String().WithDescription("User password"),
|
|
}, "email", "password"))
|
|
|
|
spec.WithSchema("AuthResponse", openapi.Object(map[string]openapi.Schema{
|
|
"user": openapi.Ref("User"),
|
|
"token": openapi.String().WithDescription("JWT authentication token"),
|
|
}, "user", "token"))
|
|
|
|
// Health
|
|
spec.AddPath("/api/auth-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(),
|
|
})),
|
|
},
|
|
})
|
|
|
|
// Register
|
|
spec.AddPath("/api/auth-api/register", "post", map[string]any{
|
|
"summary": "Register new user",
|
|
"description": "Creates a new user account and returns a JWT token.",
|
|
"tags": []string{"Auth"},
|
|
"requestBody": openapi.RequestBody(openapi.Ref("RegisterRequest"), true),
|
|
"responses": map[string]any{
|
|
"201": openapi.OpResponse("User created", openapi.ResponseSchema(openapi.Ref("AuthResponse"))),
|
|
"400": openapi.OpResponse("Bad request", openapi.ErrorResponseSchema()),
|
|
"409": openapi.OpResponse("Email already exists", openapi.ErrorResponseSchema()),
|
|
"422": openapi.OpResponse("Validation error", openapi.ErrorResponseSchema()),
|
|
},
|
|
})
|
|
|
|
// Login
|
|
spec.AddPath("/api/auth-api/login", "post", map[string]any{
|
|
"summary": "User login",
|
|
"description": "Authenticates a user and returns a JWT token.",
|
|
"tags": []string{"Auth"},
|
|
"requestBody": openapi.RequestBody(openapi.Ref("LoginRequest"), true),
|
|
"responses": map[string]any{
|
|
"200": openapi.OpResponse("Login successful", openapi.ResponseSchema(openapi.Ref("AuthResponse"))),
|
|
"400": openapi.OpResponse("Bad request", openapi.ErrorResponseSchema()),
|
|
"401": openapi.OpResponse("Invalid credentials", openapi.ErrorResponseSchema()),
|
|
},
|
|
})
|
|
|
|
// Get current user
|
|
spec.AddPath("/api/auth-api/me", "get", map[string]any{
|
|
"summary": "Get current user",
|
|
"description": "Returns the profile of the currently authenticated user.",
|
|
"tags": []string{"Auth"},
|
|
"security": []map[string][]string{{"bearer": {}}},
|
|
"responses": map[string]any{
|
|
"200": openapi.OpResponse("Success", openapi.ResponseSchema(openapi.Ref("User"))),
|
|
"401": openapi.OpResponse("Unauthorized", openapi.ErrorResponseSchema()),
|
|
},
|
|
})
|
|
|
|
// List examples
|
|
spec.AddPath("/api/auth-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/auth-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/auth-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/auth-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/auth-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
|
|
}
|