diff --git a/api/api/versions.json b/api/api/versions.json index b0a64a0f0..346fb54a5 100644 --- a/api/api/versions.json +++ b/api/api/versions.json @@ -3,7 +3,7 @@ { "version": "v1", "status": "active", - "release_date": "2025-10-29T22:13:12.29304044+05:30", + "release_date": "2025-10-31T19:02:08.937503+05:30", "end_of_life": "0001-01-01T00:00:00Z", "changes": [ "Initial API version" diff --git a/api/doc/openapi.json b/api/doc/openapi.json index 267b68113..1a5982f4f 100644 --- a/api/doc/openapi.json +++ b/api/doc/openapi.json @@ -1 +1 @@ -{"components":{"schemas":{"":{"description":" schema","properties":{"status":{"type":"string"}},"type":"object"},"ContainerLogsRequest":{"description":"ContainerLogsRequest schema","properties":{"follow":{"type":"boolean"},"id":{"type":"string"},"since":{"type":"string"},"stderr":{"type":"boolean"},"stdout":{"type":"boolean"},"tail":{"type":"integer"},"until":{"type":"string"}},"type":"object"},"CopyDirectory":{"description":"CopyDirectory schema","properties":{"from_path":{"type":"string"},"to_path":{"type":"string"}},"type":"object"},"CreateDeploymentRequest":{"description":"CreateDeploymentRequest schema","properties":{"base_path":{"nullable":true,"type":"string"},"branch":{"type":"string"},"build_pack":{"type":"string"},"build_variables":{"additionalProperties":{"type":"string"},"type":"object"},"dockerfile_path":{"nullable":true,"type":"string"},"domain":{"type":"string"},"environment":{"type":"string"},"environment_variables":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"port":{"type":"integer"},"post_run_command":{"type":"string"},"pre_run_command":{"type":"string"},"repository":{"type":"string"}},"type":"object"},"CreateDirectoryRequest":{"description":"CreateDirectoryRequest schema","properties":{"path":{"type":"string"}},"type":"object"},"CreateDomainRequest":{"description":"CreateDomainRequest schema","properties":{"name":{"type":"string"},"organization_id":{}},"type":"object"},"CreateGithubConnectorRequest":{"description":"CreateGithubConnectorRequest schema","properties":{"app_id":{"type":"string"},"client_id":{"type":"string"},"client_secret":{"type":"string"},"pem":{"type":"string"},"slug":{"type":"string"},"webhook_secret":{"type":"string"}},"type":"object"},"CreateOrganizationRequest":{"description":"CreateOrganizationRequest schema","properties":{"description":{"type":"string"},"name":{"type":"string"}},"type":"object"},"CreateSMTPConfigRequest":{"description":"CreateSMTPConfigRequest schema","properties":{"from_email":{"type":"string"},"from_name":{"type":"string"},"host":{"type":"string"},"organization_id":{},"password":{"type":"string"},"port":{"type":"integer"},"username":{"type":"string"}},"type":"object"},"CreateWebhookConfigRequest":{"description":"CreateWebhookConfigRequest schema","properties":{"type":{"type":"string"},"webhook_url":{"type":"string"}},"required":["type"],"type":"object"},"DeleteDeploymentRequest":{"description":"DeleteDeploymentRequest schema","properties":{"id":{}},"type":"object"},"DeleteDirectoryRequest":{"description":"DeleteDirectoryRequest schema","properties":{"path":{"type":"string"}},"type":"object"},"DeleteDomainRequest":{"description":"DeleteDomainRequest schema","properties":{"id":{"type":"string"}},"type":"object"},"DeleteOrganizationRequest":{"description":"DeleteOrganizationRequest schema","properties":{"id":{"type":"string"}},"type":"object"},"DeleteSMTPConfigRequest":{"description":"DeleteSMTPConfigRequest schema","properties":{"id":{}},"type":"object"},"DeleteWebhookConfigRequest":{"description":"DeleteWebhookConfigRequest schema","properties":{"type":{"type":"string"}},"required":["type"],"type":"object"},"Extension":{"nullable":true,"properties":{"author":{"type":"string"},"category":{"type":"string"},"content_hash":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deleted_at":{"format":"date-time","nullable":true,"type":"string"},"description":{"type":"string"},"extension_id":{"type":"string"},"extension_type":{"type":"string"},"icon":{"type":"string"},"id":{},"is_verified":{"type":"boolean"},"name":{"type":"string"},"parent_extension_id":{"nullable":true},"parsed_content":{"type":"string"},"updated_at":{"format":"date-time","type":"string"},"validation_errors":{"type":"string"},"validation_status":{"type":"string"},"variables":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"default_value":{},"description":{"type":"string"},"extension":{"$ref":"#/components/schemas/Extension"},"extension_id":{},"id":{},"is_required":{"type":"boolean"},"validation_pattern":{"type":"string"},"variable_name":{"type":"string"},"variable_type":{"type":"string"}},"type":"object"},"type":"array"},"version":{"type":"string"},"yaml_content":{"type":"string"}},"type":"object"},"ExtensionCategory":{"description":"ExtensionCategory schema","type":"string"},"ExtensionExecution":{"description":"ExtensionExecution schema","properties":{"completed_at":{"format":"date-time","nullable":true,"type":"string"},"created_at":{"format":"date-time","type":"string"},"error_message":{"type":"string"},"execution_log":{"type":"string"},"exit_code":{"type":"integer"},"extension":{"nullable":true,"properties":{"author":{"type":"string"},"category":{"type":"string"},"content_hash":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deleted_at":{"format":"date-time","nullable":true,"type":"string"},"description":{"type":"string"},"extension_id":{"type":"string"},"extension_type":{"type":"string"},"icon":{"type":"string"},"id":{},"is_verified":{"type":"boolean"},"name":{"type":"string"},"parent_extension_id":{"nullable":true},"parsed_content":{"type":"string"},"updated_at":{"format":"date-time","type":"string"},"validation_errors":{"type":"string"},"validation_status":{"type":"string"},"variables":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"default_value":{},"description":{"type":"string"},"extension":{"$ref":"#/components/schemas/Extension"},"extension_id":{},"id":{},"is_required":{"type":"boolean"},"validation_pattern":{"type":"string"},"variable_name":{"type":"string"},"variable_type":{"type":"string"}},"type":"object"},"type":"array"},"version":{"type":"string"},"yaml_content":{"type":"string"}},"type":"object"},"extension_id":{},"id":{},"log_seq":{"format":"int64","type":"integer"},"server_hostname":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"steps":{"items":{"properties":{"completed_at":{"format":"date-time","nullable":true,"type":"string"},"created_at":{"format":"date-time","type":"string"},"execution":{"$ref":"#/components/schemas/ExtensionExecution"},"execution_id":{},"exit_code":{"type":"integer"},"id":{},"output":{"type":"string"},"phase":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"step_name":{"type":"string"},"step_order":{"type":"integer"}},"type":"object"},"nullable":true,"type":"array"},"variable_values":{"type":"string"}},"type":"object"},"ExtensionListResponse":{"description":"ExtensionListResponse schema","properties":{"extensions":{"items":{"properties":{"author":{"type":"string"},"category":{"type":"string"},"content_hash":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deleted_at":{"format":"date-time","nullable":true,"type":"string"},"description":{"type":"string"},"extension_id":{"type":"string"},"extension_type":{"type":"string"},"icon":{"type":"string"},"id":{},"is_verified":{"type":"boolean"},"name":{"type":"string"},"parent_extension_id":{"nullable":true},"parsed_content":{"type":"string"},"updated_at":{"format":"date-time","type":"string"},"validation_errors":{"type":"string"},"validation_status":{"type":"string"},"variables":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"default_value":{},"description":{"type":"string"},"extension":{"$ref":"#/components/schemas/Extension"},"extension_id":{},"id":{},"is_required":{"type":"boolean"},"validation_pattern":{"type":"string"},"variable_name":{"type":"string"},"variable_type":{"type":"string"}},"type":"object"},"type":"array"},"version":{"type":"string"},"yaml_content":{"type":"string"}},"type":"object"},"type":"array"},"page":{"type":"integer"},"page_size":{"type":"integer"},"total":{"type":"integer"},"total_pages":{"type":"integer"}},"type":"object"},"ForkExtensionRequest":{"description":"ForkExtensionRequest schema","properties":{"yaml_content":{"nullable":true,"type":"string"}},"type":"object"},"GetApplicationDeploymentsRequest":{"description":"GetApplicationDeploymentsRequest schema","properties":{"id":{"type":"string"},"limit":{"type":"string"},"page":{"type":"string"}},"type":"object"},"GetApplicationsRequest":{"description":"GetApplicationsRequest schema","properties":{"page":{"type":"string"},"page_size":{"type":"string"},"repository":{"type":"string"}},"type":"object"},"GetGithubRepositoryBranchesRequest":{"description":"GetGithubRepositoryBranchesRequest schema","properties":{"repository_name":{"type":"string"}},"required":["repository_name"],"type":"object"},"GetOrganizationUsersRequest":{"description":"GetOrganizationUsersRequest schema","properties":{"id":{"type":"string"}},"type":"object"},"HTTPError":{"description":"HTTPError schema","properties":{"detail":{"description":"Human readable error message","nullable":true,"type":"string"},"errors":{"items":{"properties":{"more":{"additionalProperties":{},"type":"object"},"name":{"type":"string"},"reason":{"type":"string"}},"type":"object"},"nullable":true,"type":"array"},"instance":{"nullable":true,"type":"string"},"status":{"description":"HTTP status code","example":403,"nullable":true,"type":"integer"},"title":{"description":"Short title of the error","nullable":true,"type":"string"},"type":{"description":"URL of the error type. Can be used to lookup the error in a documentation","nullable":true,"type":"string"}},"type":"object"},"InviteResendRequest":{"description":"InviteResendRequest schema","properties":{"email":{"type":"string"},"organization_id":{"type":"string"},"role":{"type":"string"}},"type":"object"},"InviteSendRequest":{"description":"InviteSendRequest schema","properties":{"email":{"type":"string"},"organization_id":{"type":"string"},"role":{"type":"string"}},"type":"object"},"ListFilesRequest":{"description":"ListFilesRequest schema","properties":{"path":{"type":"string"}},"type":"object"},"ListImagesRequest":{"description":"ListImagesRequest schema","properties":{"all":{"nullable":true,"type":"boolean"},"container_id":{"nullable":true,"type":"string"},"image_prefix":{"nullable":true,"type":"string"}},"type":"object"},"ListLogsResponse":{"description":"ListLogsResponse schema","properties":{"execution_status":{"nullable":true,"type":"string"},"logs":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"data":{},"execution_id":{},"id":{},"level":{"type":"string"},"message":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"step_id":{"nullable":true}},"type":"object"},"type":"array"},"next_after":{"format":"int64","type":"integer"}},"type":"object"},"LogoutRequest":{"description":"LogoutRequest schema","properties":{"refresh_token":{"type":"string"}},"type":"object"},"MoveDirectory":{"description":"MoveDirectory schema","properties":{"from_path":{"type":"string"},"to_path":{"type":"string"}},"type":"object"},"PruneBuildCacheRequest":{"description":"PruneBuildCacheRequest schema","properties":{"all":{"nullable":true,"type":"boolean"},"filters":{"nullable":true,"type":"string"}},"type":"object"},"PruneImagesRequest":{"description":"PruneImagesRequest schema","properties":{"dangling":{"nullable":true,"type":"boolean"},"label":{"nullable":true,"type":"string"},"until":{"nullable":true,"type":"string"}},"type":"object"},"ReDeployApplicationRequest":{"description":"ReDeployApplicationRequest schema","properties":{"force":{"type":"boolean"},"force_without_cache":{"type":"boolean"},"id":{}},"type":"object"},"RegisterRequest":{"description":"RegisterRequest schema","properties":{"email":{"type":"string"},"organization":{"type":"string"},"password":{"type":"string"},"type":{"type":"string"},"username":{"type":"string"}},"type":"object"},"RemoveUserFromOrganizationRequest":{"description":"RemoveUserFromOrganizationRequest schema","properties":{"organization_id":{"type":"string"},"user_id":{"type":"string"}},"type":"object"},"Response":{"description":"Response schema","properties":{"data":{"nullable":true},"error":{"nullable":true,"type":"string"},"message":{"nullable":true,"type":"string"},"status":{"type":"string"}},"type":"object"},"RestartDeploymentRequest":{"description":"RestartDeploymentRequest schema","properties":{"id":{}},"type":"object"},"RollbackDeploymentRequest":{"description":"RollbackDeploymentRequest schema","properties":{"id":{}},"type":"object"},"RunExtensionRequest":{"description":"RunExtensionRequest schema","properties":{"variables":{"additionalProperties":{},"type":"object"}},"type":"object"},"TwoFactorLoginRequest":{"description":"TwoFactorLoginRequest schema","properties":{"code":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"}},"type":"object"},"TwoFactorVerifyRequest":{"description":"TwoFactorVerifyRequest schema","properties":{"code":{"type":"string"}},"type":"object"},"UpdateAutoUpdateRequest":{"description":"UpdateAutoUpdateRequest schema","properties":{"auto_update":{"type":"boolean"}},"type":"object"},"UpdateAvatarRequest":{"description":"UpdateAvatarRequest schema","properties":{"avatarData":{"type":"string"}},"type":"object"},"UpdateCheckResponse":{"description":"UpdateCheckResponse schema","properties":{"current_version":{"type":"string"},"environment":{"type":"string"},"last_checked":{"format":"date-time","type":"string"},"latest_version":{"type":"string"},"update_available":{"type":"boolean"}},"type":"object"},"UpdateDeploymentRequest":{"description":"UpdateDeploymentRequest schema","properties":{"base_path":{"nullable":true,"type":"string"},"build_variables":{"additionalProperties":{"type":"string"},"nullable":true,"type":"object"},"dockerfile_path":{"nullable":true,"type":"string"},"environment_variables":{"additionalProperties":{"type":"string"},"nullable":true,"type":"object"},"force":{"nullable":true,"type":"boolean"},"id":{"nullable":true},"name":{"nullable":true,"type":"string"},"port":{"nullable":true,"type":"integer"},"post_run_command":{"nullable":true,"type":"string"},"pre_run_command":{"nullable":true,"type":"string"}},"type":"object"},"UpdateDomainRequest":{"description":"UpdateDomainRequest schema","properties":{"id":{"type":"string"},"name":{"type":"string"}},"type":"object"},"UpdateFeatureFlagRequest":{"description":"UpdateFeatureFlagRequest schema","properties":{"feature_name":{"type":"string"},"is_enabled":{"type":"boolean"}},"required":["feature_name"],"type":"object"},"UpdateFontRequest":{"description":"UpdateFontRequest schema","properties":{"font_family":{"type":"string"},"font_size":{"type":"integer"}},"type":"object"},"UpdateGithubConnectorRequest":{"description":"UpdateGithubConnectorRequest schema","properties":{"installation_id":{"type":"string"}},"type":"object"},"UpdateLanguageRequest":{"description":"UpdateLanguageRequest schema","properties":{"language":{"type":"string"}},"type":"object"},"UpdateOrganizationRequest":{"description":"UpdateOrganizationRequest schema","properties":{"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}},"type":"object"},"UpdatePreferenceRequest":{"description":"UpdatePreferenceRequest schema","properties":{"category":{"type":"string"},"enabled":{"type":"boolean"},"type":{"type":"string"}},"required":["category","type"],"type":"object"},"UpdateRequest":{"description":"UpdateRequest schema","properties":{"force":{"type":"boolean"}},"type":"object"},"UpdateResponse":{"description":"UpdateResponse schema","properties":{"message":{"type":"string"},"success":{"type":"boolean"}},"type":"object"},"UpdateSMTPConfigRequest":{"description":"UpdateSMTPConfigRequest schema","properties":{"from_email":{"nullable":true,"type":"string"},"from_name":{"nullable":true,"type":"string"},"host":{"nullable":true,"type":"string"},"id":{},"organization_id":{},"password":{"nullable":true,"type":"string"},"port":{"nullable":true,"type":"integer"},"username":{"nullable":true,"type":"string"}},"type":"object"},"UpdateThemeRequest":{"description":"UpdateThemeRequest schema","properties":{"theme":{"type":"string"}},"type":"object"},"UpdateUserNameRequest":{"description":"UpdateUserNameRequest schema","properties":{"name":{"type":"string"}},"type":"object"},"UpdateUserRoleRequest":{"description":"UpdateUserRoleRequest schema","properties":{"organization_id":{"type":"string"},"role":{"type":"string"},"user_id":{"type":"string"}},"type":"object"},"UpdateWebhookConfigRequest":{"description":"UpdateWebhookConfigRequest schema","properties":{"is_active":{"nullable":true,"type":"boolean"},"type":{"type":"string"},"webhook_url":{"nullable":true,"type":"string"}},"required":["type"],"type":"object"},"unknown-interface":{"description":"unknown-interface schema"}},"securitySchemes":{"bearerAuth":{"bearerFormat":"JWT","description":"Enter your JWT token in the format: Bearer \u003ctoken\u003e","scheme":"bearer","type":"http"}}},"info":{"description":"\nThis is the autogenerated OpenAPI documentation for your [Fuego](https://github.com/go-fuego/fuego) API.\n\nBelow is a Fuego Cheatsheet to help you get started. Don't hesitate to check the [Fuego documentation](https://go-fuego.dev) for more details.\n\nHappy coding! 🔥\n\n## Usage\n\n### Route registration\n\n```go\nfunc main() {\n\t// Create a new server\n\ts := fuego.NewServer()\n\n\t// Register some routes\n\tfuego.Post(s, \"/hello\", myController)\n\tfuego.Get(s, \"/myPath\", otherController)\n\tfuego.Put(s, \"/hello\", thirdController)\n\n\tadminRoutes := fuego.Group(s, \"/admin\")\n\tfuego.Use(adminRoutes, myMiddleware) // This middleware (for authentication, etc...) will be available for routes starting by /admin/*, \n\tfuego.Get(adminRoutes, \"/hello\", groupController) // This route will be available at /admin/hello\n\n\t// Start the server\n\ts.Start()\n}\n```\n\n### Basic controller\n\n```go\ntype MyBody struct {\n\tName string `json:\"name\" validate:\"required,max=30\"`\n}\n\ntype MyResponse struct {\n\tAnswer string `json:\"answer\"`\n}\n\nfunc hello(ctx fuego.ContextWithBody[MyBody]) (*MyResponse, error) {\n\tbody, err := ctx.Body()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn \u0026MyResponse{Answer: \"Hello \" + body.Name}, nil\n}\n```\n\n### Add openAPI information to the route\n\n```go\nimport (\n\t\"github.com/go-fuego/fuego\"\n\t\"github.com/go-fuego/fuego/option\"\n\t\"github.com/go-fuego/fuego/param\"\n)\n\nfunc main() {\n\ts := fuego.NewServer()\n\n\t// Custom OpenAPI options\n\tfuego.Post(s, \"/\", myController\n\t\toption.Description(\"This route does something...\"),\n\t\toption.Summary(\"This is my summary\"),\n\t\toption.Tags(\"MyTag\"), // A tag is set by default according to the return type (can be deactivated)\n\t\toption.Deprecated(), // Marks the route as deprecated in the OpenAPI spec\n\n\t\toption.Query(\"name\", \"Declares a query parameter with default value\", param.Default(\"Carmack\")),\n\t\toption.Header(\"Authorization\", \"Bearer token\", param.Required()),\n\t\toptionPagination,\n\t\toptionCustomBehavior,\n\t)\n\n\ts.Run()\n}\n\nvar optionPagination = option.Group(\n\toption.QueryInt(\"page\", \"Page number\", param.Default(1), param.Example(\"1st page\", 1), param.Example(\"42nd page\", 42)),\n\toption.QueryInt(\"perPage\", \"Number of items per page\"),\n)\n\nvar optionCustomBehavior = func(r *fuego.BaseRoute) {\n\tr.XXX = \"YYY\"\n}\n```\n\nThen, in the controller\n\n```go\ntype MyResponse struct {\n\tAnswer string `json:\"answer\"`\n}\n\nfunc getAllPets(ctx fuego.ContextNoBody) (*MyResponse, error) {\n\tname := ctx.QueryParam(\"name\")\n\tperPage, _ := ctx.QueryParamIntErr(\"per_page\")\n\n\treturn \u0026MyResponse{Answer: \"Hello \" + name}, nil\n}\n```\n","title":"OpenAPI","version":"0.0.1"},"openapi":"3.1.0","paths":{"/api/v1/audit/logs":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/audit/controller.(*AuditController).GetRecentAuditLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func23`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func24`\n\n---\n\n","operationId":"GET_/api/v1/audit/logs","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get recent audit logs","tags":["api/v1/audit"]}},"/api/v1/auth/2fa-login":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).TwoFactorLogin`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/2fa-login","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/TwoFactorLoginRequest"}}},"description":"Request body for types.TwoFactorLoginRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"two factor login","tags":["api/v1/auth"]}},"/api/v1/auth/create-user":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).CreateUser`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/create-user","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"description":"Request body for types.RegisterRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create user","tags":["api/v1/auth"]}},"/api/v1/auth/disable-2fa":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).DisableTwoFactor`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/disable-2fa","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"disable two factor","tags":["api/v1/auth"]}},"/api/v1/auth/is-admin-registered":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).IsAdminRegistered`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"GET_/api/v1/auth/is-admin-registered","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"is admin registered","tags":["api/v1/auth"]}},"/api/v1/auth/logout":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).Logout`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/logout","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/LogoutRequest"}}},"description":"Request body for types.LogoutRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"logout","tags":["api/v1/auth"]}},"/api/v1/auth/send-verification-email":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).SendVerificationEmail`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/send-verification-email","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"send verification email","tags":["api/v1/auth"]}},"/api/v1/auth/setup-2fa":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).SetupTwoFactor`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/setup-2fa","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"setup two factor","tags":["api/v1/auth"]}},"/api/v1/auth/verify-2fa":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).VerifyTwoFactor`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/verify-2fa","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/TwoFactorVerifyRequest"}}},"description":"Request body for types.TwoFactorVerifyRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"verify two factor","tags":["api/v1/auth"]}},"/api/v1/auth/verify-email":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).VerifyEmail`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"GET_/api/v1/auth/verify-email","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"verify email","tags":["api/v1/auth"]}},"/api/v1/container":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).ListContainers`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"GET_/api/v1/container","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list containers","tags":["api/v1/container"]}},"/api/v1/container/images":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).ListImages`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/images","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ListImagesRequest"}}},"description":"Request body for controller.ListImagesRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list images","tags":["api/v1/container"]}},"/api/v1/container/prune/build-cache":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).PruneBuildCache`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/prune/build-cache","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PruneBuildCacheRequest"}}},"description":"Request body for controller.PruneBuildCacheRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"prune build cache","tags":["api/v1/container"]}},"/api/v1/container/prune/images":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).PruneImages`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/prune/images","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PruneImagesRequest"}}},"description":"Request body for controller.PruneImagesRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"prune images","tags":["api/v1/container"]}},"/api/v1/container/{container_id}":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).RemoveContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"DELETE_/api/v1/container/:container_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"remove container","tags":["api/v1/container"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).GetContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"GET_/api/v1/container/:container_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get container","tags":["api/v1/container"]}},"/api/v1/container/{container_id}/logs":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).GetContainerLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/:container_id/logs","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ContainerLogsRequest"}}},"description":"Request body for types.ContainerLogsRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get container logs","tags":["api/v1/container"]}},"/api/v1/container/{container_id}/restart":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).RestartContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/:container_id/restart","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"restart container","tags":["api/v1/container"]}},"/api/v1/container/{container_id}/start":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).StartContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/:container_id/start","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"start container","tags":["api/v1/container"]}},"/api/v1/container/{container_id}/stop":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).StopContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/:container_id/stop","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"stop container","tags":["api/v1/container"]}},"/api/v1/deploy/application":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).DeleteApplication`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"DELETE_/api/v1/deploy/application","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteDeploymentRequest"}}},"description":"Request body for types.DeleteDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete application","tags":["api/v1/deploy","application"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetApplicationById`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get application by id","tags":["api/v1/deploy","application"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).HandleDeploy`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"POST_/api/v1/deploy/application","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateDeploymentRequest"}}},"description":"Request body for types.CreateDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"handle deploy","tags":["api/v1/deploy","application"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).UpdateApplication`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"PUT_/api/v1/deploy/application","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateDeploymentRequest"}}},"description":"Request body for types.UpdateDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update application","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/deployments":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetApplicationDeployments`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application/deployments","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetApplicationDeploymentsRequest"}}},"description":"Request body for controller.GetApplicationDeploymentsRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get application deployments","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/deployments/{deployment_id}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetDeploymentById`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application/deployments/:deployment_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"deployment_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get deployment by id","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/deployments/{deployment_id}/logs":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetDeploymentLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application/deployments/:deployment_id/logs","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"deployment_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get deployment logs","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/logs/{application_id}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application/logs/:application_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"application_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get logs","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/redeploy":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).ReDeployApplication`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"POST_/api/v1/deploy/application/redeploy","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReDeployApplicationRequest"}}},"description":"Request body for types.ReDeployApplicationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"re deploy application","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/restart":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).HandleRestart`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"POST_/api/v1/deploy/application/restart","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RestartDeploymentRequest"}}},"description":"Request body for types.RestartDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"handle restart","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/rollback":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).HandleRollback`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"POST_/api/v1/deploy/application/rollback","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RollbackDeploymentRequest"}}},"description":"Request body for types.RollbackDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"handle rollback","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/applications":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetApplications`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/applications","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetApplicationsRequest"}}},"description":"Request body for controller.GetApplicationsRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get applications","tags":["api/v1/deploy"]}},"/api/v1/domain":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).DeleteDomain`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func3`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func5`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func7`\n\n---\n\n","operationId":"DELETE_/api/v1/domain","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteDomainRequest"}}},"description":"Request body for types.DeleteDomainRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete domain","tags":["api/v1/domain"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).CreateDomain`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func3`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func5`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func7`\n\n---\n\n","operationId":"POST_/api/v1/domain","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateDomainRequest"}}},"description":"Request body for types.CreateDomainRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create domain","tags":["api/v1/domain"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).UpdateDomain`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func3`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func5`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func7`\n\n---\n\n","operationId":"PUT_/api/v1/domain","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateDomainRequest"}}},"description":"Request body for types.UpdateDomainRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update domain","tags":["api/v1/domain"]}},"/api/v1/domain/generate":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).GenerateRandomSubDomain`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func3`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func5`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func7`\n\n---\n\n","operationId":"GET_/api/v1/domain/generate","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"generate random sub domain","tags":["api/v1/domain"]}},"/api/v1/domains":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).GetDomains`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func4`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func6`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func8`\n\n---\n\n","operationId":"GET_/api/v1/domains","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get domains","tags":["api/v1/domains"]}},"/api/v1/extensions":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetExtensions`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionListResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ExtensionListResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get extensions","tags":["api/v1/extensions"]}},"/api/v1/extensions/by-extension-id/{extension_id}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetExtensionByExtensionID`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/by-extension-id/:extension_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"extension_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Extension"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get extension by extension i d","tags":["api/v1/extensions"]}},"/api/v1/extensions/by-extension-id/{extension_id}/executions":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).ListExecutionsByExtensionID`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/by-extension-id/:extension_id/executions","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"extension_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ExtensionExecution"},"type":"array"}},"application/xml":{"schema":{"items":{"$ref":"#/components/schemas/ExtensionExecution"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list executions by extension i d","tags":["api/v1/extensions"]}},"/api/v1/extensions/categories":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetCategories`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/categories","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ExtensionCategory"},"type":"array"}},"application/xml":{"schema":{"items":{"$ref":"#/components/schemas/ExtensionCategory"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get categories","tags":["api/v1/extensions"]}},"/api/v1/extensions/execution/{execution_id}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetExecution`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/execution/:execution_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionExecution"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ExtensionExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get execution","tags":["api/v1/extensions"]}},"/api/v1/extensions/execution/{execution_id}/cancel":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).CancelExecution`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"POST_/api/v1/extensions/execution/:execution_id/cancel","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"cancel execution","tags":["api/v1/extensions"]}},"/api/v1/extensions/execution/{execution_id}/logs":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).ListExecutionLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/execution/:execution_id/logs","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLogsResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ListLogsResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list execution logs","tags":["api/v1/extensions"]}},"/api/v1/extensions/{extension_id}/fork":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).ForkExtension`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"POST_/api/v1/extensions/:extension_id/fork","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"extension_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ForkExtensionRequest"}}},"description":"Request body for controller.ForkExtensionRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Extension"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"fork extension","tags":["api/v1/extensions"]}},"/api/v1/extensions/{extension_id}/run":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).RunExtension`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"POST_/api/v1/extensions/:extension_id/run","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"extension_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RunExtensionRequest"}}},"description":"Request body for controller.RunExtensionRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionExecution"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ExtensionExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"run extension","tags":["api/v1/extensions"]}},"/api/v1/extensions/{id}":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).DeleteFork`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"DELETE_/api/v1/extensions/:id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/"}},"application/xml":{"schema":{"$ref":"#/components/schemas/"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete fork","tags":["api/v1/extensions"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetExtension`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/:id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Extension"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get extension","tags":["api/v1/extensions"]}},"/api/v1/feature-flags":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/feature-flags/controller.(*FeatureFlagController).GetFeatureFlags`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"GET_/api/v1/feature-flags","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get feature flags","tags":["api/v1/feature-flags"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/feature-flags/controller.(*FeatureFlagController).UpdateFeatureFlag`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func25`\n\n---\n\n","operationId":"PUT_/api/v1/feature-flags","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateFeatureFlagRequest"}}},"description":"Request body for types.UpdateFeatureFlagRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update feature flag","tags":["api/v1/feature-flags"]}},"/api/v1/feature-flags/check":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/feature-flags/controller.(*FeatureFlagController).IsFeatureEnabled`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"GET_/api/v1/feature-flags/check","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"is feature enabled","tags":["api/v1/feature-flags"]}},"/api/v1/file-manager":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).ListFiles`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"GET_/api/v1/file-manager","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ListFilesRequest"}}},"description":"Request body for controller.ListFilesRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list files","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/copy-directory":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).CopyDirectory`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"POST_/api/v1/file-manager/copy-directory","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CopyDirectory"}}},"description":"Request body for controller.CopyDirectory","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"copy directory","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/create-directory":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).CreateDirectory`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"POST_/api/v1/file-manager/create-directory","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateDirectoryRequest"}}},"description":"Request body for controller.CreateDirectoryRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create directory","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/delete-directory":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).DeleteDirectory`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"DELETE_/api/v1/file-manager/delete-directory","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteDirectoryRequest"}}},"description":"Request body for controller.DeleteDirectoryRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete directory","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/move-directory":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).MoveDirectory`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"POST_/api/v1/file-manager/move-directory","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MoveDirectory"}}},"description":"Request body for controller.MoveDirectory","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"move directory","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/upload":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).UploadFile`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"POST_/api/v1/file-manager/upload","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"upload file","tags":["api/v1/file-manager"]}},"/api/v1/github-connector":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).CreateGithubConnector`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"POST_/api/v1/github-connector","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateGithubConnectorRequest"}}},"description":"Request body for types.CreateGithubConnectorRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create github connector","tags":["api/v1/github-connector"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).UpdateGithubConnectorRequest`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"PUT_/api/v1/github-connector","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateGithubConnectorRequest"}}},"description":"Request body for types.UpdateGithubConnectorRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update github connector request","tags":["api/v1/github-connector"]}},"/api/v1/github-connector/all":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).GetGithubConnectors`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"GET_/api/v1/github-connector/all","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get github connectors","tags":["api/v1/github-connector"]}},"/api/v1/github-connector/repositories":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).GetGithubRepositories`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"GET_/api/v1/github-connector/repositories","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get github repositories","tags":["api/v1/github-connector"]}},"/api/v1/github-connector/repository/branches":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).GetGithubRepositoryBranches`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"POST_/api/v1/github-connector/repository/branches","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetGithubRepositoryBranchesRequest"}}},"description":"Request body for controller.GetGithubRepositoryBranchesRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get github repository branches","tags":["api/v1/github-connector"]}},"/api/v1/health":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/health.HealthCheck`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"GET_/api/v1/health","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"health check","tags":["api/v1/health"]}},"/api/v1/health/versions":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal.(*Router).BasicRoutes.func1`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"GET_/api/v1/health/versions","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/unknown-interface"}},"application/xml":{"schema":{"$ref":"#/components/schemas/unknown-interface"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"func1","tags":["api/v1/health","versions"]}},"/api/v1/notification/preferences":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).GetPreferences`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"GET_/api/v1/notification/preferences","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get preferences","tags":["api/v1/notification","preferences"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).UpdatePreference`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"POST_/api/v1/notification/preferences","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdatePreferenceRequest"}}},"description":"Request body for notification.UpdatePreferenceRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update preference","tags":["api/v1/notification","preferences"]}},"/api/v1/notification/smtp":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).DeleteSmtp`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"DELETE_/api/v1/notification/smtp","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteSMTPConfigRequest"}}},"description":"Request body for notification.DeleteSMTPConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete smtp","tags":["api/v1/notification","smtp"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).GetSmtp`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"GET_/api/v1/notification/smtp","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get smtp","tags":["api/v1/notification","smtp"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).AddSmtp`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"POST_/api/v1/notification/smtp","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateSMTPConfigRequest"}}},"description":"Request body for notification.CreateSMTPConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"add smtp","tags":["api/v1/notification","smtp"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).UpdateSmtp`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"PUT_/api/v1/notification/smtp","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateSMTPConfigRequest"}}},"description":"Request body for notification.UpdateSMTPConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update smtp","tags":["api/v1/notification","smtp"]}},"/api/v1/notification/webhook":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).DeleteWebhookConfig`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"DELETE_/api/v1/notification/webhook","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteWebhookConfigRequest"}}},"description":"Request body for notification.DeleteWebhookConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete webhook config","tags":["api/v1/notification","webhook"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).CreateWebhookConfig`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"POST_/api/v1/notification/webhook","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateWebhookConfigRequest"}}},"description":"Request body for notification.CreateWebhookConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create webhook config","tags":["api/v1/notification","webhook"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).UpdateWebhookConfig`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"PUT_/api/v1/notification/webhook","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateWebhookConfigRequest"}}},"description":"Request body for notification.UpdateWebhookConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update webhook config","tags":["api/v1/notification","webhook"]}},"/api/v1/notification/webhook/{type}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).GetWebhookConfig`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"GET_/api/v1/notification/webhook/:type","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"type","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get webhook config","tags":["api/v1/notification","webhook"]}},"/api/v1/organizations":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).DeleteOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"DELETE_/api/v1/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteOrganizationRequest"}}},"description":"Request body for types.DeleteOrganizationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete organization","tags":["api/v1/organizations"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).GetOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"GET_/api/v1/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get organization","tags":["api/v1/organizations"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).CreateOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Request body for types.CreateOrganizationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create organization","tags":["api/v1/organizations"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).UpdateOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"PUT_/api/v1/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationRequest"}}},"description":"Request body for types.UpdateOrganizationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update organization","tags":["api/v1/organizations"]}},"/api/v1/organizations/all":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).GetOrganizations`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"GET_/api/v1/organizations/all","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get organizations","tags":["api/v1/organizations"]}},"/api/v1/organizations/invite/resend":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).ResendInvite`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations/invite/resend","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteResendRequest"}}},"description":"Request body for types.InviteResendRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"resend invite","tags":["api/v1/organizations"]}},"/api/v1/organizations/invite/send":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).SendInvite`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations/invite/send","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteSendRequest"}}},"description":"Request body for types.InviteSendRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"send invite","tags":["api/v1/organizations"]}},"/api/v1/organizations/remove-user":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).RemoveUserFromOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations/remove-user","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RemoveUserFromOrganizationRequest"}}},"description":"Request body for types.RemoveUserFromOrganizationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"remove user from organization","tags":["api/v1/organizations"]}},"/api/v1/organizations/update-user-role":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).UpdateUserRole`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations/update-user-role","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateUserRoleRequest"}}},"description":"Request body for types.UpdateUserRoleRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update user role","tags":["api/v1/organizations"]}},"/api/v1/organizations/users":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).GetOrganizationUsers`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"GET_/api/v1/organizations/users","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetOrganizationUsersRequest"}}},"description":"Request body for controller.GetOrganizationUsersRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get organization users","tags":["api/v1/organizations"]}},"/api/v1/update":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/update/controller.(*UpdateController).PerformUpdate`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/update","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateRequest"}}},"description":"Request body for types.UpdateRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/UpdateResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"perform update","tags":["api/v1/update"]}},"/api/v1/update/check":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/update/controller.(*UpdateController).CheckForUpdates`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"GET_/api/v1/update/check","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCheckResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/UpdateCheckResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"check for updates","tags":["api/v1/update"]}},"/api/v1/user":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).GetUserDetails`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"GET_/api/v1/user","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get user details","tags":["api/v1/user"]}},"/api/v1/user/avatar":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateAvatar`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/avatar","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateAvatarRequest"}}},"description":"Request body for types.UpdateAvatarRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update avatar","tags":["api/v1/user"]}},"/api/v1/user/name":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateUserName`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/name","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateUserNameRequest"}}},"description":"Request body for types.UpdateUserNameRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update user name","tags":["api/v1/user"]}},"/api/v1/user/organizations":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).GetUserOrganizations`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"GET_/api/v1/user/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get user organizations","tags":["api/v1/user"]}},"/api/v1/user/settings":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).GetSettings`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"GET_/api/v1/user/settings","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get settings","tags":["api/v1/user"]}},"/api/v1/user/settings/auto-update":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateAutoUpdate`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/settings/auto-update","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateAutoUpdateRequest"}}},"description":"Request body for controller.UpdateAutoUpdateRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update auto update","tags":["api/v1/user"]}},"/api/v1/user/settings/font":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateFont`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/settings/font","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateFontRequest"}}},"description":"Request body for controller.UpdateFontRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update font","tags":["api/v1/user"]}},"/api/v1/user/settings/language":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateLanguage`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/settings/language","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateLanguageRequest"}}},"description":"Request body for controller.UpdateLanguageRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update language","tags":["api/v1/user"]}},"/api/v1/user/settings/theme":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateTheme`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/settings/theme","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateThemeRequest"}}},"description":"Request body for controller.UpdateThemeRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update theme","tags":["api/v1/user"]}},"/api/v1/webhook":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).HandleGithubWebhook`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"POST_/api/v1/webhook","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"handle github webhook","tags":["api/v1/webhook"]}},"/ws":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal.(*Router).WebSocketServer.func1`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"GET_/ws","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/unknown-interface"}},"application/xml":{"schema":{"$ref":"#/components/schemas/unknown-interface"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"func1"}}},"servers":[{"description":"local server","url":"http://:8080"}],"tags":[{"name":"api/v1/audit"},{"name":"api/v1/auth"},{"name":"api/v1/container"},{"name":"api/v1/deploy"},{"name":"api/v1/domain"},{"name":"api/v1/domains"},{"name":"api/v1/extensions"},{"name":"api/v1/feature-flags"},{"name":"api/v1/file-manager"},{"name":"api/v1/github-connector"},{"name":"api/v1/health"},{"name":"api/v1/notification"},{"name":"api/v1/organizations"},{"name":"api/v1/update"},{"name":"api/v1/user"},{"name":"api/v1/webhook"},{"name":"application"},{"name":"preferences"},{"name":"smtp"},{"name":"versions"},{"name":"webhook"}]} \ No newline at end of file +{"components":{"schemas":{"":{"description":" schema","properties":{"status":{"type":"string"}},"type":"object"},"ContainerLogsRequest":{"description":"ContainerLogsRequest schema","properties":{"follow":{"type":"boolean"},"id":{"type":"string"},"since":{"type":"string"},"stderr":{"type":"boolean"},"stdout":{"type":"boolean"},"tail":{"type":"integer"},"until":{"type":"string"}},"type":"object"},"CopyDirectory":{"description":"CopyDirectory schema","properties":{"from_path":{"type":"string"},"to_path":{"type":"string"}},"type":"object"},"CreateDeploymentRequest":{"description":"CreateDeploymentRequest schema","properties":{"base_path":{"nullable":true,"type":"string"},"branch":{"type":"string"},"build_pack":{"type":"string"},"build_variables":{"additionalProperties":{"type":"string"},"type":"object"},"dockerfile_path":{"nullable":true,"type":"string"},"domain":{"type":"string"},"environment":{"type":"string"},"environment_variables":{"additionalProperties":{"type":"string"},"type":"object"},"name":{"type":"string"},"port":{"type":"integer"},"post_run_command":{"type":"string"},"pre_run_command":{"type":"string"},"repository":{"type":"string"}},"type":"object"},"CreateDirectoryRequest":{"description":"CreateDirectoryRequest schema","properties":{"path":{"type":"string"}},"type":"object"},"CreateDomainRequest":{"description":"CreateDomainRequest schema","properties":{"name":{"type":"string"},"organization_id":{}},"type":"object"},"CreateGithubConnectorRequest":{"description":"CreateGithubConnectorRequest schema","properties":{"app_id":{"type":"string"},"client_id":{"type":"string"},"client_secret":{"type":"string"},"pem":{"type":"string"},"slug":{"type":"string"},"webhook_secret":{"type":"string"}},"type":"object"},"CreateOrganizationRequest":{"description":"CreateOrganizationRequest schema","properties":{"description":{"type":"string"},"name":{"type":"string"}},"type":"object"},"CreateSMTPConfigRequest":{"description":"CreateSMTPConfigRequest schema","properties":{"from_email":{"type":"string"},"from_name":{"type":"string"},"host":{"type":"string"},"organization_id":{},"password":{"type":"string"},"port":{"type":"integer"},"username":{"type":"string"}},"type":"object"},"CreateServerRequest":{"description":"CreateServerRequest schema","properties":{"description":{"type":"string"},"host":{"type":"string"},"name":{"type":"string"},"organization_id":{},"port":{"type":"integer"},"ssh_password":{"nullable":true,"type":"string"},"ssh_private_key_path":{"nullable":true,"type":"string"},"status":{"nullable":true,"type":"string"},"username":{"type":"string"}},"type":"object"},"CreateWebhookConfigRequest":{"description":"CreateWebhookConfigRequest schema","properties":{"type":{"type":"string"},"webhook_url":{"type":"string"}},"required":["type"],"type":"object"},"DeleteDeploymentRequest":{"description":"DeleteDeploymentRequest schema","properties":{"id":{}},"type":"object"},"DeleteDirectoryRequest":{"description":"DeleteDirectoryRequest schema","properties":{"path":{"type":"string"}},"type":"object"},"DeleteDomainRequest":{"description":"DeleteDomainRequest schema","properties":{"id":{"type":"string"}},"type":"object"},"DeleteOrganizationRequest":{"description":"DeleteOrganizationRequest schema","properties":{"id":{"type":"string"}},"type":"object"},"DeleteSMTPConfigRequest":{"description":"DeleteSMTPConfigRequest schema","properties":{"id":{}},"type":"object"},"DeleteServerRequest":{"description":"DeleteServerRequest schema","properties":{"id":{"type":"string"}},"type":"object"},"DeleteWebhookConfigRequest":{"description":"DeleteWebhookConfigRequest schema","properties":{"type":{"type":"string"}},"required":["type"],"type":"object"},"Extension":{"nullable":true,"properties":{"author":{"type":"string"},"category":{"type":"string"},"content_hash":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deleted_at":{"format":"date-time","nullable":true,"type":"string"},"description":{"type":"string"},"extension_id":{"type":"string"},"extension_type":{"type":"string"},"icon":{"type":"string"},"id":{},"is_verified":{"type":"boolean"},"name":{"type":"string"},"parent_extension_id":{"nullable":true},"parsed_content":{"type":"string"},"updated_at":{"format":"date-time","type":"string"},"validation_errors":{"type":"string"},"validation_status":{"type":"string"},"variables":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"default_value":{},"description":{"type":"string"},"extension":{"$ref":"#/components/schemas/Extension"},"extension_id":{},"id":{},"is_required":{"type":"boolean"},"validation_pattern":{"type":"string"},"variable_name":{"type":"string"},"variable_type":{"type":"string"}},"type":"object"},"type":"array"},"version":{"type":"string"},"yaml_content":{"type":"string"}},"type":"object"},"ExtensionCategory":{"description":"ExtensionCategory schema","type":"string"},"ExtensionExecution":{"description":"ExtensionExecution schema","properties":{"completed_at":{"format":"date-time","nullable":true,"type":"string"},"created_at":{"format":"date-time","type":"string"},"error_message":{"type":"string"},"execution_log":{"type":"string"},"exit_code":{"type":"integer"},"extension":{"nullable":true,"properties":{"author":{"type":"string"},"category":{"type":"string"},"content_hash":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deleted_at":{"format":"date-time","nullable":true,"type":"string"},"description":{"type":"string"},"extension_id":{"type":"string"},"extension_type":{"type":"string"},"icon":{"type":"string"},"id":{},"is_verified":{"type":"boolean"},"name":{"type":"string"},"parent_extension_id":{"nullable":true},"parsed_content":{"type":"string"},"updated_at":{"format":"date-time","type":"string"},"validation_errors":{"type":"string"},"validation_status":{"type":"string"},"variables":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"default_value":{},"description":{"type":"string"},"extension":{"$ref":"#/components/schemas/Extension"},"extension_id":{},"id":{},"is_required":{"type":"boolean"},"validation_pattern":{"type":"string"},"variable_name":{"type":"string"},"variable_type":{"type":"string"}},"type":"object"},"type":"array"},"version":{"type":"string"},"yaml_content":{"type":"string"}},"type":"object"},"extension_id":{},"id":{},"log_seq":{"format":"int64","type":"integer"},"server_hostname":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"steps":{"items":{"properties":{"completed_at":{"format":"date-time","nullable":true,"type":"string"},"created_at":{"format":"date-time","type":"string"},"execution":{"$ref":"#/components/schemas/ExtensionExecution"},"execution_id":{},"exit_code":{"type":"integer"},"id":{},"output":{"type":"string"},"phase":{"type":"string"},"started_at":{"format":"date-time","type":"string"},"status":{"type":"string"},"step_name":{"type":"string"},"step_order":{"type":"integer"}},"type":"object"},"nullable":true,"type":"array"},"variable_values":{"type":"string"}},"type":"object"},"ExtensionListResponse":{"description":"ExtensionListResponse schema","properties":{"extensions":{"items":{"properties":{"author":{"type":"string"},"category":{"type":"string"},"content_hash":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"deleted_at":{"format":"date-time","nullable":true,"type":"string"},"description":{"type":"string"},"extension_id":{"type":"string"},"extension_type":{"type":"string"},"icon":{"type":"string"},"id":{},"is_verified":{"type":"boolean"},"name":{"type":"string"},"parent_extension_id":{"nullable":true},"parsed_content":{"type":"string"},"updated_at":{"format":"date-time","type":"string"},"validation_errors":{"type":"string"},"validation_status":{"type":"string"},"variables":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"default_value":{},"description":{"type":"string"},"extension":{"$ref":"#/components/schemas/Extension"},"extension_id":{},"id":{},"is_required":{"type":"boolean"},"validation_pattern":{"type":"string"},"variable_name":{"type":"string"},"variable_type":{"type":"string"}},"type":"object"},"type":"array"},"version":{"type":"string"},"yaml_content":{"type":"string"}},"type":"object"},"type":"array"},"page":{"type":"integer"},"page_size":{"type":"integer"},"total":{"type":"integer"},"total_pages":{"type":"integer"}},"type":"object"},"ForkExtensionRequest":{"description":"ForkExtensionRequest schema","properties":{"yaml_content":{"nullable":true,"type":"string"}},"type":"object"},"GetApplicationDeploymentsRequest":{"description":"GetApplicationDeploymentsRequest schema","properties":{"id":{"type":"string"},"limit":{"type":"string"},"page":{"type":"string"}},"type":"object"},"GetApplicationsRequest":{"description":"GetApplicationsRequest schema","properties":{"page":{"type":"string"},"page_size":{"type":"string"},"repository":{"type":"string"}},"type":"object"},"GetGithubRepositoryBranchesRequest":{"description":"GetGithubRepositoryBranchesRequest schema","properties":{"repository_name":{"type":"string"}},"required":["repository_name"],"type":"object"},"GetOrganizationUsersRequest":{"description":"GetOrganizationUsersRequest schema","properties":{"id":{"type":"string"}},"type":"object"},"HTTPError":{"description":"HTTPError schema","properties":{"detail":{"description":"Human readable error message","nullable":true,"type":"string"},"errors":{"items":{"properties":{"more":{"additionalProperties":{},"type":"object"},"name":{"type":"string"},"reason":{"type":"string"}},"type":"object"},"nullable":true,"type":"array"},"instance":{"nullable":true,"type":"string"},"status":{"description":"HTTP status code","example":403,"nullable":true,"type":"integer"},"title":{"description":"Short title of the error","nullable":true,"type":"string"},"type":{"description":"URL of the error type. Can be used to lookup the error in a documentation","nullable":true,"type":"string"}},"type":"object"},"InviteResendRequest":{"description":"InviteResendRequest schema","properties":{"email":{"type":"string"},"organization_id":{"type":"string"},"role":{"type":"string"}},"type":"object"},"InviteSendRequest":{"description":"InviteSendRequest schema","properties":{"email":{"type":"string"},"organization_id":{"type":"string"},"role":{"type":"string"}},"type":"object"},"ListFilesRequest":{"description":"ListFilesRequest schema","properties":{"path":{"type":"string"}},"type":"object"},"ListImagesRequest":{"description":"ListImagesRequest schema","properties":{"all":{"nullable":true,"type":"boolean"},"container_id":{"nullable":true,"type":"string"},"image_prefix":{"nullable":true,"type":"string"}},"type":"object"},"ListLogsResponse":{"description":"ListLogsResponse schema","properties":{"execution_status":{"nullable":true,"type":"string"},"logs":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"data":{},"execution_id":{},"id":{},"level":{"type":"string"},"message":{"type":"string"},"sequence":{"format":"int64","type":"integer"},"step_id":{"nullable":true}},"type":"object"},"type":"array"},"next_after":{"format":"int64","type":"integer"}},"type":"object"},"LogoutRequest":{"description":"LogoutRequest schema","properties":{"refresh_token":{"type":"string"}},"type":"object"},"MoveDirectory":{"description":"MoveDirectory schema","properties":{"from_path":{"type":"string"},"to_path":{"type":"string"}},"type":"object"},"PruneBuildCacheRequest":{"description":"PruneBuildCacheRequest schema","properties":{"all":{"nullable":true,"type":"boolean"},"filters":{"nullable":true,"type":"string"}},"type":"object"},"PruneImagesRequest":{"description":"PruneImagesRequest schema","properties":{"dangling":{"nullable":true,"type":"boolean"},"label":{"nullable":true,"type":"string"},"until":{"nullable":true,"type":"string"}},"type":"object"},"ReDeployApplicationRequest":{"description":"ReDeployApplicationRequest schema","properties":{"force":{"type":"boolean"},"force_without_cache":{"type":"boolean"},"id":{}},"type":"object"},"RegisterRequest":{"description":"RegisterRequest schema","properties":{"email":{"type":"string"},"organization":{"type":"string"},"password":{"type":"string"},"type":{"type":"string"},"username":{"type":"string"}},"type":"object"},"RemoveUserFromOrganizationRequest":{"description":"RemoveUserFromOrganizationRequest schema","properties":{"organization_id":{"type":"string"},"user_id":{"type":"string"}},"type":"object"},"Response":{"description":"Response schema","properties":{"data":{"nullable":true},"error":{"nullable":true,"type":"string"},"message":{"nullable":true,"type":"string"},"status":{"type":"string"}},"type":"object"},"RestartDeploymentRequest":{"description":"RestartDeploymentRequest schema","properties":{"id":{}},"type":"object"},"RollbackDeploymentRequest":{"description":"RollbackDeploymentRequest schema","properties":{"id":{}},"type":"object"},"RunExtensionRequest":{"description":"RunExtensionRequest schema","properties":{"variables":{"additionalProperties":{},"type":"object"}},"type":"object"},"TwoFactorLoginRequest":{"description":"TwoFactorLoginRequest schema","properties":{"code":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"}},"type":"object"},"TwoFactorVerifyRequest":{"description":"TwoFactorVerifyRequest schema","properties":{"code":{"type":"string"}},"type":"object"},"UpdateAutoUpdateRequest":{"description":"UpdateAutoUpdateRequest schema","properties":{"auto_update":{"type":"boolean"}},"type":"object"},"UpdateAvatarRequest":{"description":"UpdateAvatarRequest schema","properties":{"avatarData":{"type":"string"}},"type":"object"},"UpdateCheckResponse":{"description":"UpdateCheckResponse schema","properties":{"current_version":{"type":"string"},"environment":{"type":"string"},"last_checked":{"format":"date-time","type":"string"},"latest_version":{"type":"string"},"update_available":{"type":"boolean"}},"type":"object"},"UpdateDeploymentRequest":{"description":"UpdateDeploymentRequest schema","properties":{"base_path":{"nullable":true,"type":"string"},"build_variables":{"additionalProperties":{"type":"string"},"nullable":true,"type":"object"},"dockerfile_path":{"nullable":true,"type":"string"},"environment_variables":{"additionalProperties":{"type":"string"},"nullable":true,"type":"object"},"force":{"nullable":true,"type":"boolean"},"id":{"nullable":true},"name":{"nullable":true,"type":"string"},"port":{"nullable":true,"type":"integer"},"post_run_command":{"nullable":true,"type":"string"},"pre_run_command":{"nullable":true,"type":"string"}},"type":"object"},"UpdateDomainRequest":{"description":"UpdateDomainRequest schema","properties":{"id":{"type":"string"},"name":{"type":"string"}},"type":"object"},"UpdateFeatureFlagRequest":{"description":"UpdateFeatureFlagRequest schema","properties":{"feature_name":{"type":"string"},"is_enabled":{"type":"boolean"}},"required":["feature_name"],"type":"object"},"UpdateFontRequest":{"description":"UpdateFontRequest schema","properties":{"font_family":{"type":"string"},"font_size":{"type":"integer"}},"type":"object"},"UpdateGithubConnectorRequest":{"description":"UpdateGithubConnectorRequest schema","properties":{"installation_id":{"type":"string"}},"type":"object"},"UpdateLanguageRequest":{"description":"UpdateLanguageRequest schema","properties":{"language":{"type":"string"}},"type":"object"},"UpdateOrganizationRequest":{"description":"UpdateOrganizationRequest schema","properties":{"description":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"}},"type":"object"},"UpdatePreferenceRequest":{"description":"UpdatePreferenceRequest schema","properties":{"category":{"type":"string"},"enabled":{"type":"boolean"},"type":{"type":"string"}},"required":["category","type"],"type":"object"},"UpdateRequest":{"description":"UpdateRequest schema","properties":{"force":{"type":"boolean"}},"type":"object"},"UpdateResponse":{"description":"UpdateResponse schema","properties":{"message":{"type":"string"},"success":{"type":"boolean"}},"type":"object"},"UpdateSMTPConfigRequest":{"description":"UpdateSMTPConfigRequest schema","properties":{"from_email":{"nullable":true,"type":"string"},"from_name":{"nullable":true,"type":"string"},"host":{"nullable":true,"type":"string"},"id":{},"organization_id":{},"password":{"nullable":true,"type":"string"},"port":{"nullable":true,"type":"integer"},"username":{"nullable":true,"type":"string"}},"type":"object"},"UpdateServerRequest":{"description":"UpdateServerRequest schema","properties":{"description":{"type":"string"},"host":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"port":{"type":"integer"},"ssh_password":{"nullable":true,"type":"string"},"ssh_private_key_path":{"nullable":true,"type":"string"},"status":{"nullable":true,"type":"string"},"username":{"type":"string"}},"type":"object"},"UpdateServerStatusRequest":{"description":"UpdateServerStatusRequest schema","properties":{"id":{"type":"string"},"status":{"type":"string"}},"type":"object"},"UpdateThemeRequest":{"description":"UpdateThemeRequest schema","properties":{"theme":{"type":"string"}},"type":"object"},"UpdateUserNameRequest":{"description":"UpdateUserNameRequest schema","properties":{"name":{"type":"string"}},"type":"object"},"UpdateUserRoleRequest":{"description":"UpdateUserRoleRequest schema","properties":{"organization_id":{"type":"string"},"role":{"type":"string"},"user_id":{"type":"string"}},"type":"object"},"UpdateWebhookConfigRequest":{"description":"UpdateWebhookConfigRequest schema","properties":{"is_active":{"nullable":true,"type":"boolean"},"type":{"type":"string"},"webhook_url":{"nullable":true,"type":"string"}},"required":["type"],"type":"object"},"unknown-interface":{"description":"unknown-interface schema"}},"securitySchemes":{"bearerAuth":{"bearerFormat":"JWT","description":"Enter your JWT token in the format: Bearer \u003ctoken\u003e","scheme":"bearer","type":"http"}}},"info":{"description":"\nThis is the autogenerated OpenAPI documentation for your [Fuego](https://github.com/go-fuego/fuego) API.\n\nBelow is a Fuego Cheatsheet to help you get started. Don't hesitate to check the [Fuego documentation](https://go-fuego.dev) for more details.\n\nHappy coding! 🔥\n\n## Usage\n\n### Route registration\n\n```go\nfunc main() {\n\t// Create a new server\n\ts := fuego.NewServer()\n\n\t// Register some routes\n\tfuego.Post(s, \"/hello\", myController)\n\tfuego.Get(s, \"/myPath\", otherController)\n\tfuego.Put(s, \"/hello\", thirdController)\n\n\tadminRoutes := fuego.Group(s, \"/admin\")\n\tfuego.Use(adminRoutes, myMiddleware) // This middleware (for authentication, etc...) will be available for routes starting by /admin/*, \n\tfuego.Get(adminRoutes, \"/hello\", groupController) // This route will be available at /admin/hello\n\n\t// Start the server\n\ts.Start()\n}\n```\n\n### Basic controller\n\n```go\ntype MyBody struct {\n\tName string `json:\"name\" validate:\"required,max=30\"`\n}\n\ntype MyResponse struct {\n\tAnswer string `json:\"answer\"`\n}\n\nfunc hello(ctx fuego.ContextWithBody[MyBody]) (*MyResponse, error) {\n\tbody, err := ctx.Body()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn \u0026MyResponse{Answer: \"Hello \" + body.Name}, nil\n}\n```\n\n### Add openAPI information to the route\n\n```go\nimport (\n\t\"github.com/go-fuego/fuego\"\n\t\"github.com/go-fuego/fuego/option\"\n\t\"github.com/go-fuego/fuego/param\"\n)\n\nfunc main() {\n\ts := fuego.NewServer()\n\n\t// Custom OpenAPI options\n\tfuego.Post(s, \"/\", myController\n\t\toption.Description(\"This route does something...\"),\n\t\toption.Summary(\"This is my summary\"),\n\t\toption.Tags(\"MyTag\"), // A tag is set by default according to the return type (can be deactivated)\n\t\toption.Deprecated(), // Marks the route as deprecated in the OpenAPI spec\n\n\t\toption.Query(\"name\", \"Declares a query parameter with default value\", param.Default(\"Carmack\")),\n\t\toption.Header(\"Authorization\", \"Bearer token\", param.Required()),\n\t\toptionPagination,\n\t\toptionCustomBehavior,\n\t)\n\n\ts.Run()\n}\n\nvar optionPagination = option.Group(\n\toption.QueryInt(\"page\", \"Page number\", param.Default(1), param.Example(\"1st page\", 1), param.Example(\"42nd page\", 42)),\n\toption.QueryInt(\"perPage\", \"Number of items per page\"),\n)\n\nvar optionCustomBehavior = func(r *fuego.BaseRoute) {\n\tr.XXX = \"YYY\"\n}\n```\n\nThen, in the controller\n\n```go\ntype MyResponse struct {\n\tAnswer string `json:\"answer\"`\n}\n\nfunc getAllPets(ctx fuego.ContextNoBody) (*MyResponse, error) {\n\tname := ctx.QueryParam(\"name\")\n\tperPage, _ := ctx.QueryParamIntErr(\"per_page\")\n\n\treturn \u0026MyResponse{Answer: \"Hello \" + name}, nil\n}\n```\n","title":"OpenAPI","version":"0.0.1"},"openapi":"3.1.0","paths":{"/api/v1/audit/logs":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/audit/controller.(*AuditController).GetRecentAuditLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func23`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func24`\n\n---\n\n","operationId":"GET_/api/v1/audit/logs","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get recent audit logs","tags":["api/v1/audit"]}},"/api/v1/auth/2fa-login":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).TwoFactorLogin`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/2fa-login","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/TwoFactorLoginRequest"}}},"description":"Request body for types.TwoFactorLoginRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"two factor login","tags":["api/v1/auth"]}},"/api/v1/auth/create-user":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).CreateUser`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/create-user","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"description":"Request body for types.RegisterRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create user","tags":["api/v1/auth"]}},"/api/v1/auth/disable-2fa":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).DisableTwoFactor`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/disable-2fa","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"disable two factor","tags":["api/v1/auth"]}},"/api/v1/auth/is-admin-registered":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).IsAdminRegistered`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"GET_/api/v1/auth/is-admin-registered","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"is admin registered","tags":["api/v1/auth"]}},"/api/v1/auth/logout":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).Logout`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/logout","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/LogoutRequest"}}},"description":"Request body for types.LogoutRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"logout","tags":["api/v1/auth"]}},"/api/v1/auth/send-verification-email":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).SendVerificationEmail`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/send-verification-email","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"send verification email","tags":["api/v1/auth"]}},"/api/v1/auth/setup-2fa":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).SetupTwoFactor`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/setup-2fa","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"setup two factor","tags":["api/v1/auth"]}},"/api/v1/auth/verify-2fa":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).VerifyTwoFactor`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/auth/verify-2fa","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/TwoFactorVerifyRequest"}}},"description":"Request body for types.TwoFactorVerifyRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"verify two factor","tags":["api/v1/auth"]}},"/api/v1/auth/verify-email":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/auth/controller.(*AuthController).VerifyEmail`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"GET_/api/v1/auth/verify-email","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"verify email","tags":["api/v1/auth"]}},"/api/v1/container":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).ListContainers`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"GET_/api/v1/container","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list containers","tags":["api/v1/container"]}},"/api/v1/container/images":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).ListImages`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/images","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ListImagesRequest"}}},"description":"Request body for controller.ListImagesRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list images","tags":["api/v1/container"]}},"/api/v1/container/prune/build-cache":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).PruneBuildCache`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/prune/build-cache","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PruneBuildCacheRequest"}}},"description":"Request body for controller.PruneBuildCacheRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"prune build cache","tags":["api/v1/container"]}},"/api/v1/container/prune/images":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).PruneImages`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/prune/images","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PruneImagesRequest"}}},"description":"Request body for controller.PruneImagesRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"prune images","tags":["api/v1/container"]}},"/api/v1/container/{container_id}":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).RemoveContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"DELETE_/api/v1/container/:container_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"remove container","tags":["api/v1/container"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).GetContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"GET_/api/v1/container/:container_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get container","tags":["api/v1/container"]}},"/api/v1/container/{container_id}/logs":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).GetContainerLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/:container_id/logs","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ContainerLogsRequest"}}},"description":"Request body for types.ContainerLogsRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get container logs","tags":["api/v1/container"]}},"/api/v1/container/{container_id}/restart":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).RestartContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/:container_id/restart","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"restart container","tags":["api/v1/container"]}},"/api/v1/container/{container_id}/start":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).StartContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/:container_id/start","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"start container","tags":["api/v1/container"]}},"/api/v1/container/{container_id}/stop":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/container/controller.(*ContainerController).StopContainer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func26`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func27`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func28`\n\n---\n\n","operationId":"POST_/api/v1/container/:container_id/stop","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"container_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"stop container","tags":["api/v1/container"]}},"/api/v1/deploy/application":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).DeleteApplication`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"DELETE_/api/v1/deploy/application","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteDeploymentRequest"}}},"description":"Request body for types.DeleteDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete application","tags":["api/v1/deploy","application"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetApplicationById`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get application by id","tags":["api/v1/deploy","application"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).HandleDeploy`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"POST_/api/v1/deploy/application","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateDeploymentRequest"}}},"description":"Request body for types.CreateDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"handle deploy","tags":["api/v1/deploy","application"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).UpdateApplication`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"PUT_/api/v1/deploy/application","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateDeploymentRequest"}}},"description":"Request body for types.UpdateDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update application","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/deployments":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetApplicationDeployments`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application/deployments","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetApplicationDeploymentsRequest"}}},"description":"Request body for controller.GetApplicationDeploymentsRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get application deployments","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/deployments/{deployment_id}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetDeploymentById`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application/deployments/:deployment_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"deployment_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get deployment by id","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/deployments/{deployment_id}/logs":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetDeploymentLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application/deployments/:deployment_id/logs","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"deployment_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get deployment logs","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/logs/{application_id}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/application/logs/:application_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"application_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get logs","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/redeploy":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).ReDeployApplication`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"POST_/api/v1/deploy/application/redeploy","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReDeployApplicationRequest"}}},"description":"Request body for types.ReDeployApplicationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"re deploy application","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/restart":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).HandleRestart`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"POST_/api/v1/deploy/application/restart","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RestartDeploymentRequest"}}},"description":"Request body for types.RestartDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"handle restart","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/application/rollback":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).HandleRollback`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"POST_/api/v1/deploy/application/rollback","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RollbackDeploymentRequest"}}},"description":"Request body for types.RollbackDeploymentRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"handle rollback","tags":["api/v1/deploy","application"]}},"/api/v1/deploy/applications":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).GetApplications`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func20`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func21`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func22`\n\n---\n\n","operationId":"GET_/api/v1/deploy/applications","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetApplicationsRequest"}}},"description":"Request body for controller.GetApplicationsRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get applications","tags":["api/v1/deploy"]}},"/api/v1/domain":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).DeleteDomain`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func3`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func5`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func7`\n\n---\n\n","operationId":"DELETE_/api/v1/domain","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteDomainRequest"}}},"description":"Request body for types.DeleteDomainRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete domain","tags":["api/v1/domain"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).CreateDomain`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func3`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func5`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func7`\n\n---\n\n","operationId":"POST_/api/v1/domain","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateDomainRequest"}}},"description":"Request body for types.CreateDomainRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create domain","tags":["api/v1/domain"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).UpdateDomain`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func3`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func5`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func7`\n\n---\n\n","operationId":"PUT_/api/v1/domain","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateDomainRequest"}}},"description":"Request body for types.UpdateDomainRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update domain","tags":["api/v1/domain"]}},"/api/v1/domain/generate":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).GenerateRandomSubDomain`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func3`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func5`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func7`\n\n---\n\n","operationId":"GET_/api/v1/domain/generate","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"generate random sub domain","tags":["api/v1/domain"]}},"/api/v1/domains":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/domain/controller.(*DomainsController).GetDomains`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func4`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func6`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func8`\n\n---\n\n","operationId":"GET_/api/v1/domains","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get domains","tags":["api/v1/domains"]}},"/api/v1/extensions":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetExtensions`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionListResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ExtensionListResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get extensions","tags":["api/v1/extensions"]}},"/api/v1/extensions/by-extension-id/{extension_id}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetExtensionByExtensionID`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/by-extension-id/:extension_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"extension_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Extension"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get extension by extension i d","tags":["api/v1/extensions"]}},"/api/v1/extensions/by-extension-id/{extension_id}/executions":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).ListExecutionsByExtensionID`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/by-extension-id/:extension_id/executions","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"extension_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ExtensionExecution"},"type":"array"}},"application/xml":{"schema":{"items":{"$ref":"#/components/schemas/ExtensionExecution"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list executions by extension i d","tags":["api/v1/extensions"]}},"/api/v1/extensions/categories":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetCategories`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/categories","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ExtensionCategory"},"type":"array"}},"application/xml":{"schema":{"items":{"$ref":"#/components/schemas/ExtensionCategory"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get categories","tags":["api/v1/extensions"]}},"/api/v1/extensions/execution/{execution_id}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetExecution`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/execution/:execution_id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionExecution"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ExtensionExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get execution","tags":["api/v1/extensions"]}},"/api/v1/extensions/execution/{execution_id}/cancel":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).CancelExecution`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"POST_/api/v1/extensions/execution/:execution_id/cancel","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"cancel execution","tags":["api/v1/extensions"]}},"/api/v1/extensions/execution/{execution_id}/logs":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).ListExecutionLogs`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/execution/:execution_id/logs","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"execution_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListLogsResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ListLogsResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list execution logs","tags":["api/v1/extensions"]}},"/api/v1/extensions/{extension_id}/fork":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).ForkExtension`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"POST_/api/v1/extensions/:extension_id/fork","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"extension_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ForkExtensionRequest"}}},"description":"Request body for controller.ForkExtensionRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Extension"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"fork extension","tags":["api/v1/extensions"]}},"/api/v1/extensions/{extension_id}/run":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).RunExtension`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"POST_/api/v1/extensions/:extension_id/run","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"extension_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RunExtensionRequest"}}},"description":"Request body for controller.RunExtensionRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionExecution"}},"application/xml":{"schema":{"$ref":"#/components/schemas/ExtensionExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"run extension","tags":["api/v1/extensions"]}},"/api/v1/extensions/{id}":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).DeleteFork`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"DELETE_/api/v1/extensions/:id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/"}},"application/xml":{"schema":{"$ref":"#/components/schemas/"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete fork","tags":["api/v1/extensions"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/extension/controller.(*ExtensionsController).GetExtension`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func29`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func30`\n\n---\n\n","operationId":"GET_/api/v1/extensions/:id","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Extension"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get extension","tags":["api/v1/extensions"]}},"/api/v1/feature-flags":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/feature-flags/controller.(*FeatureFlagController).GetFeatureFlags`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"GET_/api/v1/feature-flags","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get feature flags","tags":["api/v1/feature-flags"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/feature-flags/controller.(*FeatureFlagController).UpdateFeatureFlag`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func25`\n\n---\n\n","operationId":"PUT_/api/v1/feature-flags","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateFeatureFlagRequest"}}},"description":"Request body for types.UpdateFeatureFlagRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update feature flag","tags":["api/v1/feature-flags"]}},"/api/v1/feature-flags/check":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/feature-flags/controller.(*FeatureFlagController).IsFeatureEnabled`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"GET_/api/v1/feature-flags/check","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"is feature enabled","tags":["api/v1/feature-flags"]}},"/api/v1/file-manager":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).ListFiles`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"GET_/api/v1/file-manager","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ListFilesRequest"}}},"description":"Request body for controller.ListFilesRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"list files","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/copy-directory":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).CopyDirectory`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"POST_/api/v1/file-manager/copy-directory","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CopyDirectory"}}},"description":"Request body for controller.CopyDirectory","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"copy directory","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/create-directory":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).CreateDirectory`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"POST_/api/v1/file-manager/create-directory","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateDirectoryRequest"}}},"description":"Request body for controller.CreateDirectoryRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create directory","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/delete-directory":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).DeleteDirectory`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"DELETE_/api/v1/file-manager/delete-directory","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteDirectoryRequest"}}},"description":"Request body for controller.DeleteDirectoryRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete directory","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/move-directory":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).MoveDirectory`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"POST_/api/v1/file-manager/move-directory","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MoveDirectory"}}},"description":"Request body for controller.MoveDirectory","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"move directory","tags":["api/v1/file-manager"]}},"/api/v1/file-manager/upload":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/file-manager/controller.(*FileManagerController).UploadFile`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func17`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func18`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func19`\n\n---\n\n","operationId":"POST_/api/v1/file-manager/upload","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"upload file","tags":["api/v1/file-manager"]}},"/api/v1/github-connector":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).CreateGithubConnector`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"POST_/api/v1/github-connector","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateGithubConnectorRequest"}}},"description":"Request body for types.CreateGithubConnectorRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create github connector","tags":["api/v1/github-connector"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).UpdateGithubConnectorRequest`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"PUT_/api/v1/github-connector","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateGithubConnectorRequest"}}},"description":"Request body for types.UpdateGithubConnectorRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update github connector request","tags":["api/v1/github-connector"]}},"/api/v1/github-connector/all":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).GetGithubConnectors`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"GET_/api/v1/github-connector/all","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get github connectors","tags":["api/v1/github-connector"]}},"/api/v1/github-connector/repositories":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).GetGithubRepositories`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"GET_/api/v1/github-connector/repositories","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get github repositories","tags":["api/v1/github-connector"]}},"/api/v1/github-connector/repository/branches":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/github-connector/controller.(*GithubConnectorController).GetGithubRepositoryBranches`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func9`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func10`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func11`\n\n---\n\n","operationId":"POST_/api/v1/github-connector/repository/branches","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetGithubRepositoryBranchesRequest"}}},"description":"Request body for controller.GetGithubRepositoryBranchesRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get github repository branches","tags":["api/v1/github-connector"]}},"/api/v1/health":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/health.HealthCheck`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"GET_/api/v1/health","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"health check","tags":["api/v1/health"]}},"/api/v1/health/versions":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal.(*Router).BasicRoutes.func1`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"GET_/api/v1/health/versions","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/unknown-interface"}},"application/xml":{"schema":{"$ref":"#/components/schemas/unknown-interface"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"func1","tags":["api/v1/health","versions"]}},"/api/v1/notification/preferences":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).GetPreferences`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"GET_/api/v1/notification/preferences","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get preferences","tags":["api/v1/notification","preferences"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).UpdatePreference`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"POST_/api/v1/notification/preferences","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdatePreferenceRequest"}}},"description":"Request body for notification.UpdatePreferenceRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update preference","tags":["api/v1/notification","preferences"]}},"/api/v1/notification/smtp":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).DeleteSmtp`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"DELETE_/api/v1/notification/smtp","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteSMTPConfigRequest"}}},"description":"Request body for notification.DeleteSMTPConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete smtp","tags":["api/v1/notification","smtp"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).GetSmtp`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"GET_/api/v1/notification/smtp","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get smtp","tags":["api/v1/notification","smtp"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).AddSmtp`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"POST_/api/v1/notification/smtp","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateSMTPConfigRequest"}}},"description":"Request body for notification.CreateSMTPConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"add smtp","tags":["api/v1/notification","smtp"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).UpdateSmtp`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"PUT_/api/v1/notification/smtp","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateSMTPConfigRequest"}}},"description":"Request body for notification.UpdateSMTPConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update smtp","tags":["api/v1/notification","smtp"]}},"/api/v1/notification/webhook":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).DeleteWebhookConfig`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"DELETE_/api/v1/notification/webhook","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteWebhookConfigRequest"}}},"description":"Request body for notification.DeleteWebhookConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete webhook config","tags":["api/v1/notification","webhook"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).CreateWebhookConfig`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"POST_/api/v1/notification/webhook","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateWebhookConfigRequest"}}},"description":"Request body for notification.CreateWebhookConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create webhook config","tags":["api/v1/notification","webhook"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).UpdateWebhookConfig`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"PUT_/api/v1/notification/webhook","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateWebhookConfigRequest"}}},"description":"Request body for notification.UpdateWebhookConfigRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update webhook config","tags":["api/v1/notification","webhook"]}},"/api/v1/notification/webhook/{type}":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/notification/controller.(*NotificationController).GetWebhookConfig`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func12`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func13`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func14`\n\n---\n\n","operationId":"GET_/api/v1/notification/webhook/:type","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}},{"in":"path","name":"type","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get webhook config","tags":["api/v1/notification","webhook"]}},"/api/v1/organizations":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).DeleteOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"DELETE_/api/v1/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteOrganizationRequest"}}},"description":"Request body for types.DeleteOrganizationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete organization","tags":["api/v1/organizations"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).GetOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"GET_/api/v1/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get organization","tags":["api/v1/organizations"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).CreateOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"}}},"description":"Request body for types.CreateOrganizationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create organization","tags":["api/v1/organizations"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).UpdateOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"PUT_/api/v1/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationRequest"}}},"description":"Request body for types.UpdateOrganizationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update organization","tags":["api/v1/organizations"]}},"/api/v1/organizations/all":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).GetOrganizations`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"GET_/api/v1/organizations/all","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get organizations","tags":["api/v1/organizations"]}},"/api/v1/organizations/invite/resend":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).ResendInvite`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations/invite/resend","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteResendRequest"}}},"description":"Request body for types.InviteResendRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"resend invite","tags":["api/v1/organizations"]}},"/api/v1/organizations/invite/send":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).SendInvite`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations/invite/send","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteSendRequest"}}},"description":"Request body for types.InviteSendRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"send invite","tags":["api/v1/organizations"]}},"/api/v1/organizations/remove-user":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).RemoveUserFromOrganization`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations/remove-user","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RemoveUserFromOrganizationRequest"}}},"description":"Request body for types.RemoveUserFromOrganizationRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"remove user from organization","tags":["api/v1/organizations"]}},"/api/v1/organizations/update-user-role":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).UpdateUserRole`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"POST_/api/v1/organizations/update-user-role","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateUserRoleRequest"}}},"description":"Request body for types.UpdateUserRoleRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update user role","tags":["api/v1/organizations"]}},"/api/v1/organizations/users":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/organization/controller.(*OrganizationsController).GetOrganizationUsers`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func15`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func16`\n\n---\n\n","operationId":"GET_/api/v1/organizations/users","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GetOrganizationUsersRequest"}}},"description":"Request body for controller.GetOrganizationUsersRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get organization users","tags":["api/v1/organizations"]}},"/api/v1/server":{"delete":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/servers/controller.(*ServersController).DeleteServer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func31`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func33`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func35`\n\n---\n\n","operationId":"DELETE_/api/v1/server","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DeleteServerRequest"}}},"description":"Request body for types.DeleteServerRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"delete server","tags":["api/v1/server"]},"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/servers/controller.(*ServersController).GetServer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func31`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func33`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func35`\n\n---\n\n","operationId":"GET_/api/v1/server","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get server","tags":["api/v1/server"]},"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/servers/controller.(*ServersController).CreateServer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func31`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func33`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func35`\n\n---\n\n","operationId":"POST_/api/v1/server","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CreateServerRequest"}}},"description":"Request body for types.CreateServerRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"create server","tags":["api/v1/server"]},"put":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/servers/controller.(*ServersController).UpdateServer`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func31`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func33`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func35`\n\n---\n\n","operationId":"PUT_/api/v1/server","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateServerRequest"}}},"description":"Request body for types.UpdateServerRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update server","tags":["api/v1/server"]}},"/api/v1/server/status":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/servers/controller.(*ServersController).UpdateServerStatus`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func31`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func33`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func35`\n\n---\n\n","operationId":"PATCH_/api/v1/server/status","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateServerStatusRequest"}}},"description":"Request body for types.UpdateServerStatusRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update server status","tags":["api/v1/server"]}},"/api/v1/servers":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/servers/controller.(*ServersController).GetServers`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func32`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func34`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func36`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func37`\n\n---\n\n","operationId":"GET_/api/v1/servers","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get servers","tags":["api/v1/servers"]}},"/api/v1/update":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/update/controller.(*UpdateController).PerformUpdate`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"POST_/api/v1/update","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateRequest"}}},"description":"Request body for types.UpdateRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/UpdateResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"perform update","tags":["api/v1/update"]}},"/api/v1/update/check":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/update/controller.(*UpdateController).CheckForUpdates`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n\n---\n\n","operationId":"GET_/api/v1/update/check","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCheckResponse"}},"application/xml":{"schema":{"$ref":"#/components/schemas/UpdateCheckResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"check for updates","tags":["api/v1/update"]}},"/api/v1/user":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).GetUserDetails`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"GET_/api/v1/user","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get user details","tags":["api/v1/user"]}},"/api/v1/user/avatar":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateAvatar`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/avatar","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateAvatarRequest"}}},"description":"Request body for types.UpdateAvatarRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update avatar","tags":["api/v1/user"]}},"/api/v1/user/name":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateUserName`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/name","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateUserNameRequest"}}},"description":"Request body for types.UpdateUserNameRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update user name","tags":["api/v1/user"]}},"/api/v1/user/organizations":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).GetUserOrganizations`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"GET_/api/v1/user/organizations","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get user organizations","tags":["api/v1/user"]}},"/api/v1/user/settings":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).GetSettings`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"GET_/api/v1/user/settings","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"get settings","tags":["api/v1/user"]}},"/api/v1/user/settings/auto-update":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateAutoUpdate`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/settings/auto-update","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateAutoUpdateRequest"}}},"description":"Request body for controller.UpdateAutoUpdateRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update auto update","tags":["api/v1/user"]}},"/api/v1/user/settings/font":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateFont`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/settings/font","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateFontRequest"}}},"description":"Request body for controller.UpdateFontRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update font","tags":["api/v1/user"]}},"/api/v1/user/settings/language":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateLanguage`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/settings/language","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateLanguageRequest"}}},"description":"Request body for controller.UpdateLanguageRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update language","tags":["api/v1/user"]}},"/api/v1/user/settings/theme":{"patch":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/user/controller.(*UserController).UpdateTheme`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func1`\n- `github.com/raghavyuva/nixopus-api/internal.(*Router).Routes.func2`\n\n---\n\n","operationId":"PATCH_/api/v1/user/settings/theme","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UpdateThemeRequest"}}},"description":"Request body for controller.UpdateThemeRequest","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"update theme","tags":["api/v1/user"]}},"/api/v1/webhook":{"post":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal/features/deploy/controller.(*DeployController).HandleGithubWebhook`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"POST_/api/v1/webhook","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Response"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"handle github webhook","tags":["api/v1/webhook"]}},"/ws":{"get":{"description":"#### Controller: \n\n`github.com/raghavyuva/nixopus-api/internal.(*Router).WebSocketServer.func1`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego.defaultLogger.middleware`\n\n---\n\n","operationId":"GET_/ws","parameters":[{"in":"header","name":"Accept","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/unknown-interface"}},"application/xml":{"schema":{"$ref":"#/components/schemas/unknown-interface"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Bad Request _(validation or deserialization error)_"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}},"application/xml":{"schema":{"$ref":"#/components/schemas/HTTPError"}}},"description":"Internal Server Error _(panics)_"},"default":{"description":""}},"summary":"func1"}}},"servers":[{"description":"local server","url":"http://:8080"}],"tags":[{"name":"api/v1/audit"},{"name":"api/v1/auth"},{"name":"api/v1/container"},{"name":"api/v1/deploy"},{"name":"api/v1/domain"},{"name":"api/v1/domains"},{"name":"api/v1/extensions"},{"name":"api/v1/feature-flags"},{"name":"api/v1/file-manager"},{"name":"api/v1/github-connector"},{"name":"api/v1/health"},{"name":"api/v1/notification"},{"name":"api/v1/organizations"},{"name":"api/v1/server"},{"name":"api/v1/servers"},{"name":"api/v1/update"},{"name":"api/v1/user"},{"name":"api/v1/webhook"},{"name":"application"},{"name":"preferences"},{"name":"smtp"},{"name":"versions"},{"name":"webhook"}]} \ No newline at end of file diff --git a/api/internal/features/deploy/docker/init.go b/api/internal/features/deploy/docker/init.go index c40c61899..8d40f25d3 100644 --- a/api/internal/features/deploy/docker/init.go +++ b/api/internal/features/deploy/docker/init.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "net" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" @@ -20,9 +21,17 @@ import ( ) type DockerService struct { - Cli *client.Client - Ctx context.Context - logger logger.Logger + Cli *client.Client + Ctx context.Context + logger logger.Logger + sshTunnel *SSHTunnel +} + +type SSHTunnel struct { + localSocket string + sshClient *ssh.SSH + listener net.Listener + cleanup func() error } type DockerRepository interface { @@ -79,27 +88,48 @@ type DockerClient struct { // NewDockerService creates a new instance of DockerService using the default docker client. func NewDockerService() *DockerService { - client := NewDockerClient() - service := &DockerService{ - Cli: client, - Ctx: context.Background(), - logger: logger.NewLogger(), - } + lgr := logger.NewLogger() + cli, tunnel := newDockerClientWithOptionalSSHTunnel(lgr) + svc := &DockerService{Cli: cli, Ctx: context.Background(), logger: lgr, sshTunnel: tunnel} - // Initialize cluster if not already initialized, this should be run on master node only - // TODO: Add a check to see if the node is the master node - // WARNING: This should be thought again during multi-server architecture feature - if !isClusterInitialized(client) { - if err := service.InitCluster(); err != nil { - service.logger.Log(logger.Warning, "Failed to initialize cluster", err.Error()) + if !isClusterInitialized(svc.Cli) { + if err := svc.InitCluster(); err != nil { + svc.logger.Log(logger.Warning, "Failed to initialize cluster", err.Error()) } else { - service.logger.Log(logger.Info, "Cluster initialized successfully", "") + svc.logger.Log(logger.Info, "Cluster initialized successfully", "") } } else { - service.logger.Log(logger.Info, "Cluster already initialized", "") + svc.logger.Log(logger.Info, "Cluster already initialized", "") + } + + return svc +} + +func newDockerClientWithOptionalSSHTunnel(lgr logger.Logger) (*client.Client, *SSHTunnel) { + sshClient := ssh.NewSSH() + // Try to create an SSH tunnel to the remote Docker daemon socket, if it fails, use the local docker socket + tunnel, err := CreateSSHTunnel(sshClient, lgr) + if err != nil || tunnel == nil { + if err != nil { + lgr.Log(logger.Info, "SSH tunnel not established, using local docker socket", err.Error()) + } + // If the SSH tunnel creation fails, use the local docker socket + lgr.Log(logger.Info, "Using local docker socket", "") + return NewDockerClient(), nil } - return service + host := fmt.Sprintf("unix://%s", tunnel.localSocket) + lgr.Log(logger.Info, "SSH tunnel established; using tunneled docker socket", host) + cli, cliErr := client.NewClientWithOpts( + client.WithHost(host), + client.WithAPIVersionNegotiation(), + ) + if cliErr != nil { + lgr.Log(logger.Warning, "Failed to create docker client over SSH tunnel, using local", cliErr.Error()) + return NewDockerClient(), nil + } + lgr.Log(logger.Info, "Docker client created over SSH tunnel", "") + return cli, tunnel } func isClusterInitialized(cli *client.Client) bool { diff --git a/api/internal/features/deploy/docker/ssh_tunnel.go b/api/internal/features/deploy/docker/ssh_tunnel.go new file mode 100644 index 000000000..63c558879 --- /dev/null +++ b/api/internal/features/deploy/docker/ssh_tunnel.go @@ -0,0 +1,98 @@ +package docker + +import ( + "fmt" + "io" + "net" + "os" + "path/filepath" + "time" + + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/ssh" +) + +// CreateSSHTunnel creates a local Unix socket and forwards all connections +// through the provided SSH client to the remote Docker daemon socket +// at /var/run/docker.sock. It returns an SSHTunnel with a cleanup function +// that closes the listener and removes the temporary socket file. +func CreateSSHTunnel(sshClient *ssh.SSH, logger logger.Logger) (*SSHTunnel, error) { + tempDir := os.TempDir() + localSocket := filepath.Join(tempDir, fmt.Sprintf("docker-ssh-%d.sock", time.Now().UnixNano())) + + os.Remove(localSocket) + + listener, err := net.Listen("unix", localSocket) + if err != nil { + return nil, fmt.Errorf("failed to create local socket: %w", err) + } + + tunnel := &SSHTunnel{ + localSocket: localSocket, + sshClient: sshClient, + listener: listener, + cleanup: func() error { + listener.Close() + os.Remove(localSocket) + return nil + }, + } + + go tunnel.handleConnections(logger) + + return tunnel, nil +} + +// handleConnections manages the SSH tunnel connections +func (t *SSHTunnel) handleConnections(lgr logger.Logger) { + for { + localConn, err := t.listener.Accept() + if err != nil { + lgr.Log(logger.Error, "SSH tunnel listener error", err.Error()) + return + } + + go t.forwardConnection(localConn, lgr) + } +} + +// forwardConnection forwards a local connection through the SSH tunnel to the remote Docker socket +func (t *SSHTunnel) forwardConnection(localConn net.Conn, lgr logger.Logger) { + defer localConn.Close() + + sshConn, err := t.sshClient.Connect() + if err != nil { + lgr.Log(logger.Error, "Failed to establish SSH connection", err.Error()) + return + } + defer sshConn.Close() + + remoteConn, err := sshConn.Dial("unix", "/var/run/docker.sock") + if err != nil { + lgr.Log(logger.Error, "Failed to connect to remote Docker socket", err.Error()) + return + } + defer remoteConn.Close() + + done := make(chan struct{}, 2) + + go func() { + io.Copy(remoteConn, localConn) + done <- struct{}{} + }() + + go func() { + io.Copy(localConn, remoteConn) + done <- struct{}{} + }() + + <-done +} + +// Close cleans up the DockerService and any SSH tunnels +func (s *DockerService) Close() error { + if s.sshTunnel != nil { + return s.sshTunnel.cleanup() + } + return nil +} diff --git a/api/internal/features/feature-flags/service/init.go b/api/internal/features/feature-flags/service/init.go index 7b6bd558c..87039c8bd 100644 --- a/api/internal/features/feature-flags/service/init.go +++ b/api/internal/features/feature-flags/service/init.go @@ -42,7 +42,7 @@ func (s *FeatureFlagService) GetFeatureFlags(organizationID uuid.UUID) ([]types. defer tx.Rollback() txStorage := s.storage.WithTx(tx) - defaultFeatures := []types.FeatureName{types.FeatureDomain, types.FeatureTerminal, types.FeatureNotifications, types.FeatureFileManager, types.FeatureSelfHosted, types.FeatureAudit, types.FeatureGithubConnector, types.FeatureMonitoring, types.FeatureContainer} + defaultFeatures := []types.FeatureName{types.FeatureDomain, types.FeatureTerminal, types.FeatureNotifications, types.FeatureFileManager, types.FeatureSelfHosted, types.FeatureAudit, types.FeatureGithubConnector, types.FeatureMonitoring, types.FeatureContainer, types.FeatureServers} defaultFlags := make([]types.FeatureFlag, 0, len(defaultFeatures)) for _, feature := range defaultFeatures { diff --git a/api/internal/features/servers/controller/create-server.go b/api/internal/features/servers/controller/create-server.go new file mode 100644 index 000000000..48080c81e --- /dev/null +++ b/api/internal/features/servers/controller/create-server.go @@ -0,0 +1,88 @@ +package controller + +import ( + "net/http" + + "github.com/go-fuego/fuego" + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/utils" + + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +func (c *ServersController) CreateServer(f fuego.ContextWithBody[types.CreateServerRequest]) (*shared_types.Response, error) { + serverRequest, err := f.Body() + + if err != nil { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusBadRequest, + } + } + + w, r := f.Response(), f.Request() + if !c.parseAndValidate(w, r, &serverRequest) { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusBadRequest, + } + } + + user := utils.GetUser(w, r) + + if user == nil { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusUnauthorized, + } + } + + organization := utils.GetOrganizationID(r) + + if organization == uuid.Nil { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusUnauthorized, + } + } + + created, err := c.service.CreateServer(serverRequest, user.ID.String(), organization.String()) + + if err != nil { + c.logger.Log(logger.Error, err.Error(), "") + + if isInvalidServerError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusBadRequest, + } + } + + if err == types.ErrServerAlreadyExists || err == types.ErrServerHostAlreadyExists { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusConflict, + } + } + + if isPermissionError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusForbidden, + } + } + + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusInternalServerError, + } + } + + return &shared_types.Response{ + Status: "success", + Message: "Server created successfully", + Data: created, + }, nil +} \ No newline at end of file diff --git a/api/internal/features/servers/controller/delete-server.go b/api/internal/features/servers/controller/delete-server.go new file mode 100644 index 000000000..14fa4d084 --- /dev/null +++ b/api/internal/features/servers/controller/delete-server.go @@ -0,0 +1,78 @@ +package controller + +import ( + "net/http" + + "github.com/go-fuego/fuego" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/utils" + + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +func (c *ServersController) DeleteServer(f fuego.ContextWithBody[types.DeleteServerRequest]) (*shared_types.Response, error) { + serverRequest, err := f.Body() + + if err != nil { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusBadRequest, + } + } + + w, r := f.Response(), f.Request() + if !c.parseAndValidate(w, r, &serverRequest) { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusBadRequest, + } + } + + user := utils.GetUser(w, r) + + if user == nil { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusUnauthorized, + } + } + + err = c.service.DeleteServer(serverRequest, user.ID.String()) + + if err != nil { + c.logger.Log(logger.Error, err.Error(), "") + + if isInvalidServerError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusBadRequest, + } + } + + if err == types.ErrServerNotFound { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusNotFound, + } + } + + if isPermissionError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusForbidden, + } + } + + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusInternalServerError, + } + } + + return &shared_types.Response{ + Status: "success", + Message: "Server deleted successfully", + Data: nil, + }, nil +} diff --git a/api/internal/features/servers/controller/error-helpers.go b/api/internal/features/servers/controller/error-helpers.go new file mode 100644 index 000000000..89b05b09f --- /dev/null +++ b/api/internal/features/servers/controller/error-helpers.go @@ -0,0 +1,41 @@ +package controller + +import "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + +func isInvalidServerError(err error) bool { + switch err { + case types.ErrInvalidServerID, + types.ErrMissingServerID, + types.ErrServerNameInvalid, + types.ErrServerNameTooLong, + types.ErrServerNameTooShort, + types.ErrMissingServerName, + types.ErrMissingHost, + types.ErrInvalidHost, + types.ErrMissingPort, + types.ErrInvalidPort, + types.ErrMissingUsername, + types.ErrMissingSSHAuth, + types.ErrBothSSHAuthProvided, + types.ErrInvalidSSHPrivateKeyPath, + types.ErrSSHConnectionFailed, + types.ErrSSHAuthenticationFailed, + types.ErrMissingStatus, + types.ErrInvalidStatus: + return true + default: + return false + } +} + +func isPermissionError(err error) bool { + switch err { + case types.ErrUserDoesNotBelongToOrganization, + types.ErrPermissionDenied, + types.ErrAccessDenied, + types.ErrUserDoesNotHavePermissionForTheResource: + return true + default: + return false + } +} diff --git a/api/internal/features/servers/controller/get-server.go b/api/internal/features/servers/controller/get-server.go new file mode 100644 index 000000000..4e6ed0604 --- /dev/null +++ b/api/internal/features/servers/controller/get-server.go @@ -0,0 +1,64 @@ +package controller + +import ( + "net/http" + + "github.com/go-fuego/fuego" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/utils" + + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +func (c *ServersController) GetServer(f fuego.ContextNoBody) (*shared_types.Response, error) { + serverID := f.Request().URL.Query().Get("id") + + if serverID == "" { + return nil, fuego.HTTPError{ + Err: types.ErrMissingServerID, + Status: http.StatusBadRequest, + } + } + + w, r := f.Response(), f.Request() + user := utils.GetUser(w, r) + + if user == nil { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusUnauthorized, + } + } + + server, err := c.service.GetServer(serverID, user.ID.String()) + + if err != nil { + c.logger.Log(logger.Error, err.Error(), "") + + if err == types.ErrServerNotFound { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusNotFound, + } + } + + if isPermissionError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusForbidden, + } + } + + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusInternalServerError, + } + } + + return &shared_types.Response{ + Status: "success", + Message: "Server retrieved successfully", + Data: server, + }, nil +} diff --git a/api/internal/features/servers/controller/get-servers.go b/api/internal/features/servers/controller/get-servers.go new file mode 100644 index 000000000..edd90d2a5 --- /dev/null +++ b/api/internal/features/servers/controller/get-servers.go @@ -0,0 +1,92 @@ +package controller + +import ( + "net/http" + "strconv" + + "github.com/go-fuego/fuego" + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/utils" + + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +func (c *ServersController) GetServers(f fuego.ContextNoBody) (*shared_types.Response, error) { + w, r := f.Response(), f.Request() + user := utils.GetUser(w, r) + + if user == nil { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusUnauthorized, + } + } + + organizationID := utils.GetOrganizationID(r) + if organizationID == uuid.Nil { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusBadRequest, + } + } + + queryParams := parseServerQueryParams(r) + queryParams.SetDefaults() + + if !queryParams.IsValidSortField() { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusBadRequest, + } + } + + serverListResponse, err := c.service.GetServers(user.ID.String(), organizationID.String(), queryParams) + + if err != nil { + c.logger.Log(logger.Error, err.Error(), "") + + if isPermissionError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusForbidden, + } + } + + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusInternalServerError, + } + } + + return &shared_types.Response{ + Status: "success", + Message: "Servers retrieved successfully", + Data: serverListResponse, + }, nil +} + +func parseServerQueryParams(r *http.Request) *types.ServerQueryParams { + params := &types.ServerQueryParams{} + + if pageStr := r.URL.Query().Get("page"); pageStr != "" { + if page, err := strconv.Atoi(pageStr); err == nil { + params.Page = page + } + } + + if pageSizeStr := r.URL.Query().Get("page_size"); pageSizeStr != "" { + if pageSize, err := strconv.Atoi(pageSizeStr); err == nil { + params.PageSize = pageSize + } + } + + params.Search = r.URL.Query().Get("search") + + params.SortBy = r.URL.Query().Get("sort_by") + + params.SortOrder = r.URL.Query().Get("sort_order") + + return params +} diff --git a/api/internal/features/servers/controller/init.go b/api/internal/features/servers/controller/init.go new file mode 100644 index 000000000..2cb1dc6bb --- /dev/null +++ b/api/internal/features/servers/controller/init.go @@ -0,0 +1,66 @@ +package controller + +import ( + "context" + "net/http" + + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/notification" + "github.com/raghavyuva/nixopus-api/internal/features/servers/service" + "github.com/raghavyuva/nixopus-api/internal/features/servers/storage" + "github.com/raghavyuva/nixopus-api/internal/features/servers/validation" + shared_storage "github.com/raghavyuva/nixopus-api/internal/storage" + "github.com/raghavyuva/nixopus-api/internal/utils" +) + +type ServersController struct { + store *shared_storage.Store + validator *validation.Validator + service *service.ServersService + ctx context.Context + logger logger.Logger + notification *notification.NotificationManager +} + +func NewServersController( + store *shared_storage.Store, + ctx context.Context, + l logger.Logger, + notificationManager *notification.NotificationManager, +) *ServersController { + storage := storage.ServerStorage{DB: store.DB, Ctx: ctx} + return &ServersController{ + store: store, + validator: validation.NewValidator(&storage), + service: service.NewServersService(store, ctx, l, &storage), + ctx: ctx, + logger: l, + notification: notificationManager, + } +} + +// parseAndValidate parses and validates the request body. +// +// This method attempts to parse the request body into the provided 'req' interface +// using the controller's validator. If parsing fails, an error response is sent +// and the method returns false. It also validates the parsed request object and +// returns false if validation fails. If both operations are successful, it returns true. +// +// Parameters: +// +// w - the HTTP response writer to send error responses. +// r - the HTTP request containing the body to parse. +// req - the interface to populate with the parsed request body. +// +// Returns: +// +// bool - true if parsing and validation succeed, false otherwise. +func (c *ServersController) parseAndValidate(w http.ResponseWriter, r *http.Request, req interface{}) bool { + if err := c.validator.ValidateRequest(req); err != nil { + c.logger.Log(logger.Error, err.Error(), err.Error()) + utils.SendErrorResponse(w, err.Error(), http.StatusBadRequest) + return false + } + + return true +} diff --git a/api/internal/features/servers/controller/update-server-status.go b/api/internal/features/servers/controller/update-server-status.go new file mode 100644 index 000000000..0f8c21aad --- /dev/null +++ b/api/internal/features/servers/controller/update-server-status.go @@ -0,0 +1,78 @@ +package controller + +import ( + "net/http" + + "github.com/go-fuego/fuego" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/utils" + + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +func (c *ServersController) UpdateServerStatus(f fuego.ContextWithBody[types.UpdateServerStatusRequest]) (*shared_types.Response, error) { + serverStatusRequest, err := f.Body() + + if err != nil { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusBadRequest, + } + } + + w, r := f.Response(), f.Request() + if !c.parseAndValidate(w, r, &serverStatusRequest) { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusBadRequest, + } + } + + user := utils.GetUser(w, r) + + if user == nil { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusUnauthorized, + } + } + + updated, err := c.service.UpdateServerStatus(serverStatusRequest, user.ID.String()) + + if err != nil { + c.logger.Log(logger.Error, err.Error(), "") + + if isInvalidServerError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusBadRequest, + } + } + + if err == types.ErrServerNotFound { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusNotFound, + } + } + + if isPermissionError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusForbidden, + } + } + + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusInternalServerError, + } + } + + return &shared_types.Response{ + Status: "success", + Message: "Server status updated successfully", + Data: updated, + }, nil +} diff --git a/api/internal/features/servers/controller/update-server.go b/api/internal/features/servers/controller/update-server.go new file mode 100644 index 000000000..363da3889 --- /dev/null +++ b/api/internal/features/servers/controller/update-server.go @@ -0,0 +1,85 @@ +package controller + +import ( + "net/http" + + "github.com/go-fuego/fuego" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/utils" + + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +func (c *ServersController) UpdateServer(f fuego.ContextWithBody[types.UpdateServerRequest]) (*shared_types.Response, error) { + serverRequest, err := f.Body() + + if err != nil { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusBadRequest, + } + } + + w, r := f.Response(), f.Request() + if !c.parseAndValidate(w, r, &serverRequest) { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusBadRequest, + } + } + + user := utils.GetUser(w, r) + + if user == nil { + return nil, fuego.HTTPError{ + Err: nil, + Status: http.StatusUnauthorized, + } + } + + updated, err := c.service.UpdateServer(serverRequest, user.ID.String()) + + if err != nil { + c.logger.Log(logger.Error, err.Error(), "") + + if isInvalidServerError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusBadRequest, + } + } + + if err == types.ErrServerNotFound { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusNotFound, + } + } + + if err == types.ErrServerAlreadyExists || err == types.ErrServerHostAlreadyExists { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusConflict, + } + } + + if isPermissionError(err) { + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusForbidden, + } + } + + return nil, fuego.HTTPError{ + Err: err, + Status: http.StatusInternalServerError, + } + } + + return &shared_types.Response{ + Status: "success", + Message: "Server updated successfully", + Data: updated, + }, nil +} diff --git a/api/internal/features/servers/service/create_server.go b/api/internal/features/servers/service/create_server.go new file mode 100644 index 000000000..e818270ae --- /dev/null +++ b/api/internal/features/servers/service/create_server.go @@ -0,0 +1,162 @@ +package service + +import ( + "fmt" + "strings" + "time" + + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/features/servers/validation" + "github.com/raghavyuva/nixopus-api/internal/features/ssh" + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +func (s *ServersService) verifySSHConnection(req types.CreateServerRequest) error { + s.logger.Log(logger.Info, "verifying SSH connection", fmt.Sprintf("host=%s, port=%d, user=%s", req.Host, req.Port, req.Username)) + + sshClient := &ssh.SSH{ + Host: req.Host, + User: req.Username, + Port: uint(req.Port), + } + + if req.SSHPassword != nil && *req.SSHPassword != "" { + sshClient.Password = *req.SSHPassword + } + + if req.SSHPrivateKeyPath != nil && *req.SSHPrivateKeyPath != "" { + sshClient.PrivateKey = *req.SSHPrivateKeyPath + } + + client, err := sshClient.Connect() + if err != nil { + msg := err.Error() + s.logger.Log(logger.Error, "SSH connection verification failed", fmt.Sprintf("host=%s, port=%d, user=%s, error=%s", req.Host, req.Port, req.Username, msg)) + return classifySSHError(msg) + } + defer client.Close() + + s.logger.Log(logger.Info, "SSH connection verified successfully", fmt.Sprintf("host=%s, port=%d, user=%s", req.Host, req.Port, req.Username)) + return nil +} + +// CreateServer creates a new server in the application. +// +// It takes a CreateServerRequest, which contains the server details, and a user ID. +// The user ID is used to associate the server with a user. +// +// It returns a CreateServerResponse containing the server ID, and an error. +// The error is either ErrServerAlreadyExists, or any error that occurred +// while creating the server in the storage layer. +func (s *ServersService) CreateServer(req types.CreateServerRequest, userID string, organizationID string) (types.CreateServerResponse, error) { + s.logger.Log(logger.Info, "create server request received", fmt.Sprintf("server_name=%s, host=%s, user_id=%s", req.Name, req.Host, userID)) + + _, err := uuid.Parse(userID) + if err != nil { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return types.CreateServerResponse{}, types.ErrInvalidUserID + } + + if userID == "" { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return types.CreateServerResponse{}, types.ErrInvalidUserID + } + + validator := validation.NewValidator(s.storage) + if err := validator.ValidateCreateServerRequest(req); err != nil { + return types.CreateServerResponse{}, err + } + + if err := s.verifySSHConnection(req); err != nil { + s.logger.Log(logger.Error, "SSH connection verification failed", err.Error()) + return types.CreateServerResponse{}, err + } + + org, err := s.store.Organization.GetOrganization(organizationID) + if err != nil { + s.logger.Log(logger.Error, "error while retrieving organization", err.Error()) + return types.CreateServerResponse{}, fmt.Errorf("organization not found") + } + if org == nil || org.ID == uuid.Nil { + s.logger.Log(logger.Error, "organization not found", organizationID) + return types.CreateServerResponse{}, fmt.Errorf("organization not found") + } + + tx, err := s.storage.BeginTx() + if err != nil { + s.logger.Log(logger.Error, "failed to start transaction", err.Error()) + return types.CreateServerResponse{}, types.ErrFailedToCreateServer + } + defer tx.Rollback() + + txStorage := s.storage.WithTx(tx) + + // Check for existing server by name + existingServerByName, err := txStorage.GetServerName(req.Name, uuid.MustParse(organizationID)) + if err != nil { + s.logger.Log(logger.Debug, "error while checking existing server by name", err.Error()) + } + + if existingServerByName != nil { + s.logger.Log(logger.Error, "server already exists", fmt.Sprintf("server_name=%s", req.Name)) + return types.CreateServerResponse{}, types.ErrServerAlreadyExists + } + + // Check for existing server by host and port + existingServerByHost, err := txStorage.GetServerByHost(req.Host, req.Port, uuid.MustParse(organizationID)) + if err != nil { + s.logger.Log(logger.Debug, "error while checking existing server by host", err.Error()) + } + + if existingServerByHost != nil { + s.logger.Log(logger.Error, "server with host already exists", fmt.Sprintf("host=%s, port=%d", req.Host, req.Port)) + return types.CreateServerResponse{}, types.ErrServerHostAlreadyExists + } + + server := &shared_types.Server{ + ID: uuid.New(), + Name: req.Name, + Description: req.Description, + Host: req.Host, + Port: req.Port, + Username: req.Username, + SSHPassword: req.SSHPassword, + SSHPrivateKeyPath: req.SSHPrivateKeyPath, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: nil, + UserID: uuid.MustParse(userID), + OrganizationID: uuid.MustParse(organizationID), + } + + if err := txStorage.CreateServer(server); err != nil { + s.logger.Log(logger.Error, "error while creating server", err.Error()) + return types.CreateServerResponse{}, err + } + + if err := tx.Commit(); err != nil { + s.logger.Log(logger.Error, "failed to commit transaction", err.Error()) + return types.CreateServerResponse{}, types.ErrFailedToCreateServer + } + + return types.CreateServerResponse{ID: server.ID.String()}, nil +} + +func classifySSHError(msg string) error { + m := strings.ToLower(msg) + // DNS/host resolution errors + if strings.Contains(m, "no such host") || strings.Contains(m, "temporary failure in name resolution") || strings.Contains(m, "name or service not known") { + return types.ErrInvalidHost + } + // Authentication errors + if strings.Contains(m, "permission denied") || strings.Contains(m, "unable to authenticate") || strings.Contains(m, "auth") { + return types.ErrSSHAuthenticationFailed + } + // Connectivity errors + if strings.Contains(m, "connection refused") || strings.Contains(m, "no route to host") || strings.Contains(m, "i/o timeout") || strings.Contains(m, "network is unreachable") || strings.Contains(m, "connection timed out") { + return types.ErrSSHConnectionFailed + } + return types.ErrSSHConnectionFailed +} diff --git a/api/internal/features/servers/service/delete_server.go b/api/internal/features/servers/service/delete_server.go new file mode 100644 index 000000000..eabe7212c --- /dev/null +++ b/api/internal/features/servers/service/delete_server.go @@ -0,0 +1,72 @@ +package service + +import ( + "fmt" + + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/features/servers/validation" +) + +// DeleteServer deletes a server (soft delete) +func (s *ServersService) DeleteServer(req types.DeleteServerRequest, userID string) error { + s.logger.Log(logger.Info, "delete server request received", fmt.Sprintf("server_id=%s, user_id=%s", req.ID, userID)) + + _, err := uuid.Parse(userID) + if err != nil { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return types.ErrInvalidUserID + } + + if userID == "" { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return types.ErrInvalidUserID + } + + validator := validation.NewValidator(s.storage) + if err := validator.ValidateDeleteServerRequest(req); err != nil { + return err + } + + tx, err := s.storage.BeginTx() + if err != nil { + s.logger.Log(logger.Error, "failed to start transaction", err.Error()) + return types.ErrFailedToDeleteServer + } + defer tx.Rollback() + + txStorage := s.storage.WithTx(tx) + + // Get the existing server + existingServer, err := txStorage.GetServer(req.ID) + if err != nil { + s.logger.Log(logger.Error, "error while retrieving server", err.Error()) + return types.ErrServerNotFound + } + + if existingServer == nil { + s.logger.Log(logger.Error, "server not found", fmt.Sprintf("server_id=%s", req.ID)) + return types.ErrServerNotFound + } + + // Check if the user owns the server + if existingServer.UserID.String() != userID { + s.logger.Log(logger.Error, "user does not own server", fmt.Sprintf("server_id=%s, user_id=%s", req.ID, userID)) + return types.ErrPermissionDenied + } + + // Soft delete the server + if err := txStorage.DeleteServer(existingServer); err != nil { + s.logger.Log(logger.Error, "error while deleting server", err.Error()) + return err + } + + if err := tx.Commit(); err != nil { + s.logger.Log(logger.Error, "failed to commit transaction", err.Error()) + return types.ErrFailedToDeleteServer + } + + s.logger.Log(logger.Info, "server deleted successfully", fmt.Sprintf("server_id=%s", req.ID)) + return nil +} diff --git a/api/internal/features/servers/service/get_server.go b/api/internal/features/servers/service/get_server.go new file mode 100644 index 000000000..70491e3ea --- /dev/null +++ b/api/internal/features/servers/service/get_server.go @@ -0,0 +1,50 @@ +package service + +import ( + "fmt" + + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +// GetServer retrieves a server by ID for a specific user +func (s *ServersService) GetServer(serverID string, userID string) (*shared_types.Server, error) { + s.logger.Log(logger.Info, "get server request received", fmt.Sprintf("server_id=%s, user_id=%s", serverID, userID)) + + _, err := uuid.Parse(userID) + if err != nil { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return nil, types.ErrInvalidUserID + } + + if userID == "" { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return nil, types.ErrInvalidUserID + } + + _, err = uuid.Parse(serverID) + if err != nil { + s.logger.Log(logger.Error, "invalid server id", fmt.Sprintf("server_id=%s", serverID)) + return nil, types.ErrInvalidServerID + } + + server, err := s.storage.GetServer(serverID) + if err != nil { + s.logger.Log(logger.Error, "error while retrieving server", err.Error()) + return nil, types.ErrServerNotFound + } + + if server == nil { + s.logger.Log(logger.Error, "server not found", fmt.Sprintf("server_id=%s", serverID)) + return nil, types.ErrServerNotFound + } + + if server.UserID.String() != userID { + s.logger.Log(logger.Error, "user does not own server", fmt.Sprintf("server_id=%s, user_id=%s, owner_id=%s", serverID, userID, server.UserID.String())) + return nil, types.ErrPermissionDenied + } + + return server, nil +} diff --git a/api/internal/features/servers/service/get_servers.go b/api/internal/features/servers/service/get_servers.go new file mode 100644 index 000000000..76f9c0f37 --- /dev/null +++ b/api/internal/features/servers/service/get_servers.go @@ -0,0 +1,55 @@ +package service + +import ( + "fmt" + "math" + + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" +) + +// GetServers retrieves servers for a specific user within their organization with pagination, search, and sorting +func (s *ServersService) GetServers(userID string, organizationID string, queryParams *types.ServerQueryParams) (*types.ServerListResponse, error) { + s.logger.Log(logger.Info, "get servers request received", fmt.Sprintf("user_id=%s, organization_id=%s, page=%d, page_size=%d, search=%s, sort_by=%s, sort_order=%s", + userID, organizationID, queryParams.Page, queryParams.PageSize, queryParams.Search, queryParams.SortBy, queryParams.SortOrder)) + + userUUID, err := uuid.Parse(userID) + if err != nil { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return nil, types.ErrInvalidUserID + } + + if userID == "" { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return nil, types.ErrInvalidUserID + } + + totalCount, err := s.storage.GetServersCount(organizationID, userUUID, queryParams.Search) + if err != nil { + s.logger.Log(logger.Error, "error while retrieving servers count", err.Error()) + return nil, err + } + + servers, err := s.storage.GetServersPaginated(organizationID, userUUID, queryParams) + if err != nil { + s.logger.Log(logger.Error, "error while retrieving servers", err.Error()) + return nil, err + } + + totalPages := int(math.Ceil(float64(totalCount) / float64(queryParams.PageSize))) + + pagination := types.Pagination{ + CurrentPage: queryParams.Page, + PageSize: queryParams.PageSize, + TotalPages: totalPages, + TotalItems: totalCount, + HasNext: queryParams.Page < totalPages, + HasPrev: queryParams.Page > 1, + } + + return &types.ServerListResponse{ + Servers: servers, + Pagination: pagination, + }, nil +} diff --git a/api/internal/features/servers/service/init.go b/api/internal/features/servers/service/init.go new file mode 100644 index 000000000..079f5036c --- /dev/null +++ b/api/internal/features/servers/service/init.go @@ -0,0 +1,25 @@ +package service + +import ( + "context" + + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/storage" + shared_storage "github.com/raghavyuva/nixopus-api/internal/storage" +) + +type ServersService struct { + storage storage.ServerStorageInterface + Ctx context.Context + store *shared_storage.Store + logger logger.Logger +} + +func NewServersService(store *shared_storage.Store, ctx context.Context, logger logger.Logger, server_repo storage.ServerStorageInterface) *ServersService { + return &ServersService{ + storage: server_repo, + store: store, + Ctx: ctx, + logger: logger, + } +} diff --git a/api/internal/features/servers/service/update_server.go b/api/internal/features/servers/service/update_server.go new file mode 100644 index 000000000..325bffb2b --- /dev/null +++ b/api/internal/features/servers/service/update_server.go @@ -0,0 +1,126 @@ +package service + +import ( + "fmt" + "time" + + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/features/servers/validation" + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +// UpdateServer updates an existing server +func (s *ServersService) UpdateServer(req types.UpdateServerRequest, userID string) (*shared_types.Server, error) { + s.logger.Log(logger.Info, "update server request received", fmt.Sprintf("server_id=%s, user_id=%s", req.ID, userID)) + + _, err := uuid.Parse(userID) + if err != nil { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return nil, types.ErrInvalidUserID + } + + if userID == "" { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return nil, types.ErrInvalidUserID + } + + validator := validation.NewValidator(s.storage) + if err := validator.ValidateUpdateServerRequest(req); err != nil { + return nil, err + } + + tx, err := s.storage.BeginTx() + if err != nil { + s.logger.Log(logger.Error, "failed to start transaction", err.Error()) + return nil, types.ErrFailedToUpdateServer + } + defer tx.Rollback() + + txStorage := s.storage.WithTx(tx) + + // Get the existing server + existingServer, err := txStorage.GetServer(req.ID) + if err != nil { + s.logger.Log(logger.Error, "error while retrieving server", err.Error()) + return nil, types.ErrServerNotFound + } + + if existingServer == nil { + s.logger.Log(logger.Error, "server not found", fmt.Sprintf("server_id=%s", req.ID)) + return nil, types.ErrServerNotFound + } + + // Check if the user owns the server + if existingServer.UserID.String() != userID { + s.logger.Log(logger.Error, "user does not own server", fmt.Sprintf("server_id=%s, user_id=%s", req.ID, userID)) + return nil, types.ErrPermissionDenied + } + + // Check if another server with the same name exists (excluding current server) + if req.Name != existingServer.Name { + existingServerByName, err := txStorage.GetServerName(req.Name, existingServer.OrganizationID) + if err != nil { + s.logger.Log(logger.Debug, "error while checking existing server by name", err.Error()) + } + + if existingServerByName != nil && existingServerByName.ID != existingServer.ID { + s.logger.Log(logger.Error, "server with name already exists", fmt.Sprintf("server_name=%s", req.Name)) + return nil, types.ErrServerAlreadyExists + } + } + + // Check if another server with the same host:port exists (excluding current server) + if req.Host != existingServer.Host || req.Port != existingServer.Port { + existingServerByHost, err := txStorage.GetServerByHost(req.Host, req.Port, existingServer.OrganizationID) + if err != nil { + s.logger.Log(logger.Debug, "error while checking existing server by host", err.Error()) + } + + if existingServerByHost != nil && existingServerByHost.ID != existingServer.ID { + s.logger.Log(logger.Error, "server with host already exists", fmt.Sprintf("host=%s, port=%d", req.Host, req.Port)) + return nil, types.ErrServerHostAlreadyExists + } + } + + // Update the server - preserve existing auth credentials if not provided + sshPassword := existingServer.SSHPassword + if req.SSHPassword != nil { + sshPassword = req.SSHPassword + } + + sshPrivateKeyPath := existingServer.SSHPrivateKeyPath + if req.SSHPrivateKeyPath != nil { + sshPrivateKeyPath = req.SSHPrivateKeyPath + } + + updatedServer := &shared_types.Server{ + ID: existingServer.ID, + Name: req.Name, + Description: req.Description, + Host: req.Host, + Port: req.Port, + Username: req.Username, + SSHPassword: sshPassword, + SSHPrivateKeyPath: sshPrivateKeyPath, + Status: existingServer.Status, + CreatedAt: existingServer.CreatedAt, + UpdatedAt: time.Now(), + DeletedAt: existingServer.DeletedAt, + UserID: existingServer.UserID, + OrganizationID: existingServer.OrganizationID, + } + + if err := txStorage.UpdateServer(updatedServer); err != nil { + s.logger.Log(logger.Error, "error while updating server", err.Error()) + return nil, err + } + + if err := tx.Commit(); err != nil { + s.logger.Log(logger.Error, "failed to commit transaction", err.Error()) + return nil, types.ErrFailedToUpdateServer + } + + return updatedServer, nil +} diff --git a/api/internal/features/servers/service/update_server_status.go b/api/internal/features/servers/service/update_server_status.go new file mode 100644 index 000000000..2278a06ef --- /dev/null +++ b/api/internal/features/servers/service/update_server_status.go @@ -0,0 +1,77 @@ +package service + +import ( + "fmt" + + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/logger" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + "github.com/raghavyuva/nixopus-api/internal/features/servers/validation" + shared_types "github.com/raghavyuva/nixopus-api/internal/types" +) + +func (s *ServersService) UpdateServerStatus(req types.UpdateServerStatusRequest, userID string) (*shared_types.Server, error) { + s.logger.Log(logger.Info, "update server status request received", fmt.Sprintf("server_id=%s, status=%s, user_id=%s", req.ID, req.Status, userID)) + + _, err := uuid.Parse(userID) + if err != nil { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return nil, types.ErrInvalidUserID + } + + if userID == "" { + s.logger.Log(logger.Error, "invalid user id", fmt.Sprintf("user_id=%s", userID)) + return nil, types.ErrInvalidUserID + } + + validator := validation.NewValidator(s.storage) + if err := validator.ValidateUpdateServerStatusRequest(req); err != nil { + return nil, err + } + + tx, err := s.storage.BeginTx() + if err != nil { + s.logger.Log(logger.Error, "failed to start transaction", err.Error()) + return nil, types.ErrFailedToUpdateServer + } + defer tx.Rollback() + + txStorage := s.storage.WithTx(tx) + + existingServer, err := txStorage.GetServer(req.ID) + if err != nil { + s.logger.Log(logger.Error, "error while retrieving server", err.Error()) + return nil, types.ErrServerNotFound + } + + if existingServer == nil { + s.logger.Log(logger.Error, "server not found", fmt.Sprintf("server_id=%s", req.ID)) + return nil, types.ErrServerNotFound + } + + if existingServer.UserID.String() != userID { + s.logger.Log(logger.Error, "user does not own server", fmt.Sprintf("server_id=%s, user_id=%s", req.ID, userID)) + return nil, types.ErrPermissionDenied + } + + err = txStorage.UpdateServerStatus(req.ID, req.Status) + if err != nil { + s.logger.Log(logger.Error, "failed to update server status", err.Error()) + return nil, types.ErrFailedToUpdateServer + } + + if err := tx.Commit(); err != nil { + s.logger.Log(logger.Error, "failed to commit transaction", err.Error()) + return nil, types.ErrFailedToUpdateServer + } + + updatedServer, err := s.storage.GetServer(req.ID) + if err != nil { + s.logger.Log(logger.Error, "error while retrieving updated server", err.Error()) + return nil, types.ErrServerNotFound + } + + s.logger.Log(logger.Info, "server status updated successfully", fmt.Sprintf("server_id=%s, new_status=%s", req.ID, req.Status)) + + return updatedServer, nil +} diff --git a/api/internal/features/servers/storage/init.go b/api/internal/features/servers/storage/init.go new file mode 100644 index 000000000..417111bd5 --- /dev/null +++ b/api/internal/features/servers/storage/init.go @@ -0,0 +1,188 @@ +package storage + +import ( + "context" + + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" + shared_types "github.com/raghavyuva/nixopus-api/internal/types" + "github.com/uptrace/bun" +) + +type ServerStorage struct { + DB *bun.DB + Ctx context.Context + tx *bun.Tx +} + +type ServerStorageInterface interface { + CreateServer(server *shared_types.Server) error + GetServer(id string) (*shared_types.Server, error) + UpdateServer(server *shared_types.Server) error + UpdateServerStatus(ID string, Status string) error + DeleteServer(server *shared_types.Server) error + GetServers(OrganizationID string, UserID uuid.UUID) ([]shared_types.Server, error) + GetServersPaginated(OrganizationID string, UserID uuid.UUID, queryParams *types.ServerQueryParams) ([]shared_types.Server, error) + GetServersCount(OrganizationID string, UserID uuid.UUID, search string) (int, error) + GetServerName(name string, organizationID uuid.UUID) (*shared_types.Server, error) + GetServerByHost(host string, port int, organizationID uuid.UUID) (*shared_types.Server, error) + BeginTx() (bun.Tx, error) + WithTx(tx bun.Tx) ServerStorageInterface +} + +func (s *ServerStorage) BeginTx() (bun.Tx, error) { + return s.DB.BeginTx(s.Ctx, nil) +} + +func (s *ServerStorage) WithTx(tx bun.Tx) ServerStorageInterface { + return &ServerStorage{ + DB: s.DB, + Ctx: s.Ctx, + tx: &tx, + } +} + +func (s *ServerStorage) getDB() bun.IDB { + if s.tx != nil { + return *s.tx + } + return s.DB +} + +func (s *ServerStorage) CreateServer(server *shared_types.Server) error { + _, err := s.getDB().NewInsert().Model(server).Exec(s.Ctx) + if err != nil { + return err + } + return nil +} + +func (s *ServerStorage) GetServer(id string) (*shared_types.Server, error) { + var server shared_types.Server + err := s.getDB().NewSelect().Model(&server).Where("id = ? AND deleted_at IS NULL", id).Scan(s.Ctx) + if err != nil { + return nil, err + } + return &server, nil +} + +func (s *ServerStorage) UpdateServer(server *shared_types.Server) error { + _, err := s.getDB().NewUpdate().Model(server). + Column("name", "description", "host", "port", "username", "ssh_password", "ssh_private_key_path", "updated_at"). + Where("id = ? AND deleted_at IS NULL", server.ID). + Exec(s.Ctx) + if err != nil { + return err + } + return nil +} + +func (s *ServerStorage) UpdateServerStatus(ID string, Status string) error { + _, err := s.getDB().NewUpdate(). + Model((*shared_types.Server)(nil)). + Set("status = ?, updated_at = NOW()", Status). + Where("id = ? AND deleted_at IS NULL", ID). + Exec(s.Ctx) + if err != nil { + return err + } + return nil +} + +func (s *ServerStorage) DeleteServer(server *shared_types.Server) error { + _, err := s.getDB().NewUpdate().Model(server). + Set("deleted_at = ?", "NOW()"). + Where("id = ? AND deleted_at IS NULL", server.ID). + Exec(s.Ctx) + if err != nil { + return err + } + return nil +} + +func (s *ServerStorage) GetServers(OrganizationID string, UserID uuid.UUID) ([]shared_types.Server, error) { + var servers []shared_types.Server + err := s.getDB().NewSelect().Model(&servers). + Column("id", "name", "description", "host", "port", "username", "status", "created_at", "updated_at", "user_id", "organization_id"). + Where("organization_id = ? AND user_id = ? AND deleted_at IS NULL", OrganizationID, UserID). + Scan(s.Ctx) + if err != nil { + return nil, err + } + return servers, nil +} + +func (s *ServerStorage) GetServersPaginated(OrganizationID string, UserID uuid.UUID, queryParams *types.ServerQueryParams) ([]shared_types.Server, error) { + var servers []shared_types.Server + + query := s.getDB().NewSelect().Model(&servers). + Column("id", "name", "description", "host", "port", "username", "status", "created_at", "updated_at", "user_id", "organization_id"). + Where("organization_id = ? AND user_id = ? AND deleted_at IS NULL", OrganizationID, UserID) + + if queryParams.Search != "" { + searchTerm := "%" + queryParams.Search + "%" + query = query.Where("(name ILIKE ? OR host ILIKE ? OR username ILIKE ? OR description ILIKE ?)", + searchTerm, searchTerm, searchTerm, searchTerm) + } + + sortField := queryParams.SortBy + sortOrder := queryParams.SortOrder + + switch sortField { + case "created_at", "updated_at", "name", "host", "port", "username": + default: + sortField = "created_at" + sortOrder = "desc" + } + + query = query.Order(sortField + " " + sortOrder) + + query = query.Limit(queryParams.GetLimit()).Offset(queryParams.GetOffset()) + + err := query.Scan(s.Ctx) + if err != nil { + return nil, err + } + + return servers, nil +} + +func (s *ServerStorage) GetServersCount(OrganizationID string, UserID uuid.UUID, search string) (int, error) { + query := s.getDB().NewSelect().Model((*shared_types.Server)(nil)). + Where("organization_id = ? AND user_id = ? AND deleted_at IS NULL", OrganizationID, UserID) + + if search != "" { + searchTerm := "%" + search + "%" + query = query.Where("(name ILIKE ? OR host ILIKE ? OR username ILIKE ? OR description ILIKE ?)", + searchTerm, searchTerm, searchTerm, searchTerm) + } + + count, err := query.Count(s.Ctx) + if err != nil { + return 0, err + } + + return count, nil +} + +func (s *ServerStorage) GetServerName(name string, organizationID uuid.UUID) (*shared_types.Server, error) { + var server shared_types.Server + err := s.getDB().NewSelect().Model(&server). + Where("name = ? AND organization_id = ? AND deleted_at IS NULL", name, organizationID). + Scan(s.Ctx) + if err != nil { + return nil, err + } + return &server, nil +} + +func (s *ServerStorage) GetServerByHost(host string, port int, organizationID uuid.UUID) (*shared_types.Server, error) { + var server shared_types.Server + err := s.getDB().NewSelect().Model(&server). + Where("host = ? AND port = ? AND organization_id = ? AND deleted_at IS NULL", host, port, organizationID). + Scan(s.Ctx) + if err != nil { + return nil, err + } + return &server, nil +} diff --git a/api/internal/features/servers/types/queries.go b/api/internal/features/servers/types/queries.go new file mode 100644 index 000000000..bae190827 --- /dev/null +++ b/api/internal/features/servers/types/queries.go @@ -0,0 +1,60 @@ +package types + +type ServerQueryParams struct { + Page int `query:"page"` + PageSize int `query:"page_size"` + Search string `query:"search"` + SortBy string `query:"sort_by"` + SortOrder string `query:"sort_order"` +} + +type ServerListResponse struct { + Servers interface{} `json:"servers"` + Pagination Pagination `json:"pagination"` +} + +type Pagination struct { + CurrentPage int `json:"current_page"` + PageSize int `json:"page_size"` + TotalPages int `json:"total_pages"` + TotalItems int `json:"total_items"` + HasNext bool `json:"has_next"` + HasPrev bool `json:"has_prev"` +} + +func (q *ServerQueryParams) SetDefaults() { + if q.Page <= 0 { + q.Page = 1 + } + if q.PageSize <= 0 || q.PageSize > 100 { + q.PageSize = 10 + } + if q.SortBy == "" { + q.SortBy = "created_at" + } + if q.SortOrder != "asc" && q.SortOrder != "desc" { + q.SortOrder = "desc" + } +} + +func (q *ServerQueryParams) GetOffset() int { + return (q.Page - 1) * q.PageSize +} + +func (q *ServerQueryParams) GetLimit() int { + return q.PageSize +} + +func ValidSortFields() []string { + return []string{"name", "host", "port", "username", "created_at", "updated_at"} +} + +func (q *ServerQueryParams) IsValidSortField() bool { + validFields := ValidSortFields() + for _, field := range validFields { + if field == q.SortBy { + return true + } + } + return false +} diff --git a/api/internal/features/servers/types/servers.go b/api/internal/features/servers/types/servers.go new file mode 100644 index 000000000..43a3c18de --- /dev/null +++ b/api/internal/features/servers/types/servers.go @@ -0,0 +1,97 @@ +package types + +import ( + "errors" + "time" + + "github.com/google/uuid" +) + +var ( + ErrServerNotFound = errors.New("server not found") + ErrInvalidRequestType = errors.New("invalid request type") + ErrMissingServerName = errors.New("server name is required") + ErrInvalidServerID = errors.New("invalid server id") + ErrMissingServerID = errors.New("server id is required") + ErrServerAlreadyExists = errors.New("server already exists") + ErrServerHostAlreadyExists = errors.New("server with this host and port already exists") + ErrNotAllowed = errors.New("request not allowed") + ErrServerNameTooLong = errors.New("server name too long") + ErrServerNameTooShort = errors.New("server name too short") + ErrInvalidUserID = errors.New("invalid user id") + ErrInvalidAccess = errors.New("invalid access") + ErrUserDoesNotBelongToOrganization = errors.New("user does not belong to organization") + ErrUserDoesNotHavePermissionForTheResource = errors.New("user does not have permission for the resource") + ErrInvalidResource = errors.New("invalid resource") + ErrMissingID = errors.New("id is required") + ErrPermissionDenied = errors.New("permission denied") + ErrAccessDenied = errors.New("access denied") + ErrServerNameInvalid = errors.New("invalid server name") + ErrNoRoleAssigned = errors.New("no role assigned") + ErrFailedToCreateServer = errors.New("failed to create server") + ErrFailedToDeleteServer = errors.New("failed to delete server") + ErrFailedToUpdateServer = errors.New("failed to update server") + ErrMissingHost = errors.New("host is required") + ErrInvalidHost = errors.New("invalid host") + ErrMissingPort = errors.New("port is required") + ErrInvalidPort = errors.New("invalid port") + ErrMissingUsername = errors.New("username is required") + ErrMissingSSHAuth = errors.New("either ssh_password or ssh_private_key_path is required") + ErrBothSSHAuthProvided = errors.New("provide either ssh_password or ssh_private_key_path, not both") + ErrInvalidSSHPrivateKeyPath = errors.New("invalid ssh private key path") + ErrSSHConnectionFailed = errors.New("failed to establish SSH connection") + ErrSSHAuthenticationFailed = errors.New("SSH authentication failed") + ErrMissingStatus = errors.New("status is required") + ErrInvalidStatus = errors.New("invalid status") +) + +type CreateServerRequest struct { + Name string `json:"name"` + Description string `json:"description"` + Host string `json:"host"` + Port int `json:"port"` + Username string `json:"username"` + SSHPassword *string `json:"ssh_password,omitempty"` + SSHPrivateKeyPath *string `json:"ssh_private_key_path,omitempty"` + Status *string `json:"status,omitempty"` + OrganizationID uuid.UUID `json:"organization_id"` +} + +type UpdateServerRequest struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Host string `json:"host"` + Port int `json:"port"` + Username string `json:"username"` + SSHPassword *string `json:"ssh_password,omitempty"` + SSHPrivateKeyPath *string `json:"ssh_private_key_path,omitempty"` + Status *string `json:"status,omitempty"` +} + +type UpdateServerStatusRequest struct { + ID string `json:"id"` + Status string `json:"status"` +} + +type DeleteServerRequest struct { + ID string `json:"id"` +} + +type CreateServerResponse struct { + ID string `json:"id"` +} + +type ServerResponseWithoutSecrets struct { + ID uuid.UUID `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Host string `json:"host"` + Port int `json:"port"` + Username string `json:"username"` + Status string `json:"status"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + UserID uuid.UUID `json:"user_id"` + OrganizationID uuid.UUID `json:"organization_id"` +} diff --git a/api/internal/features/servers/validation/validator.go b/api/internal/features/servers/validation/validator.go new file mode 100644 index 000000000..7708e51b4 --- /dev/null +++ b/api/internal/features/servers/validation/validator.go @@ -0,0 +1,266 @@ +package validation + +import ( + "net" + "path/filepath" + "regexp" + "strings" + + "github.com/google/uuid" + "github.com/raghavyuva/nixopus-api/internal/features/servers/storage" + "github.com/raghavyuva/nixopus-api/internal/features/servers/types" +) + +// Validator handles server validation logic +type Validator struct { + storage storage.ServerStorageInterface +} + +// NewValidator creates a new validator instance +func NewValidator(storage storage.ServerStorageInterface) *Validator { + return &Validator{ + storage: storage, + } +} + +// ValidateID validates the server ID is a valid UUID +func (v *Validator) ValidateID(id string) error { + if id == "" { + return types.ErrMissingServerID + } + if _, err := uuid.Parse(id); err != nil { + return types.ErrInvalidServerID + } + return nil +} + +// ValidateName validates server name meets requirements +func (v *Validator) ValidateName(name string) error { + if name == "" { + return types.ErrMissingServerName + } + + if len(name) < 2 { + return types.ErrServerNameTooShort + } + + if len(name) > 255 { + return types.ErrServerNameTooLong + } + + // Allow alphanumeric characters, hyphens, underscores, and spaces + validName := regexp.MustCompile(`^[a-zA-Z0-9\-_\s]+$`) + if !validName.MatchString(name) { + return types.ErrServerNameInvalid + } + + return nil +} + +// ValidateHost validates server host (IP address or hostname) +func (v *Validator) ValidateHost(host string) error { + if host == "" { + return types.ErrMissingHost + } + + // Check if it's a valid IP address + if net.ParseIP(host) != nil { + return nil + } + + // Check if it's a valid hostname + validHostname := regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$`) + if !validHostname.MatchString(host) { + return types.ErrInvalidHost + } + + return nil +} + +// ValidatePort validates server port number +func (v *Validator) ValidatePort(port int) error { + if port <= 0 { + return types.ErrMissingPort + } + + if port < 1 || port > 65535 { + return types.ErrInvalidPort + } + + return nil +} + +// ValidateUsername validates SSH username +func (v *Validator) ValidateUsername(username string) error { + if username == "" { + return types.ErrMissingUsername + } + + // Basic username validation (alphanumeric, hyphens, underscores) + validUsername := regexp.MustCompile(`^[a-zA-Z0-9\-_]+$`) + if !validUsername.MatchString(username) { + return types.ErrMissingUsername + } + + return nil +} + +// ValidateSSHAuth validates SSH authentication methods for creation (requires auth) +func (v *Validator) ValidateSSHAuth(password *string, privateKeyPath *string) error { + hasPassword := password != nil && *password != "" + hasPrivateKey := privateKeyPath != nil && *privateKeyPath != "" + + // Must have exactly one authentication method + if !hasPassword && !hasPrivateKey { + return types.ErrMissingSSHAuth + } + + if hasPassword && hasPrivateKey { + return types.ErrBothSSHAuthProvided + } + + // Validate private key path if provided + if hasPrivateKey { + if !filepath.IsAbs(*privateKeyPath) { + return types.ErrInvalidSSHPrivateKeyPath + } + // Check file extension + ext := filepath.Ext(*privateKeyPath) + if ext != "" && !strings.Contains(".pem.key.ppk", ext) { + return types.ErrInvalidSSHPrivateKeyPath + } + } + + return nil +} + +// ValidateSSHAuthForUpdate validates SSH authentication methods for updates (optional) +func (v *Validator) ValidateSSHAuthForUpdate(password *string, privateKeyPath *string) error { + hasPassword := password != nil && *password != "" + hasPrivateKey := privateKeyPath != nil && *privateKeyPath != "" + + // In update mode, auth fields are optional - only validate if both are provided + if hasPassword && hasPrivateKey { + return types.ErrBothSSHAuthProvided + } + + // Validate private key path if provided + if hasPrivateKey { + if !filepath.IsAbs(*privateKeyPath) { + return types.ErrInvalidSSHPrivateKeyPath + } + // Check file extension + ext := filepath.Ext(*privateKeyPath) + if ext != "" && !strings.Contains(".pem.key.ppk", ext) { + return types.ErrInvalidSSHPrivateKeyPath + } + } + + return nil +} + +// ValidateRequest validates different server request types +func (v *Validator) ValidateRequest(req interface{}) error { + switch r := req.(type) { + case *types.CreateServerRequest: + return v.ValidateCreateServerRequest(*r) + case *types.UpdateServerRequest: + return v.ValidateUpdateServerRequest(*r) + case *types.UpdateServerStatusRequest: + return v.ValidateUpdateServerStatusRequest(*r) + case *types.DeleteServerRequest: + return v.ValidateDeleteServerRequest(*r) + default: + return types.ErrInvalidRequestType + } +} + +// ValidateCreateServerRequest validates server creation requests +func (v *Validator) ValidateCreateServerRequest(req types.CreateServerRequest) error { + if err := v.ValidateName(req.Name); err != nil { + return err + } + + if err := v.ValidateHost(req.Host); err != nil { + return err + } + + if err := v.ValidatePort(req.Port); err != nil { + return err + } + + if err := v.ValidateUsername(req.Username); err != nil { + return err + } + + if err := v.ValidateSSHAuth(req.SSHPassword, req.SSHPrivateKeyPath); err != nil { + return err + } + + return nil +} + +// ValidateUpdateServerRequest validates server update requests +func (v *Validator) ValidateUpdateServerRequest(req types.UpdateServerRequest) error { + if err := v.ValidateID(req.ID); err != nil { + return err + } + + if err := v.ValidateName(req.Name); err != nil { + return err + } + + if err := v.ValidateHost(req.Host); err != nil { + return err + } + + if err := v.ValidatePort(req.Port); err != nil { + return err + } + + if err := v.ValidateUsername(req.Username); err != nil { + return err + } + + if err := v.ValidateSSHAuthForUpdate(req.SSHPassword, req.SSHPrivateKeyPath); err != nil { + return err + } + + return nil +} + +// ValidateDeleteServerRequest validates server deletion requests +func (v *Validator) ValidateDeleteServerRequest(req types.DeleteServerRequest) error { + if err := v.ValidateID(req.ID); err != nil { + return err + } + + return nil +} + +func (v *Validator) ValidateUpdateServerStatusRequest(req types.UpdateServerStatusRequest) error { + if err := v.ValidateID(req.ID); err != nil { + return err + } + + if err := v.ValidateStatus(req.Status); err != nil { + return err + } + + return nil +} + +func (v *Validator) ValidateStatus(status string) error { + if status == "" { + return types.ErrMissingStatus + } + + validStatuses := []string{"active", "inactive", "maintenance"} + for _, validStatus := range validStatuses { + if status == validStatus { + return nil + } + } + + return types.ErrInvalidStatus +} diff --git a/api/internal/features/supertokens/auth.go b/api/internal/features/supertokens/auth.go index c31558cba..0d42bb17b 100644 --- a/api/internal/features/supertokens/auth.go +++ b/api/internal/features/supertokens/auth.go @@ -44,6 +44,7 @@ var ( "terminal:create", "terminal:read", "terminal:update", "terminal:delete", "feature_flags:read", "feature_flags:update", "dashboard:read", "extension:read", "extension:create", "extension:update", "extension:delete", + "server:create", "server:read", "server:update", "server:delete", } memberPermissions = []string{ @@ -58,11 +59,12 @@ var ( "feature_flags:read", "dashboard:read", "extension:read", + "server:read", } viewerPermissions = []string{ "user:read", "organization:read", "container:read", "audit:read", "domain:read", "notification:read", "file-manager:read", "deploy:read", "feature_flags:read", "dashboard:read", - "extension:read", + "extension:read", "server:read", } ) @@ -74,7 +76,7 @@ func Init(appInstance *storage.App) { websiteBasePath := "/auth" err := supertokens.Init(supertokens.TypeInput{ - Debug: true, + Debug: false, Supertokens: &supertokens.ConnectionInfo{ ConnectionURI: config.Supertokens.ConnectionURI, APIKey: config.Supertokens.APIKey, @@ -148,6 +150,11 @@ func Init(appInstance *storage.App) { if seedErr := seedDefaultRolesAndPermissions(); seedErr != nil { log.Printf("Failed to seed roles and permissions via SuperTokens: %v", seedErr) } + + // Ensure any existing roles are updated with newly added permissions + if syncErr := syncExistingRolesPermissions(); syncErr != nil { + log.Printf("Failed to sync existing SuperTokens roles with latest permissions: %v", syncErr) + } } // addRolesAndPermissionsToSession fetches and sets the user's roles and permissions claims in the session @@ -316,6 +323,7 @@ func createDefaultFeatureFlags(organizationID uuid.UUID, tx *bun.Tx) error { types.FeatureGithubConnector, types.FeatureMonitoring, types.FeatureContainer, + types.FeatureServers, } for _, feature := range defaultFeatures { @@ -399,3 +407,55 @@ func GetRolesAndPermissionsForUserInOrganization(userId, organizationId string) return orgRoles, allPermissions, nil } + +// syncExistingRolesPermissions updates global and organization scoped roles to include any newly added permissions +func syncExistingRolesPermissions() error { + rolesResponse, err := userroles.GetAllRoles(nil) + if err != nil { + return err + } + + for _, roleName := range rolesResponse.OK.Roles { + if roleName == "admin" { + if _, err := userroles.CreateNewRoleOrAddPermissions(roleName, GetAdminPermissions(), nil); err != nil { + log.Printf("sync roles: failed updating %s: %v", roleName, err) + } + continue + } + if roleName == "member" { + if _, err := userroles.CreateNewRoleOrAddPermissions(roleName, GetMemberPermissions(), nil); err != nil { + log.Printf("sync roles: failed updating %s: %v", roleName, err) + } + continue + } + if roleName == "viewer" { + if _, err := userroles.CreateNewRoleOrAddPermissions(roleName, GetViewerPermissions(), nil); err != nil { + log.Printf("sync roles: failed updating %s: %v", roleName, err) + } + continue + } + + if strings.HasPrefix(roleName, "orgid_") { + if strings.HasSuffix(roleName, "_admin") { + if _, err := userroles.CreateNewRoleOrAddPermissions(roleName, GetAdminPermissions(), nil); err != nil { + log.Printf("sync roles: failed updating %s: %v", roleName, err) + } + continue + } + if strings.HasSuffix(roleName, "_member") { + if _, err := userroles.CreateNewRoleOrAddPermissions(roleName, GetMemberPermissions(), nil); err != nil { + log.Printf("sync roles: failed updating %s: %v", roleName, err) + } + continue + } + if strings.HasSuffix(roleName, "_viewer") { + if _, err := userroles.CreateNewRoleOrAddPermissions(roleName, GetViewerPermissions(), nil); err != nil { + log.Printf("sync roles: failed updating %s: %v", roleName, err) + } + continue + } + } + } + + return nil +} diff --git a/api/internal/middleware/auth.go b/api/internal/middleware/auth.go index 7da2d9531..9fdf3f3fb 100644 --- a/api/internal/middleware/auth.go +++ b/api/internal/middleware/auth.go @@ -2,14 +2,15 @@ package middleware import ( "context" + "net/http" + "strings" + "github.com/raghavyuva/nixopus-api/internal/cache" user_storage "github.com/raghavyuva/nixopus-api/internal/features/auth/storage" "github.com/raghavyuva/nixopus-api/internal/storage" "github.com/raghavyuva/nixopus-api/internal/types" "github.com/raghavyuva/nixopus-api/internal/utils" "github.com/supertokens/supertokens-golang/recipe/session" - "net/http" - "strings" ) // AuthMiddleware is a middleware that checks if the request has a valid @@ -94,6 +95,23 @@ func AuthMiddleware(next http.Handler, app *storage.App, cache *cache.Cache) htt } ctx = context.WithValue(ctx, types.OrganizationIDKey, organizationID) + + // Handle X-Server-Id header if present (multi server setups) + serverID := r.Header.Get("X-Server-Id") + if serverID != "" { + server, err := utils.ValidateServerAccess(app.Store.DB, ctx, user.ID.String(), serverID) + if err != nil { + utils.SendErrorResponse(w, "Error verifying server access", http.StatusForbidden) + return + } + + if server == nil { + utils.SendErrorResponse(w, "Server not found", http.StatusNotFound) + return + } + + ctx = context.WithValue(ctx, types.ServerIDKey, server) + } } r = r.WithContext(ctx) diff --git a/api/internal/middleware/cors.go b/api/internal/middleware/cors.go index 03da17e4e..b11a05317 100644 --- a/api/internal/middleware/cors.go +++ b/api/internal/middleware/cors.go @@ -46,10 +46,10 @@ func CorsMiddleware(next http.Handler) http.Handler { } w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH") - w.Header().Set("Access-Control-Expose-Headers", "Authorization, X-Organization-Id") + w.Header().Set("Access-Control-Expose-Headers", "Authorization, X-Organization-Id, X-Server-Id") w.Header().Set("Access-Control-Allow-Credentials", "true") w.Header().Set("Access-Control-Max-Age", "300") - headers := []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Organization-Id"} + headers := []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Organization-Id", "X-Server-Id"} supertokensHeaders := supertokens.GetAllCORSHeaders() w.Header().Set("Access-Control-Allow-Headers", strings.Join(append(headers, supertokensHeaders...), ",")) diff --git a/api/internal/routes.go b/api/internal/routes.go index 3d8ca5b72..765dfaba8 100644 --- a/api/internal/routes.go +++ b/api/internal/routes.go @@ -39,6 +39,7 @@ import ( "github.com/raghavyuva/nixopus-api/internal/realtime" "github.com/raghavyuva/nixopus-api/internal/storage" api "github.com/raghavyuva/nixopus-api/internal/version-manager" + serverController "github.com/raghavyuva/nixopus-api/internal/features/servers/controller" ) type Router struct { @@ -277,6 +278,34 @@ func (router *Router) Routes() { }) router.ExtensionRoutes(extensionGroup, extensionController) + + serversController := serverController.NewServersController(router.app.Store, router.app.Ctx, l, notificationManager) + serverGroup := fuego.Group(server, apiV1.Path+"/server") + serversAllGroup := fuego.Group(server, apiV1.Path+"/servers") + fuego.Use(serverGroup, func(next http.Handler) http.Handler { + return middleware.RBACMiddleware(next, router.app, "server") + }) + fuego.Use(serversAllGroup, func(next http.Handler) http.Handler { + return middleware.RBACMiddleware(next, router.app, "server") + }) + fuego.Use(serverGroup, func(next http.Handler) http.Handler { + return middleware.FeatureFlagMiddleware(next, router.app, "server", router.cache) + }) + fuego.Use(serversAllGroup, func(next http.Handler) http.Handler { + return middleware.FeatureFlagMiddleware(next, router.app, "server", router.cache) + }) + fuego.Use(serverGroup, func(next http.Handler) http.Handler { + return middleware.AuditMiddleware(next, router.app, l, "server") + }) + fuego.Use(serversAllGroup, func(next http.Handler) http.Handler { + return middleware.AuditMiddleware(next, router.app, l, "server") + }) + fuego.Use(serversAllGroup, func(next http.Handler) http.Handler { + return middleware.AuditMiddleware(next, router.app, l, "server") + }) + router.ServerRoutes(serverGroup, serversController) + router.ServersRoutes(serversAllGroup, serversController) + log.Printf("Server starting on port %s", PORT) log.Printf("Swagger UI available at: http://localhost:%s/swagger/", PORT) server.Run() @@ -453,3 +482,15 @@ func (router *Router) OrganizationRoutes(f *fuego.Server, organizationController fuego.Post(f, "/invite/send", organizationController.SendInvite) fuego.Post(f, "/invite/resend", organizationController.ResendInvite) } + +func (router *Router) ServerRoutes(s *fuego.Server, serverController *serverController.ServersController) { + fuego.Post(s, "", serverController.CreateServer) + fuego.Get(s, "", serverController.GetServer) + fuego.Put(s, "", serverController.UpdateServer) + fuego.Patch(s, "/status", serverController.UpdateServerStatus) + fuego.Delete(s, "", serverController.DeleteServer) +} + +func (router *Router) ServersRoutes(s *fuego.Server, serverController *serverController.ServersController) { + fuego.Get(s, "", serverController.GetServers) +} \ No newline at end of file diff --git a/api/internal/types/domain.go b/api/internal/types/domain.go index b6e4414e8..1f8f66c33 100644 --- a/api/internal/types/domain.go +++ b/api/internal/types/domain.go @@ -1,8 +1,6 @@ package types import ( - "net" - "os" "time" "github.com/google/uuid" @@ -21,65 +19,21 @@ type Domain struct { } type Server struct { - bun.BaseModel `bun:"table:servers,alias:s" swaggerignore:"true"` - ID uuid.UUID `json:"id" bun:"id,pk,type:uuid"` - UserID uuid.UUID `json:"user_id" bun:"user_id,notnull,type:uuid"` - CreatedAt time.Time `json:"created_at" bun:"created_at,notnull,default:current_timestamp"` - UpdatedAt time.Time `json:"updated_at" bun:"updated_at,notnull,default:current_timestamp"` - DeletedAt *time.Time `json:"deleted_at,omitempty" bun:"deleted_at"` - Name string `json:"name" bun:"name,notnull"` - IP string `json:"ip" bun:"ip,notnull"` - Hostname string `json:"hostname" bun:"hostname,notnull"` -} - -func GetDefaultServer() Server { - ip := getHostIP() - - hostname, _ := os.Hostname() - - return Server{ - ID: uuid.UUID{}, - UserID: uuid.UUID{}, - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - DeletedAt: nil, - Name: "Default", - IP: ip, - Hostname: hostname, - } -} - -// this logic has to be rechecked for when app is running inside a docker container -func getHostIP() string { - interfaces, err := net.Interfaces() - if err != nil { - return "" - } - - for _, iface := range interfaces { - if iface.Flags&net.FlagLoopback != 0 || iface.Flags&net.FlagUp == 0 { - continue - } - addrs, err := iface.Addrs() - if err != nil { - continue - } - - for _, addr := range addrs { - var ip net.IP - switch v := addr.(type) { - case *net.IPNet: - ip = v.IP - case *net.IPAddr: - ip = v.IP - } - if ip == nil || ip.IsLoopback() || ip.To4() == nil { - continue - } - - return ip.String() - } - } - - return "" + bun.BaseModel `bun:"table:servers,alias:s" swaggerignore:"true"` + ID uuid.UUID `json:"id" bun:"id,pk,type:uuid"` + Name string `json:"name" bun:"name,notnull"` + Description string `json:"description" bun:"description"` + Host string `json:"host" bun:"host,notnull"` + Port int `json:"port" bun:"port,notnull"` + Username string `json:"username" bun:"username,notnull"` + SSHPassword *string `json:"ssh_password,omitempty" bun:"ssh_password"` + SSHPrivateKeyPath *string `json:"ssh_private_key_path,omitempty" bun:"ssh_private_key_path"` + Status string `json:"status" bun:"status,notnull,default:'inactive'"` + CreatedAt time.Time `json:"created_at" bun:"created_at,notnull,default:current_timestamp"` + UpdatedAt time.Time `json:"updated_at" bun:"updated_at,notnull,default:current_timestamp"` + DeletedAt *time.Time `json:"deleted_at,omitempty" bun:"deleted_at"` + UserID uuid.UUID `json:"user_id" bun:"user_id,notnull,type:uuid"` + OrganizationID uuid.UUID `json:"organization_id" bun:"organization_id,notnull,type:uuid"` + User *User `json:"user,omitempty" bun:"rel:belongs-to,join:user_id=id"` + Organization *Organization `json:"organization,omitempty" bun:"rel:belongs-to,join:organization_id=id"` } diff --git a/api/internal/types/feature_flags.go b/api/internal/types/feature_flags.go index d17216e4c..ffad62736 100644 --- a/api/internal/types/feature_flags.go +++ b/api/internal/types/feature_flags.go @@ -33,6 +33,7 @@ const ( FeatureDomain FeatureName = "domain" FeatureSelfHosted FeatureName = "self_hosted" FeatureContainer FeatureName = "container" + FeatureServers FeatureName = "servers" ) type UpdateFeatureFlagRequest struct { diff --git a/api/internal/types/types.go b/api/internal/types/types.go index 0ec4354a9..299ea895f 100644 --- a/api/internal/types/types.go +++ b/api/internal/types/types.go @@ -80,6 +80,7 @@ const UserContextKey contextKey = "user" const AuthTokenKey ClientContext = "auth_token" const DBContextKey ClientContext = "db" const OrganizationIDKey contextKey = "organization_id" +const ServerIDKey contextKey = "server_id" type AvailableActions string @@ -103,6 +104,7 @@ type Payload struct { var JWTSecretKey = []byte("secret-key") + type ValidationError struct { Field string `json:"field"` Message string `json:"message"` diff --git a/api/internal/utils/server.go b/api/internal/utils/server.go new file mode 100644 index 000000000..7405623dc --- /dev/null +++ b/api/internal/utils/server.go @@ -0,0 +1,82 @@ +package utils + +import ( + "context" + "errors" + "net/http" + + "github.com/google/uuid" + server_storage "github.com/raghavyuva/nixopus-api/internal/features/servers/storage" + "github.com/raghavyuva/nixopus-api/internal/types" + "github.com/uptrace/bun" +) + +// ValidateServerAccess checks if a user has access to a specific server and returns the server details +func ValidateServerAccess(db *bun.DB, ctx context.Context, userID, serverID string) (*types.Server, error) { + if serverID == "" { + return nil, nil + } + + _, err := uuid.Parse(serverID) + if err != nil { + return nil, err + } + + userUUID, err := uuid.Parse(userID) + if err != nil { + return nil, err + } + + serverStorage := server_storage.ServerStorage{ + DB: db, + Ctx: ctx, + } + + server, err := serverStorage.GetServer(serverID) + if err != nil { + return nil, err + } + + if server == nil { + return nil, errors.New("server not found") + } + + if server.UserID != userUUID { + return nil, errors.New("user does not have access to this server") + } + + return server, nil +} + +// GetServerDetails extracts server details from request context +func GetServerDetailsWithErr(r *http.Request) (*types.Server, error) { + serverAny := r.Context().Value(types.ServerIDKey) + server, ok := serverAny.(*types.Server) + + if !ok { + return nil, errors.New("server details not found") + } + + return server, nil +} + +// GetServer retrieves the current server from the request context (similar to GetUser pattern) +func GetServer(w http.ResponseWriter, r *http.Request) *types.Server { + serverAny := r.Context().Value(types.ServerIDKey) + server, ok := serverAny.(*types.Server) + + if !ok { + return nil + } + + return server +} + +// GetServerID extracts server ID from request context +func GetServerID(r *http.Request) string { + server, err := GetServerDetailsWithErr(r) + if err != nil || server == nil { + return "" + } + return server.ID.String() +} diff --git a/api/migrations/servers/033_create_servers_down.sql b/api/migrations/servers/033_create_servers_down.sql new file mode 100644 index 000000000..47575c262 --- /dev/null +++ b/api/migrations/servers/033_create_servers_down.sql @@ -0,0 +1,15 @@ +DROP TRIGGER IF EXISTS trigger_ensure_single_active_server ON servers; +DROP FUNCTION IF EXISTS ensure_single_active_server(); + +DROP INDEX IF EXISTS idx_servers_org_status; +DROP INDEX IF EXISTS idx_servers_status; +DROP INDEX IF EXISTS idx_servers_active_per_org; +ALTER TABLE IF EXISTS servers DROP CONSTRAINT IF EXISTS check_server_status; + +DROP INDEX IF EXISTS idx_servers_org_host_port_unique; +DROP INDEX IF EXISTS idx_servers_org_name_unique; +DROP INDEX IF EXISTS idx_servers_organization_id; +DROP INDEX IF EXISTS idx_servers_user_id; + +DROP TABLE IF EXISTS servers; +DROP FUNCTION IF EXISTS generate_server_name(); diff --git a/api/migrations/servers/033_create_servers_up.sql b/api/migrations/servers/033_create_servers_up.sql new file mode 100644 index 000000000..6667ddb34 --- /dev/null +++ b/api/migrations/servers/033_create_servers_up.sql @@ -0,0 +1,74 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +CREATE OR REPLACE FUNCTION generate_server_name() RETURNS VARCHAR(255) AS $$ +DECLARE + prefixes TEXT[] := ARRAY['web', 'api', 'db', 'app', 'srv', 'node', 'host', 'prod', 'dev', 'stage']; + suffixes TEXT[] := ARRAY['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', 'iota', 'kappa']; + numbers TEXT[] := ARRAY['01', '02', '03', '04', '05', '06', '07', '08', '09', '10']; + prefix TEXT; + suffix TEXT; + number TEXT; +BEGIN + prefix := prefixes[1 + floor(random() * array_length(prefixes, 1))::int]; + suffix := suffixes[1 + floor(random() * array_length(suffixes, 1))::int]; + number := numbers[1 + floor(random() * array_length(numbers, 1))::int]; + RETURN prefix || '-' || suffix || '-' || number; +END; +$$ LANGUAGE plpgsql; + +CREATE TABLE servers ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + name VARCHAR(255) NOT NULL DEFAULT generate_server_name(), + description TEXT DEFAULT 'Auto Generated Server', + host VARCHAR(255) NOT NULL DEFAULT 'localhost', + port INT NOT NULL DEFAULT 22, + username VARCHAR(255) NOT NULL DEFAULT 'root', + ssh_password VARCHAR(255), + ssh_private_key_path VARCHAR(255), + status VARCHAR(50) NOT NULL DEFAULT 'inactive', + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP WITH TIME ZONE, + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, + CONSTRAINT ssh_auth_check CHECK ( + (ssh_password IS NOT NULL AND ssh_private_key_path IS NULL) OR + (ssh_password IS NULL AND ssh_private_key_path IS NOT NULL) + ), + CONSTRAINT check_server_status CHECK (status IN ('active', 'inactive', 'maintenance')) +); + +CREATE INDEX idx_servers_user_id ON servers(user_id); +CREATE INDEX idx_servers_organization_id ON servers(organization_id); +CREATE UNIQUE INDEX idx_servers_org_name_unique + ON servers(organization_id, name) + WHERE deleted_at IS NULL; +CREATE UNIQUE INDEX idx_servers_org_host_port_unique + ON servers(organization_id, host, port) + WHERE deleted_at IS NULL; + +CREATE UNIQUE INDEX idx_servers_active_per_org +ON servers(organization_id) +WHERE status = 'active' AND deleted_at IS NULL; + +CREATE OR REPLACE FUNCTION ensure_single_active_server() RETURNS TRIGGER AS $$ +BEGIN + IF NEW.status = 'active' AND NEW.deleted_at IS NULL THEN + UPDATE servers + SET status = 'inactive', updated_at = CURRENT_TIMESTAMP + WHERE organization_id = NEW.organization_id + AND id != NEW.id + AND status = 'active' + AND deleted_at IS NULL; + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER trigger_ensure_single_active_server + BEFORE INSERT OR UPDATE ON servers + FOR EACH ROW + EXECUTE FUNCTION ensure_single_active_server(); + +CREATE INDEX idx_servers_status ON servers(status) WHERE deleted_at IS NULL; +CREATE INDEX idx_servers_org_status ON servers(organization_id, status) WHERE deleted_at IS NULL; diff --git a/view/app/settings/servers/components/create-server.tsx b/view/app/settings/servers/components/create-server.tsx new file mode 100644 index 000000000..7dc04c62a --- /dev/null +++ b/view/app/settings/servers/components/create-server.tsx @@ -0,0 +1,81 @@ +'use client'; +import React from 'react'; +import { + Form, +} from '@/components/ui/form'; +import { Button } from '@/components/ui/button'; +import { Server } from '@/redux/types/server'; +import { Plus } from 'lucide-react'; +import { useServerForm } from '@/app/settings/servers/hooks/use-server-form'; +import { DialogWrapper } from '@/components/ui/dialog-wrapper'; +import ServerFormFields from './server-form-fields'; + +interface CreateServerDialogProps { + open?: boolean; + setOpen?: (open: boolean) => void; + serverId?: string; + serverData?: Server; + mode?: 'create' | 'edit'; +} + +function CreateServerDialog({ open, setOpen, serverId, serverData, mode = 'create' }: CreateServerDialogProps) { + const { t, form, authType, setAuthType, isEditMode, isLoading, onSubmit } = useServerForm({ + mode, + serverData, + serverId, + onSuccess: () => { + setOpen?.(false); + } + }); + + const actions = [ + { + label: t('servers.create.dialog.buttons.cancel'), + onClick: () => { + form.reset(); + setOpen?.(false); + }, + variant: 'outline' as const + }, + { + label: isLoading + ? (isEditMode ? t('servers.create.dialog.buttons.updating') : t('servers.create.dialog.buttons.creating')) + : (isEditMode ? t('servers.create.dialog.buttons.update') : t('servers.create.dialog.buttons.create')), + onClick: () => form.handleSubmit(onSubmit)(), + disabled: isLoading, + loading: isLoading + } + ]; + + return ( + + + {t('servers.create.button')} + + ) : undefined} + actions={actions} + size="lg" + contentClassName="max-h-[90vh] overflow-y-auto" + > +
+ { e.preventDefault(); }}> + + + +
+ ); +} + +export default CreateServerDialog; diff --git a/view/app/settings/servers/components/server-form-fields.tsx b/view/app/settings/servers/components/server-form-fields.tsx new file mode 100644 index 000000000..0cee5892b --- /dev/null +++ b/view/app/settings/servers/components/server-form-fields.tsx @@ -0,0 +1,146 @@ +import React from 'react'; +import { Label } from '@/components/ui/label'; +import { AuthenticationType } from '@/redux/types/server'; +import FormInputField from '@/components/ui/form-input-field'; +import FormTextareaField from '@/components/ui/form-textarea-field'; + +interface ServerFormFieldsProps { + form: any; + t: (key: any) => string; + authType: AuthenticationType; + setAuthType: (type: AuthenticationType) => void; + isEditMode: boolean; +} + +export function ServerFormFields({ form, t, authType, setAuthType, isEditMode }: ServerFormFieldsProps) { + const inputFields = [ + { + name: 'name', + label: t('servers.create.dialog.fields.name.label'), + placeholder: t('servers.create.dialog.fields.name.placeholder') + }, + { + name: 'username', + label: t('servers.create.dialog.fields.username.label'), + placeholder: t('servers.create.dialog.fields.username.placeholder') + } + ]; + + const gridFields = [ + { + name: 'host', + label: t('servers.create.dialog.fields.host.label'), + placeholder: t('servers.create.dialog.fields.host.placeholder') + }, + { + name: 'port', + label: t('servers.create.dialog.fields.port.label'), + placeholder: t('servers.create.dialog.fields.port.placeholder'), + type: 'number' as const, + onValueChange: (v: string) => parseInt(v) || 22 + } + ]; + + const descriptionField = { + name: 'description', + label: t('servers.create.dialog.fields.description.label'), + placeholder: t('servers.create.dialog.fields.description.placeholder') + }; + + const authField = + authType === AuthenticationType.PASSWORD + ? { + name: 'ssh_password', + label: t('servers.create.dialog.fields.sshPassword.label'), + placeholder: isEditMode + ? 'Leave empty to keep current password' + : t('servers.create.dialog.fields.sshPassword.placeholder'), + type: 'password' as const, + required: false + } + : { + name: 'ssh_private_key_path', + label: t('servers.create.dialog.fields.privateKeyPath.label'), + placeholder: isEditMode + ? 'Leave empty to keep current private key path' + : t('servers.create.dialog.fields.privateKeyPath.placeholder'), + required: false + }; + + return ( + <> + {inputFields.map((cfg) => ( + + ))} + + + +
+ {gridFields.map((cfg) => ( + + ))} +
+ +
+ +
+
+ setAuthType(e.target.value as AuthenticationType)} + className="h-4 w-4 text-primary focus:ring-primary border-input" + /> + +
+
+ setAuthType(e.target.value as AuthenticationType)} + className="h-4 w-4 text-primary focus:ring-primary border-input" + /> + +
+
+ + +
+ + ); +} + +export default ServerFormFields; diff --git a/view/app/settings/servers/components/servers-table-skeleton.tsx b/view/app/settings/servers/components/servers-table-skeleton.tsx new file mode 100644 index 000000000..15e847718 --- /dev/null +++ b/view/app/settings/servers/components/servers-table-skeleton.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { useTranslation } from '@/hooks/use-translation'; +import { DataTable, TableColumn } from '@/components/ui/data-table'; +import type { Server } from '@/redux/types/server'; + +function ServersTableSkeleton() { + const { t } = useTranslation(); + + const columns: TableColumn[] = [ + { key: 'name', title: t('servers.table.headers.name') }, + { key: 'host', title: t('servers.table.headers.host') }, + { key: 'port', title: t('servers.table.headers.port') }, + { key: 'username', title: t('servers.table.headers.username') }, + { key: 'created_at', title: t('servers.table.headers.created') }, + { key: 'actions', title: '', width: '70px', align: 'right' } + ]; + + return ( + + data={[]} + columns={columns} + loading={true} + loadingRows={5} + showBorder + /> + ); +} + +export default ServersTableSkeleton; diff --git a/view/app/settings/servers/components/servers-table.tsx b/view/app/settings/servers/components/servers-table.tsx new file mode 100644 index 000000000..003d3d352 --- /dev/null +++ b/view/app/settings/servers/components/servers-table.tsx @@ -0,0 +1,121 @@ +'use client'; +import React from 'react'; +import { Server as ServerIcon, Trash2 } from 'lucide-react'; +import { Server, Pagination, GetServersRequest } from '@/redux/types/server'; +import { useTranslation } from '@/hooks/use-translation'; +import ServersTableSkeleton from '@/app/settings/servers/components/servers-table-skeleton'; +import { DeleteDialog } from '@/components/ui/delete-dialog'; +import { DahboardUtilityHeader } from '@/components/layout/dashboard-page-header'; +import PaginationWrapper from '@/components/ui/pagination'; +import { SelectWrapper } from '@/components/ui/select-wrapper'; +import { DataTable } from '@/components/ui/data-table'; +import useServersTable from '@/app/settings/servers/hooks/use-servers-table'; +import { ResourceGuard } from '@/components/rbac/PermissionGuard'; +import CreateServerDialog from '@/app/settings/servers/components/create-server'; + +interface ServersTableProps { + servers: Server[]; + pagination?: Pagination; + isLoading: boolean; + queryParams: GetServersRequest; + onQueryChange: (params: Partial) => void; + onEditServer: (server: Server) => void; + createDialogOpen: boolean; + setCreateDialogOpen: (open: boolean) => void; +} + +function ServersTable({ servers, pagination, isLoading, queryParams, onQueryChange, onEditServer, createDialogOpen, setCreateDialogOpen }: ServersTableProps) { + const { t } = useTranslation(); + const { + columns, + headerSortConfig, + sortOptions, + deleteDialogOpen, + setDeleteDialogOpen, + serverToDelete, + deletingId, + handleDeleteClick, + handleDeleteConfirm, + handleSearchChange, + handleSortChange, + handlePageSizeChange, + handlePageChange + } = useServersTable({ queryParams, onQueryChange, onEditServer }); + + if (isLoading) { + return ; + } + + return ( +
+ + searchTerm={queryParams.search || ''} + handleSearchChange={handleSearchChange} + sortConfig={headerSortConfig as any} + onSortChange={handleSortChange} + sortOptions={sortOptions} + label={t('servers.page.title')} + searchPlaceHolder={t('servers.table.search.placeholder')} + > +
+ {t('servers.table.pagination.itemsPerPage')} + + + + +
+ + + + data={servers || []} + columns={columns} + loading={false} + emptyStateComponent={ +
+ +

{t('servers.table.empty.noServers.title')}

+

{t('servers.table.empty.noServers.description')}

+
+ } + showBorder + /> + + {pagination && pagination.total_pages > 1 && ( +
+ +
+ )} + + +
+ ); +} + +export default ServersTable; diff --git a/view/app/settings/servers/hooks/use-server-form.ts b/view/app/settings/servers/hooks/use-server-form.ts new file mode 100644 index 000000000..fe76f074c --- /dev/null +++ b/view/app/settings/servers/hooks/use-server-form.ts @@ -0,0 +1,191 @@ +import React, { useEffect, useState } from 'react'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { useCreateServerMutation, useUpdateServerMutation } from '@/redux/services/settings/serversApi'; +import { AuthenticationType, Server } from '@/redux/types/server'; +import { useTranslation } from '@/hooks/use-translation'; +import { toast } from 'sonner'; + +type Mode = 'create' | 'edit'; + +interface UseServerFormParams { + mode?: Mode; + serverData?: Server; + serverId?: string; + onSuccess?: () => void; +} + +export function useServerForm({ mode = 'create', serverData, serverId, onSuccess }: UseServerFormParams) { + const { t } = useTranslation(); + const [createServer, { isLoading: isCreating }] = useCreateServerMutation(); + const [updateServer, { isLoading: isUpdating }] = useUpdateServerMutation(); + + const isEditMode = mode === 'edit'; + const isLoading = isCreating || isUpdating; + + const [authType, setAuthType] = useState(() => { + if (isEditMode && serverData) { + return serverData.ssh_password ? AuthenticationType.PASSWORD : AuthenticationType.PRIVATE_KEY; + } + return AuthenticationType.PASSWORD; + }); + + const baseServerSchema = z.object({ + name: z + .string() + .min(2, { message: t('servers.create.dialog.validation.nameRequired') }) + .max(255, { message: t('servers.create.dialog.validation.nameMaxLength') }), + description: z + .string() + .max(500, { message: t('servers.create.dialog.validation.descriptionMaxLength') }) + .optional(), + host: z + .string() + .min(1, { message: t('servers.create.dialog.validation.hostRequired') }) + .refine( + (host) => { + const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; + const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/; + return ipRegex.test(host) || hostnameRegex.test(host); + }, + { message: t('servers.create.dialog.validation.invalidHost') } + ), + port: z + .number() + .min(1, { message: t('servers.create.dialog.validation.portRange') }) + .max(65535, { message: t('servers.create.dialog.validation.portRange') }), + username: z + .string() + .min(1, { message: t('servers.create.dialog.validation.usernameRequired') }) + .regex(/^[a-zA-Z0-9\-_]+$/, { message: t('servers.create.dialog.validation.usernameInvalid') }), + ssh_password: z.string().optional(), + ssh_private_key_path: z.string().optional() + }); + + const createServerSchema = baseServerSchema.refine((data) => { + if (authType === AuthenticationType.PASSWORD) { + return data.ssh_password && data.ssh_password.length > 0; + } else { + return data.ssh_private_key_path && data.ssh_private_key_path.length > 0; + } + }, { + message: t('servers.create.dialog.validation.authRequired'), + path: authType === AuthenticationType.PASSWORD ? ['ssh_password'] : ['ssh_private_key_path'] + }); + + const editServerSchema = baseServerSchema.refine((data) => { + if (authType === AuthenticationType.PASSWORD && data.ssh_password) { + return data.ssh_password.length > 0; + } + if (authType === AuthenticationType.PRIVATE_KEY && data.ssh_private_key_path) { + return data.ssh_private_key_path.length > 0; + } + return true; + }, { + message: t('servers.create.dialog.validation.authRequired'), + path: authType === AuthenticationType.PASSWORD ? ['ssh_password'] : ['ssh_private_key_path'] + }); + + const serverFormSchema = isEditMode ? editServerSchema : createServerSchema; + + const form = useForm({ + resolver: zodResolver(serverFormSchema), + defaultValues: { + name: serverData?.name || '', + description: serverData?.description || '', + host: serverData?.host || '', + port: serverData?.port || 22, + username: serverData?.username || '', + ssh_password: '', + ssh_private_key_path: serverData?.ssh_private_key_path || '' + } + }); + + useEffect(() => { + if (serverData) { + form.reset({ + name: serverData.name, + description: serverData.description, + host: serverData.host, + port: serverData.port, + username: serverData.username, + ssh_password: '', + ssh_private_key_path: serverData.ssh_private_key_path || '' + }); + setAuthType(serverData.ssh_password ? AuthenticationType.PASSWORD : AuthenticationType.PRIVATE_KEY); + } else { + form.reset({ + name: '', + description: '', + host: '', + port: 22, + username: '', + ssh_password: '', + ssh_private_key_path: '' + }); + setAuthType(AuthenticationType.PASSWORD); + } + }, [serverData, form]); + + async function onSubmit(formData: z.infer) { + try { + const baseRequestData = { + name: formData.name, + description: formData.description || '', + host: formData.host, + port: formData.port, + username: formData.username + }; + + let requestData: any; + + if (isEditMode) { + requestData = { ...baseRequestData } as any; + if (authType === AuthenticationType.PASSWORD && formData.ssh_password) { + (requestData as any).ssh_password = formData.ssh_password; + } + if (authType === AuthenticationType.PRIVATE_KEY && formData.ssh_private_key_path) { + (requestData as any).ssh_private_key_path = formData.ssh_private_key_path; + } + } else { + requestData = { + ...baseRequestData, + ...(authType === AuthenticationType.PASSWORD + ? { ssh_password: formData.ssh_password } + : { ssh_private_key_path: formData.ssh_private_key_path }) + }; + } + + if (isEditMode && serverId) { + await updateServer({ id: serverId, ...requestData }).unwrap(); + toast.success(t('servers.messages.updateSuccess')); + } else { + await createServer(requestData).unwrap(); + toast.success(t('servers.messages.createSuccess')); + } + + form.reset(); + onSuccess?.(); + } catch (e) { + if (isEditMode) { + toast.error(t('servers.messages.updateError')); + } else { + toast.error(t('servers.messages.createError')); + } + } + } + + return { + t, + form, + authType, + setAuthType, + isEditMode, + isLoading, + onSubmit + }; +} + +export default useServerForm; + diff --git a/view/app/settings/servers/hooks/use-servers-table.tsx b/view/app/settings/servers/hooks/use-servers-table.tsx new file mode 100644 index 000000000..6f192d214 --- /dev/null +++ b/view/app/settings/servers/hooks/use-servers-table.tsx @@ -0,0 +1,175 @@ +'use client'; +import React, { useMemo, useState } from 'react'; +import { useTranslation } from '@/hooks/use-translation'; +import { formatDistanceToNow } from 'date-fns'; +import { useDeleteServerMutation } from '@/redux/services/settings/serversApi'; +import { Server, GetServersRequest } from '@/redux/types/server'; +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; +import { TableColumn } from '@/components/ui/data-table'; +import { Edit, MoreHorizontal, Trash2 } from 'lucide-react'; +import { toast } from 'sonner'; +import { SortOption } from '@/components/ui/sort-selector'; + +export interface UseServersTableArgs { + queryParams: GetServersRequest; + onQueryChange: (params: Partial) => void; + onEditServer: (server: Server) => void; +} + +export function useServersTable({ queryParams, onQueryChange, onEditServer }: UseServersTableArgs) { + const { t } = useTranslation(); + const [deleteServer] = useDeleteServerMutation(); + const [deletingId, setDeletingId] = useState(null); + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); + const [serverToDelete, setServerToDelete] = useState(null); + + const sortOptions: SortOption[] = [ + { value: 'name', label: t('servers.table.sort.name_asc'), direction: 'asc' }, + { value: 'name', label: t('servers.table.sort.name_desc'), direction: 'desc' }, + { value: 'host', label: t('servers.table.sort.host_asc'), direction: 'asc' }, + { value: 'host', label: t('servers.table.sort.host_desc'), direction: 'desc' }, + { value: 'port', label: t('servers.table.sort.port_asc'), direction: 'asc' }, + { value: 'port', label: t('servers.table.sort.port_desc'), direction: 'desc' }, + { value: 'username', label: t('servers.table.sort.username_asc'), direction: 'asc' }, + { value: 'username', label: t('servers.table.sort.username_desc'), direction: 'desc' }, + { value: 'created_at', label: t('servers.table.sort.created_newest'), direction: 'desc' }, + { value: 'created_at', label: t('servers.table.sort.created_oldest'), direction: 'asc' } + ]; + + const headerSortConfig = useMemo( + () => ({ + key: (queryParams.sort_by as keyof Server) ?? ('created_at' as keyof Server), + direction: (queryParams.sort_order as 'asc' | 'desc') ?? 'desc' + }), + [queryParams.sort_by, queryParams.sort_order] + ); + + const handleDeleteClick = (server: Server) => { + setServerToDelete(server); + setDeleteDialogOpen(true); + }; + + const handleDeleteConfirm = async () => { + if (!serverToDelete) return; + try { + setDeletingId(serverToDelete.id); + await deleteServer({ id: serverToDelete.id }).unwrap(); + toast.success(t('servers.messages.deleteSuccess')); + setDeleteDialogOpen(false); + setServerToDelete(null); + } catch (error) { + toast.error(t('servers.messages.deleteError')); + } finally { + setDeletingId(null); + } + }; + + const handleSearchChange = (e: React.ChangeEvent) => { + onQueryChange({ search: e.target.value, page: 1 }); + }; + + const handleSortChange = (newSortOption: SortOption) => { + onQueryChange({ sort_by: newSortOption.value as string, sort_order: newSortOption.direction, page: 1 }); + }; + + const handlePageSizeChange = (newPageSize: string) => { + onQueryChange({ page_size: Number(newPageSize), page: 1 }); + }; + + const handlePageChange = (newPage: number) => { + onQueryChange({ page: newPage }); + }; + + const columns: TableColumn[] = useMemo( + () => [ + { + key: 'name', + title: t('servers.table.headers.name'), + render: (_, record) => ( +
+
{record.name}
+ {record.description ? ( +
{record.description}
+ ) : null} +
+ ) + }, + { + key: 'host', + title: t('servers.table.headers.host'), + render: (_, record) => {record.host} + }, + { + key: 'port', + title: t('servers.table.headers.port'), + render: (_, record) => {record.port} + }, + { + key: 'username', + title: t('servers.table.headers.username'), + render: (_, record) => {record.username} + }, + { + key: 'created_at', + title: t('servers.table.headers.created'), + render: (_, record) => ( + + {formatDistanceToNow(new Date(record.created_at), { addSuffix: true })} + + ) + }, + { + key: 'actions', + title: '', + width: '70px', + align: 'right', + render: (_, record) => ( + + + + + + onEditServer(record)}> + + {t('servers.actions.edit')} + + handleDeleteClick(record)} + disabled={deletingId === record.id} + > + + {deletingId === record.id ? t('servers.actions.deleting') : t('servers.actions.delete')} + + + + ) + } + ], + [t, deletingId, onEditServer] + ); + + return { + columns, + headerSortConfig, + sortOptions, + deleteDialogOpen, + setDeleteDialogOpen, + serverToDelete, + deletingId, + handleDeleteClick, + handleDeleteConfirm, + handleSearchChange, + handleSortChange, + handlePageSizeChange, + handlePageChange + }; +} + +export type UseServersTableReturn = ReturnType; + +export default useServersTable; diff --git a/view/app/settings/servers/hooks/use-servers.ts b/view/app/settings/servers/hooks/use-servers.ts new file mode 100644 index 000000000..0de03643d --- /dev/null +++ b/view/app/settings/servers/hooks/use-servers.ts @@ -0,0 +1,51 @@ +import { useState } from 'react'; +import { useGetAllServersQuery } from '@/redux/services/settings/serversApi'; +import { GetServersRequest, Server } from '@/redux/types/server'; + +export function useServers() { + const [createDialogOpen, setCreateDialogOpen] = useState(false); + const [editDialogOpen, setEditDialogOpen] = useState(false); + const [editingServer, setEditingServer] = useState(null); + const [queryParams, setQueryParams] = useState({ + page: 1, + page_size: 10, + search: '', + sort_by: 'created_at', + sort_order: 'desc' + }); + + const { data: serverResponse, isLoading, error } = useGetAllServersQuery(queryParams); + + const handleQueryChange = (newParams: Partial) => { + setQueryParams(prev => ({ ...prev, ...newParams })); + }; + + const handleEditServer = (server: Server) => { + setEditingServer(server); + setEditDialogOpen(true); + }; + + const handleEditDialogClose = () => { + setEditDialogOpen(false); + setEditingServer(null); + }; + + return { + createDialogOpen, + setCreateDialogOpen, + editDialogOpen, + setEditDialogOpen, + editingServer, + setEditingServer, + queryParams, + setQueryParams, + serverResponse, + isLoading, + error, + handleQueryChange, + handleEditServer, + handleEditDialogClose + }; +} + +export default useServers; diff --git a/view/app/settings/servers/page.tsx b/view/app/settings/servers/page.tsx index b54602a79..aa74f62bd 100644 --- a/view/app/settings/servers/page.tsx +++ b/view/app/settings/servers/page.tsx @@ -1,16 +1,88 @@ 'use client'; import React from 'react'; import DashboardPageHeader from '@/components/layout/dashboard-page-header'; +import { ResourceGuard } from '@/components/rbac/PermissionGuard'; +import { Skeleton } from '@/components/ui/skeleton'; +import { useTranslation } from '@/hooks/use-translation'; +import CreateServerDialog from '@/app/settings/servers/components/create-server'; +import ServersTable from '@/app/settings/servers/components/servers-table'; +import useServers from '@/app/settings/servers/hooks/use-servers'; function Page() { + const { t } = useTranslation(); + const { + createDialogOpen, + setCreateDialogOpen, + editDialogOpen, + setEditDialogOpen, + editingServer, + setEditingServer, + queryParams, + serverResponse, + isLoading, + error, + handleQueryChange, + handleEditServer, + handleEditDialogClose + } = useServers(); + return ( -
- -
+ <> + } + > +
+
+ {error ? ( +
+

{t('servers.page.error')}

+
+ ) : ( + + )} +
+ + + + + { + setEditDialogOpen(open); + if (!open) setEditingServer(null); + }} + mode="edit" + serverId={editingServer?.id} + serverData={editingServer || undefined} + /> + +
+
+ ); } -export default Page; +export default Page; \ No newline at end of file diff --git a/view/components/layout/dashboard-layout.tsx b/view/components/layout/dashboard-layout.tsx index 21fa9edd5..5759c1567 100644 --- a/view/components/layout/dashboard-layout.tsx +++ b/view/components/layout/dashboard-layout.tsx @@ -26,6 +26,7 @@ import { AnyPermissionGuard } from '@/components/rbac/PermissionGuard'; import { ModeToggler } from '@/components/ui/theme-toggler'; import { RBACGuard } from '@/components/rbac/RBACGuard'; import { TopbarWidgets } from './topbar-widgets'; +import { ServerSelector } from './server-selector'; enum TERMINAL_POSITION { BOTTOM = 'bottom', @@ -98,6 +99,9 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
+ + +
- + { + const value = e.target.value; + const transformed = onValueChange ? onValueChange(value) : value; + field.onChange(transformed); + }} + /> {description && {description}} diff --git a/view/components/ui/form-textarea-field.tsx b/view/components/ui/form-textarea-field.tsx new file mode 100644 index 000000000..c38c4e512 --- /dev/null +++ b/view/components/ui/form-textarea-field.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { + FormControl, + FormDescription, + FormItem, + FormLabel, + FormMessage, + FormField +} from '@/components/ui/form'; + +interface FormTextareaFieldProps { + form: any; + label: string; + name: string; + description?: string; + placeholder?: string; + required?: boolean; + rows?: number; +} + +function FormTextareaField({ + form, + label, + name, + description, + placeholder, + required = true, + rows = 4 +}: FormTextareaFieldProps) { + return ( + ( + +
+ {label && {label}} + + {required ? '*' : ''} + +
+ +