From f42a7533725823321bab59cf5b3f5478b3c30770 Mon Sep 17 00:00:00 2001 From: nutcas3 Date: Mon, 20 Apr 2026 20:06:37 +0300 Subject: [PATCH] feat: Add Swagger documentation models for API endpoints with comprehensive field annotations - Add Subscriber model with IMSI/MSISDN/email/status/plan_id/profile_status fields and validation examples - Add Service model with name/namespace/replicas/ready_replicas/available_replicas/creation_timestamp fields - Add Deployment model with service/version/status/started_at/completed_at/metadata fields and status enum - Add Plugin model with name/version/author/description/enabled/config fields - Add Automation model with name/description/trigger/ --- apps/api-server/docs/api.go | 403 ++++++++++++++++++++++++++++++++ apps/api-server/docs/auth.go | 177 ++++++++++++++ apps/api-server/docs/docs.go | 117 ++++++++++ apps/api-server/docs/swagger.go | 25 ++ 4 files changed, 722 insertions(+) create mode 100644 apps/api-server/docs/api.go create mode 100644 apps/api-server/docs/auth.go create mode 100644 apps/api-server/docs/docs.go create mode 100644 apps/api-server/docs/swagger.go diff --git a/apps/api-server/docs/api.go b/apps/api-server/docs/api.go new file mode 100644 index 0000000..d3410f5 --- /dev/null +++ b/apps/api-server/docs/api.go @@ -0,0 +1,403 @@ +package docs + +// Subscriber represents a telecom subscriber +// @Description Subscriber represents a telecom subscriber in the system +type Subscriber struct { + // Unique identifier of the subscriber + // @ReadOnly: true + ID uint `json:"id"` + + // IMSI (International Mobile Subscriber Identity) + // @Example: 208930000000001 + IMSI string `json:"imsi"` + + // MSISDN (Mobile Station International Subscriber Directory Number) + // @Example: +33612345678 + MSISDN string `json:"msisdn"` + + // First name of the subscriber + // @Example: John + FirstName string `json:"first_name"` + + // Last name of the subscriber + // @Example: Doe + LastName string `json:"last_name"` + + // Email address of the subscriber + // @Format: email + // @Example: john.doe@example.com + Email string `json:"email"` + + // Current status of the subscriber + // @Enum: active,inactive,suspended + // @Example: active + Status string `json:"status"` + + // Data plan assigned to the subscriber + // @Example: premium_5g + PlanID string `json:"plan_id"` + + // eSIM profile status + // @Enum: active,provisioning,inactive,failed + // @Example: active + ProfileStatus string `json:"profile_status"` + + // Account creation time + // @ReadOnly: true + // @Format: datetime + CreatedAt string `json:"created_at"` + + // Account last update time + // @ReadOnly: true + // @Format: datetime + UpdatedAt string `json:"updated_at"` +} + +// Service represents a Kubernetes service +// @Description Service represents a Kubernetes service in the platform +type Service struct { + // Name of the service + // @Example: api-server + Name string `json:"name"` + + // Kubernetes namespace where the service is deployed + // @Example: telecom-platform + Namespace string `json:"namespace"` + + // Number of desired replicas + // @Example: 3 + Replicas int32 `json:"replicas"` + + // Number of ready replicas + // @Example: 3 + ReadyReplicas int32 `json:"ready_replicas"` + + // Number of available replicas + // @Example: 3 + AvailableReplicas int32 `json:"available_replicas"` + + // Service creation timestamp + // @Format: datetime + CreationTimestamp string `json:"creation_timestamp"` +} + +// Deployment represents a deployment in the platform +// @Description Deployment represents a deployment in the platform +type Deployment struct { + // Unique identifier of the deployment + // @ReadOnly: true + ID uint `json:"id"` + + // Name of the service being deployed + // @Example: api-server + Service string `json:"service"` + + // Version being deployed + // @Example: v1.2.3 + Version string `json:"version"` + + // Current status of the deployment + // @Enum: completed,failed,running,pending,rolling_back + // @Example: completed + Status string `json:"status"` + + // Deployment start time + // @Format: datetime + StartedAt string `json:"started_at"` + + // Deployment completion time + // @Format: datetime + CompletedAt *string `json:"completed_at"` + + // Deployment metadata + Metadata map[string]any `json:"metadata"` +} + +// Plugin represents a platform plugin +// @Description Plugin represents a platform plugin +type Plugin struct { + // Unique identifier of the plugin + // @ReadOnly: true + ID uint `json:"id"` + + // Name of the plugin + // @Example: rate-limiter + Name string `json:"name"` + + // Version of the plugin + // @Example: v1.0.0 + Version string `json:"version"` + + // Author of the plugin + // @Example: Platform Team + Author string `json:"author"` + + // Description of the plugin + // @Example: Rate limiting plugin for API endpoints + Description string `json:"description"` + + // Whether the plugin is enabled + // @Example: true + Enabled bool `json:"enabled"` + + // Plugin configuration + // @Example: {"rate_limit": 100, "window": "1m"} + Config map[string]any `json:"config"` + + // Plugin installation time + // @Format: datetime + CreatedAt string `json:"created_at"` + + // Plugin last update time + // @Format: datetime + UpdatedAt string `json:"updated_at"` +} + +// Automation represents a workflow automation +// @Description Automation represents a workflow automation +type Automation struct { + // Unique identifier of the automation + // @ReadOnly: true + ID uint `json:"id"` + + // Name of the automation + // @Example: Daily Backup + Name string `json:"name"` + + // Description of the automation + // @Example: Backup database daily at midnight + Description string `json:"description"` + + // Trigger type for the automation + // @Enum: manual,schedule,webhook + // @Example: schedule + Trigger string `json:"trigger"` + + // Cron schedule for the automation + // @Example: 0 0 * * * + Schedule string `json:"schedule"` + + // Whether the automation is enabled + // @Example: true + Enabled bool `json:"enabled"` + + // Automation configuration + // @Example: {"backup_path": "/backups", "retention": "7d"} + Config map[string]any `json:"config"` + + // Automation creation time + // @Format: datetime + CreatedAt string `json:"created_at"` + + // Automation last update time + // @Format: datetime + UpdatedAt string `json:"updated_at"` +} + +// Payment represents a payment transaction +// @Description Payment represents a payment transaction +type Payment struct { + // Unique identifier of the payment + // @ReadOnly: true + ID uint `json:"id"` + + // Transaction ID + // @Example: txn_123456789 + TransactionID string `json:"transaction_id"` + + // Invoice ID associated with the payment + // @Example: inv_123456789 + InvoiceID string `json:"invoice_id"` + + // Payment method used + // @Enum: credit_card,debit_card,bank_transfer,paypal + // @Example: credit_card + Method string `json:"method"` + + // Payment amount + // @Example: 29.99 + Amount float64 `json:"amount"` + + // Payment status + // @Enum: pending,completed,failed,refunded + // @Example: completed + Status string `json:"status"` + + // Payment creation time + // @Format: datetime + CreatedAt string `json:"created_at"` +} + +// ConfigEntry represents a configuration entry +// @Description ConfigEntry represents a configuration entry +type ConfigEntry struct { + // Configuration key + // @Example: api_base_url + Key string `json:"key"` + + // Configuration value + // @Example: http://localhost:8000 + Value string `json:"value"` + + // Configuration description + // @Example: Base URL for API endpoints + Description string `json:"description"` + + // Whether the configuration is encrypted + // @Example: false + Encrypted bool `json:"encrypted"` +} + +// HealthStatus represents system health status +// @Description HealthStatus represents system health status +type HealthStatus struct { + // Overall health status + // @Enum: healthy,degraded,unhealthy + // @Example: healthy + Status string `json:"status"` + + // List of service health statuses + Services []ServiceHealth `json:"services"` + + // Health check timestamp + // @Format: datetime + Timestamp string `json:"timestamp"` +} + +// ServiceHealth represents individual service health +// @Description ServiceHealth represents individual service health +type ServiceHealth struct { + // Service name + // @Example: api-server + Name string `json:"name"` + + // Service health status + // @Enum: healthy,degraded,unhealthy + // @Example: healthy + Status string `json:"status"` + + // Service response time in milliseconds + // @Example: 45 + ResponseTime int `json:"response_time"` + + // Last health check time + // @Format: datetime + LastCheck string `json:"last_check"` +} + +// UsageEvent represents a usage event +// @Description UsageEvent represents a usage event +type UsageEvent struct { + // Event ID + // @Example: evt_123456789 + ID string `json:"id"` + + // Subscriber IMSI + // @Example: 208930000000001 + SubscriberIMSI string `json:"subscriber_imsi"` + + // Type of usage + // @Enum: data,voice,sms + // @Example: data + Type string `json:"type"` + + // Amount of usage (bytes, seconds, or count) + // @Example: 1048576 + Amount int64 `json:"amount"` + + // Event timestamp + // @Format: datetime + Timestamp string `json:"timestamp"` +} + +// MetricSample represents a metric data point +// @Description MetricSample represents a metric data point +type MetricSample struct { + // Metric timestamp + // @Format: datetime + Timestamp string `json:"timestamp"` + + // Metric value + // @Example: 42.5 + Value float64 `json:"value"` +} + +// Alert represents a monitoring alert +// @Description Alert represents a monitoring alert +type Alert struct { + // Alert name + // @Example: High CPU Usage + Name string `json:"name"` + + // Alert severity + // @Enum: critical,warning,info + // @Example: warning + Severity string `json:"severity"` + + // Alert state + // @Enum: firing,resolved + // @Example: firing + State string `json:"state"` + + // Alert summary + // @Example: CPU usage is above 80% + Summary string `json:"summary"` + + // Alert description + // @Example: CPU usage has been above 80% for more than 5 minutes + Description string `json:"description"` + + // Alert start time + // @Format: datetime + StartsAt string `json:"starts_at"` + + // Alert end time + // @Format: datetime + EndsAt *string `json:"ends_at"` +} + +// AutomationRun represents an automation execution run +// @Description AutomationRun represents an automation execution run +type AutomationRun struct { + // Run ID + // @Example: run_123456789 + ID uint `json:"id"` + + // Automation ID + // @Example: 1 + AutomationID uint `json:"automation_id"` + + // Run status + // @Enum: completed,failed,running,pending + // @Example: completed + Status string `json:"status"` + + // Run start time + // @Format: datetime + StartedAt string `json:"started_at"` + + // Run completion time + // @Format: datetime + CompletedAt *string `json:"completed_at"` + + // Run output + // @Example: Backup completed successfully + Output string `json:"output"` + + // Run error (if any) + // @Example: Backup failed: insufficient disk space + Error string `json:"error"` +} + +// APIResponse represents a standard API response +// @Description APIResponse represents a standard API response +type APIResponse struct { + // Response data + Data any `json:"data"` + + // Response message + Message string `json:"message"` + + // Success status + Success bool `json:"success"` +} diff --git a/apps/api-server/docs/auth.go b/apps/api-server/docs/auth.go new file mode 100644 index 0000000..0b1fb57 --- /dev/null +++ b/apps/api-server/docs/auth.go @@ -0,0 +1,177 @@ +package docs + +// LoginRequest represents a login request +// @Description LoginRequest represents a login request +type LoginRequest struct { + // Username of the user + // @Required: true + // @Example: admin + Username string `json:"username" binding:"required"` + + // Password of the user + // @Required: true + // @MinLength: 6 + // @Example: password123 + Password string `json:"password" binding:"required"` +} + +// LoginResponse represents a login response +// @Description LoginResponse represents a login response +type LoginResponse struct { + // JWT access token (15-minute expiry) + AccessToken string `json:"access_token"` + + // JWT refresh token (7-day expiry) + RefreshToken string `json:"refresh_token"` + + // User information + User User `json:"user"` +} + +// RegisterRequest represents a registration request +// @Description RegisterRequest represents a registration request +type RegisterRequest struct { + // Username of the user (must be unique) + // @Required: true + // @Example: testuser + Username string `json:"username" binding:"required"` + + // Email address of the user (must be unique) + // @Required: true + // @Format: email + // @Example: user@example.com + Email string `json:"email" binding:"required,email"` + + // Password for the user account + // @Required: true + // @MinLength: 6 + // @Example: password123 + Password string `json:"password" binding:"required,min=6"` + + // First name of the user + // @Required: true + // @Example: John + FirstName string `json:"first_name" binding:"required"` + + // Last name of the user + // @Required: true + // @Example: Doe + LastName string `json:"last_name" binding:"required"` + + // Role of the user (admin, operator, viewer) + // @Required: true + // @Enum: admin,operator,viewer + // @Example: viewer + Role string `json:"role" binding:"required,oneof=admin operator viewer"` +} + +// ChangePasswordRequest represents a password change request +// @Description ChangePasswordRequest represents a password change request +type ChangePasswordRequest struct { + // Current password of the user + // @Required: true + // @Example: oldpassword123 + OldPassword string `json:"old_password" binding:"required"` + + // New password for the user account + // @Required: true + // @MinLength: 6 + // @Example: newpassword123 + NewPassword string `json:"new_password" binding:"required,min=6"` +} + +// User represents a user account +// @Description User represents a user account in the system +type User struct { + // Unique identifier of the user + // @ReadOnly: true + ID uint `json:"id"` + + // Username of the user + // @Example: testuser + Username string `json:"username"` + + // Email address of the user + // @Format: email + // @Example: user@example.com + Email string `json:"email"` + + // First name of the user + // @Example: John + FirstName string `json:"first_name"` + + // Last name of the user + // @Example: Doe + LastName string `json:"last_name"` + + // Role of the user + // @Enum: admin,operator,viewer + // @Example: viewer + Role string `json:"role"` + + // Whether the user account is active + // @ReadOnly: true + // @Example: true + IsActive bool `json:"is_active"` + + // Last login time of the user + // @ReadOnly: true + // @Format: datetime + LastLogin *string `json:"last_login"` + + // Account creation time + // @ReadOnly: true + // @Format: datetime + CreatedAt string `json:"created_at"` + + // Account last update time + // @ReadOnly: true + // @Format: datetime + UpdatedAt string `json:"updated_at"` +} + +// ErrorResponse represents an error response +// @Description ErrorResponse represents an error response from the API +type ErrorResponse struct { + // Error message describing what went wrong + // @Example: Invalid credentials + Error string `json:"error"` +} + +// SuccessResponse represents a success response +// @Description SuccessResponse represents a success response from the API +type SuccessResponse struct { + // Success message + // @Example: Operation completed successfully + Message string `json:"message"` +} + +// PaginationResponse represents pagination information +// @Description PaginationResponse represents pagination information for list endpoints +type PaginationResponse struct { + // Current page number + // @Example: 1 + Page int `json:"page"` + + // Number of items per page + // @Example: 20 + Limit int `json:"limit"` + + // Total number of items + // @Example: 100 + Total int64 `json:"total"` + + // Total number of pages + // @Example: 5 + TotalPages int64 `json:"total_pages"` +} + +// UsersResponse represents a response with user list and pagination +// @Description UsersResponse represents a response with user list and pagination +type UsersResponse struct { + // List of users + Users []User `json:"users"` + + // Pagination information + Pagination PaginationResponse `json:"pagination"` +} diff --git a/apps/api-server/docs/docs.go b/apps/api-server/docs/docs.go new file mode 100644 index 0000000..fed8279 --- /dev/null +++ b/apps/api-server/docs/docs.go @@ -0,0 +1,117 @@ +// Package docs GENERATED BY SWAG; DO NOT EDIT +// This file was generated by swaggo/swag + +package docs + +import ( + "strings" + + "github.com/swaggo/swag" +) + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{.Description}}", + "title": "{{.Title}}", + "termsOfService": "{{.TermsOfService}}", + "contact": { + "name": "{{.ContactName}}", + "url": "{{.ContactURL}}", + "email": "{{.ContactEmail}}" + }, + "license": { + "name": "{{.LicenseName}}", + "url": "{{.LicenseURL}}" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": {}, + "definitions": {} +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = struct { + Host string + BasePath string + Schemes []string + Title string + Description string + Version string + // License information + LicenseName string + LicenseURL string + // Contact information + ContactName string + ContactURL string + ContactEmail string +}{ + Host: "localhost:8000", + BasePath: "/v1", + Schemes: []string{"http", "https"}, + Title: "Telecom Platform API", + Description: "A comprehensive telecom platform API for managing subscribers, services, monitoring, deployments, plugins, automation, and billing", + Version: "1.0.0", + LicenseName: "MIT", + LicenseURL: "https://opensource.org/licenses/MIT", + ContactName: "Telecom Platform Team", + ContactURL: "https://github.com/nutcas3/telecom-platform", + ContactEmail: "support@telecom-platform.com", +} + +type s struct{} + +func (s s) ReadDoc() string { + sInfo := SwaggerInfo + description := `Telecom Platform API + +This API provides comprehensive functionality for managing a telecom platform including: +- Subscriber management and eSIM provisioning +- Service management and Kubernetes integration +- Monitoring and metrics collection +- Deployment management +- Plugin system +- Workflow automation +- Billing and invoicing +- Configuration management +- Authentication and authorization + +## Authentication + +The API uses JWT (JSON Web Token) authentication. To access protected endpoints: +1. Register a user account +2. Login to obtain an access token +3. Include the token in the Authorization header: "Bearer " + +## Rate Limiting + +API requests are rate-limited to ensure fair usage. Current limits: +- 100 requests per minute per authenticated user +- 10 requests per minute for unauthenticated requests + +## Error Handling + +The API uses standard HTTP status codes: +- 200: Success +- 201: Created +- 400: Bad Request +- 401: Unauthorized +- 403: Forbidden +- 404: Not Found +- 500: Internal Server Error + +Error responses include a JSON object with an "error" field containing a descriptive message.` + + // Replace template placeholders with actual values + result := strings.Replace(docTemplate, "{{.Version}}", sInfo.Version, -1) + result = strings.Replace(result, "{{.Description}}", description, -1) + + return result +} + +func init() { + swag.Register(swag.Name, &s{}) +} diff --git a/apps/api-server/docs/swagger.go b/apps/api-server/docs/swagger.go new file mode 100644 index 0000000..785e813 --- /dev/null +++ b/apps/api-server/docs/swagger.go @@ -0,0 +1,25 @@ +package docs + +import ( + "github.com/swaggo/swag" +) + +// @title Telecom Platform API +// @version 1.0.0 +// @description A comprehensive telecom platform API for managing subscribers, services, monitoring, deployments, plugins, automation, and billing +// @termsOfService https://github.com/nutcas3/telecom-platform/blob/main/LICENSE +// @contact.name Telecom Platform Team +// @contact.url https://github.com/nutcas3/telecom-platform +// @contact.email support@telecom-platform.com +// @license.name MIT +// @license.url https://opensource.org/licenses/MIT +// @host localhost:8000 +// @BasePath /v1 +// @securityDefinitions.apikey BearerAuth +// @in header +// @name Authorization +// @description Type "Bearer" followed by a space and JWT token. + +func init() { + swag.Register(swag.Name, &s{}) +}