From 4c91d0c15078827f44e6262b30e48fb3895fdb66 Mon Sep 17 00:00:00 2001 From: ZigBalthazar Date: Sun, 12 Jan 2025 00:24:47 +0330 Subject: [PATCH] chore: init --- README.md | 24 +--- cmd/commands/run.go | 6 +- cmd/commands/utils.go | 2 +- cmd/daemon/daemon.go | 24 ++-- cmd/main.go | 4 +- config/config.go | 12 +- .../grpc/buf/buf.gen.yaml | 0 {delivery => deliveries}/grpc/config.go | 0 .../grpc/gen/health.pb.go | 0 .../grpc/gen/health_grpc.pb.go | 0 {delivery => deliveries}/grpc/health.go | 4 +- .../grpc/proto/health.proto | 0 {delivery => deliveries}/grpc/server.go | 6 +- {delivery => deliveries}/http/config.go | 0 .../http/handlers/.gitkeep | 0 .../handlers/domain_handler/domain_create.go | 49 +++++++ .../domain_handler/dto/domain_request.go | 8 ++ .../domain_handler/dto/domain_response.go | 5 + .../http/handlers/domain_handler/handler.go | 13 ++ .../http/handlers/domain_handler/router.go | 11 ++ deliveries/http/http_handlers.go | 33 +++++ deliveries/http/http_server.go | 45 ++++++ .../http/middlewares}/auth.go | 0 deliveries/http/response.go | 7 + delivery/http/server.go | 42 ------ delivery/http/user_handler/handler.go | 13 -- delivery/http/user_handler/profile.go | 19 --- delivery/http/user_handler/router.go | 13 -- docs/docs.go | 135 ++++++++++++++++++ docs/swagger.json | 111 ++++++++++++++ docs/swagger.yaml | 77 ++++++++++ entity/user.go | 6 - go.mod | 34 ++++- go.sum | 52 +++++++ .../database/config.go | 0 .../database/database.go | 0 .../grpc_client/buf/buf.gen.yaml | 0 .../grpc_client/client.go | 2 +- .../grpc_client/config.go | 0 .../grpc_client/gen/example.pb.go | 0 .../grpc_client/gen/example_grpc.pb.go | 0 .../grpc_client/proto/example.proto | 0 .../redis/config.go | 0 .../redis/redis.go | 0 makefile | 8 +- pkg/validator/validation_err.go | 6 + pkg/validator/validator.go | 80 +++++++++++ repositories/domain/domain.go | 65 +++++++++ repository/user/user.go | 57 -------- schema.md | 108 ++++++++++++++ schemas/base.go | 6 + schemas/domain.go | 10 ++ service/user/profile.go | 20 --- service/user/service.go | 18 --- service/.keep => services/.gitkeep | 0 services/domain/domain_create.go | 44 ++++++ services/domain/domain_error.go | 9 ++ services/domain/domain_service.go | 21 +++ services/domain/domain_validator.go | 7 + 59 files changed, 966 insertions(+), 250 deletions(-) rename {delivery => deliveries}/grpc/buf/buf.gen.yaml (100%) rename {delivery => deliveries}/grpc/config.go (100%) rename {delivery => deliveries}/grpc/gen/health.pb.go (100%) rename {delivery => deliveries}/grpc/gen/health_grpc.pb.go (100%) rename {delivery => deliveries}/grpc/health.go (91%) rename {delivery => deliveries}/grpc/proto/health.proto (100%) rename {delivery => deliveries}/grpc/server.go (87%) rename {delivery => deliveries}/http/config.go (100%) rename repository/.keep => deliveries/http/handlers/.gitkeep (100%) create mode 100644 deliveries/http/handlers/domain_handler/domain_create.go create mode 100644 deliveries/http/handlers/domain_handler/dto/domain_request.go create mode 100644 deliveries/http/handlers/domain_handler/dto/domain_response.go create mode 100644 deliveries/http/handlers/domain_handler/handler.go create mode 100644 deliveries/http/handlers/domain_handler/router.go create mode 100644 deliveries/http/http_handlers.go create mode 100644 deliveries/http/http_server.go rename {delivery/http/middleware => deliveries/http/middlewares}/auth.go (100%) create mode 100644 deliveries/http/response.go delete mode 100644 delivery/http/server.go delete mode 100644 delivery/http/user_handler/handler.go delete mode 100644 delivery/http/user_handler/profile.go delete mode 100644 delivery/http/user_handler/router.go create mode 100644 docs/docs.go create mode 100644 docs/swagger.json create mode 100644 docs/swagger.yaml delete mode 100644 entity/user.go rename {infrastructure => infrastructures}/database/config.go (100%) rename {infrastructure => infrastructures}/database/database.go (100%) rename {infrastructure => infrastructures}/grpc_client/buf/buf.gen.yaml (100%) rename {infrastructure => infrastructures}/grpc_client/client.go (91%) rename {infrastructure => infrastructures}/grpc_client/config.go (100%) rename {infrastructure => infrastructures}/grpc_client/gen/example.pb.go (100%) rename {infrastructure => infrastructures}/grpc_client/gen/example_grpc.pb.go (100%) rename {infrastructure => infrastructures}/grpc_client/proto/example.proto (100%) rename {infrastructure => infrastructures}/redis/config.go (100%) rename {infrastructure => infrastructures}/redis/redis.go (100%) create mode 100644 pkg/validator/validation_err.go create mode 100644 pkg/validator/validator.go create mode 100644 repositories/domain/domain.go delete mode 100644 repository/user/user.go create mode 100644 schema.md create mode 100644 schemas/base.go create mode 100644 schemas/domain.go delete mode 100644 service/user/profile.go delete mode 100644 service/user/service.go rename service/.keep => services/.gitkeep (100%) create mode 100644 services/domain/domain_create.go create mode 100644 services/domain/domain_error.go create mode 100644 services/domain/domain_service.go create mode 100644 services/domain/domain_validator.go diff --git a/README.md b/README.md index 0ff48cd..1eaff34 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,2 @@ -# Go Echo Boilerplate - -This is a golang boilerplate for projects using echo and mongo db stack on Dezh Technologies. - -## Stack - -* Mongo DB -* Redis -* HTTP/echo -* gRPC/google.grpc - -## TODOs - -- [ ] Implementing auth middleware. - -## Contributions - -All kind of contribution are welcome here. - -## License - -This repo is [unlicensed](./LICENSE). +# Panda +## NIP-05 service \ No newline at end of file diff --git a/cmd/commands/run.go b/cmd/commands/run.go index c2665e2..3b25d5f 100644 --- a/cmd/commands/run.go +++ b/cmd/commands/run.go @@ -6,9 +6,9 @@ import ( "os/signal" "syscall" - "github.com/dezh-tech/geb/cmd/daemon" - "github.com/dezh-tech/geb/config" - "github.com/dezh-tech/geb/pkg/logger" + "github.com/dezh-tech/panda/cmd/daemon" + "github.com/dezh-tech/panda/config" + "github.com/dezh-tech/panda/pkg/logger" ) func HandleRun(args []string) { diff --git a/cmd/commands/utils.go b/cmd/commands/utils.go index b974b1d..01e132c 100644 --- a/cmd/commands/utils.go +++ b/cmd/commands/utils.go @@ -6,6 +6,6 @@ import ( ) func ExitOnError(err error) { - log.Printf("immortal error: %s\n", err.Error()) //nolint + log.Printf("panda error: %s\n", err.Error()) //nolint os.Exit(1) } diff --git a/cmd/daemon/daemon.go b/cmd/daemon/daemon.go index 02b1a3a..0a03478 100644 --- a/cmd/daemon/daemon.go +++ b/cmd/daemon/daemon.go @@ -3,15 +3,15 @@ package daemon import ( "time" - "github.com/dezh-tech/geb/config" - "github.com/dezh-tech/geb/delivery/grpc" - "github.com/dezh-tech/geb/delivery/http" - "github.com/dezh-tech/geb/infrastructure/database" - grpcclient "github.com/dezh-tech/geb/infrastructure/grpc_client" - "github.com/dezh-tech/geb/infrastructure/redis" - "github.com/dezh-tech/geb/pkg/logger" - userrepo "github.com/dezh-tech/geb/repository/user" - usersrv "github.com/dezh-tech/geb/service/user" + "github.com/dezh-tech/panda/config" + "github.com/dezh-tech/panda/deliveries/grpc" + "github.com/dezh-tech/panda/deliveries/http" + "github.com/dezh-tech/panda/infrastructures/database" + grpcClient "github.com/dezh-tech/panda/infrastructures/grpc_client" + "github.com/dezh-tech/panda/infrastructures/redis" + "github.com/dezh-tech/panda/pkg/logger" + domainRepo "github.com/dezh-tech/panda/repositories/domain" + domainService "github.com/dezh-tech/panda/services/domain" ) type Daemon struct { @@ -33,14 +33,14 @@ func New(cfg *config.Config) (*Daemon, error) { return nil, err } - _, err = grpcclient.New(cfg.GRPCClient.Endpoint) + _, err = grpcClient.New(cfg.GRPCClient.Endpoint) if err != nil { return nil, err } - userRepo := userrepo.New(db) + userRepo := domainRepo.New(db) - hs := http.New(cfg.HTTPServer, usersrv.New(userRepo)) + hs := http.New(cfg.HTTPServer, domainService.New(userRepo)) gs := grpc.New(&cfg.GRPCServer, r, db, time.Now()) return &Daemon{ diff --git a/cmd/main.go b/cmd/main.go index a94fb50..69cae57 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - goginboilerplate "github.com/dezh-tech/geb" - "github.com/dezh-tech/geb/cmd/commands" + goginboilerplate "github.com/dezh-tech/panda" + "github.com/dezh-tech/panda/cmd/commands" ) func main() { diff --git a/config/config.go b/config/config.go index 4165c0d..90a488d 100644 --- a/config/config.go +++ b/config/config.go @@ -3,12 +3,12 @@ package config import ( "os" - "github.com/dezh-tech/geb/delivery/grpc" - "github.com/dezh-tech/geb/delivery/http" - "github.com/dezh-tech/geb/infrastructure/database" - grpcclient "github.com/dezh-tech/geb/infrastructure/grpc_client" - "github.com/dezh-tech/geb/infrastructure/redis" - "github.com/dezh-tech/geb/pkg/logger" + "github.com/dezh-tech/panda/deliveries/grpc" + "github.com/dezh-tech/panda/deliveries/http" + "github.com/dezh-tech/panda/infrastructures/database" + grpcclient "github.com/dezh-tech/panda/infrastructures/grpc_client" + "github.com/dezh-tech/panda/infrastructures/redis" + "github.com/dezh-tech/panda/pkg/logger" "github.com/joho/godotenv" "gopkg.in/yaml.v3" ) diff --git a/delivery/grpc/buf/buf.gen.yaml b/deliveries/grpc/buf/buf.gen.yaml similarity index 100% rename from delivery/grpc/buf/buf.gen.yaml rename to deliveries/grpc/buf/buf.gen.yaml diff --git a/delivery/grpc/config.go b/deliveries/grpc/config.go similarity index 100% rename from delivery/grpc/config.go rename to deliveries/grpc/config.go diff --git a/delivery/grpc/gen/health.pb.go b/deliveries/grpc/gen/health.pb.go similarity index 100% rename from delivery/grpc/gen/health.pb.go rename to deliveries/grpc/gen/health.pb.go diff --git a/delivery/grpc/gen/health_grpc.pb.go b/deliveries/grpc/gen/health_grpc.pb.go similarity index 100% rename from delivery/grpc/gen/health_grpc.pb.go rename to deliveries/grpc/gen/health_grpc.pb.go diff --git a/delivery/grpc/health.go b/deliveries/grpc/health.go similarity index 91% rename from delivery/grpc/health.go rename to deliveries/grpc/health.go index 20e171e..796b8bc 100644 --- a/delivery/grpc/health.go +++ b/deliveries/grpc/health.go @@ -4,8 +4,8 @@ import ( "context" "time" - goginboilerplate "github.com/dezh-tech/geb" - pb "github.com/dezh-tech/geb/delivery/grpc/gen" + goginboilerplate "github.com/dezh-tech/panda" + pb "github.com/dezh-tech/panda/deliveries/grpc/gen" ) type healthServer struct { diff --git a/delivery/grpc/proto/health.proto b/deliveries/grpc/proto/health.proto similarity index 100% rename from delivery/grpc/proto/health.proto rename to deliveries/grpc/proto/health.proto diff --git a/delivery/grpc/server.go b/deliveries/grpc/server.go similarity index 87% rename from delivery/grpc/server.go rename to deliveries/grpc/server.go index 7176808..dde0f09 100644 --- a/delivery/grpc/server.go +++ b/deliveries/grpc/server.go @@ -6,9 +6,9 @@ import ( "strconv" "time" - pb "github.com/dezh-tech/geb/delivery/grpc/gen" - "github.com/dezh-tech/geb/infrastructure/database" - "github.com/dezh-tech/geb/infrastructure/redis" + pb "github.com/dezh-tech/panda/deliveries/grpc/gen" + "github.com/dezh-tech/panda/infrastructures/database" + "github.com/dezh-tech/panda/infrastructures/redis" "google.golang.org/grpc" ) diff --git a/delivery/http/config.go b/deliveries/http/config.go similarity index 100% rename from delivery/http/config.go rename to deliveries/http/config.go diff --git a/repository/.keep b/deliveries/http/handlers/.gitkeep similarity index 100% rename from repository/.keep rename to deliveries/http/handlers/.gitkeep diff --git a/deliveries/http/handlers/domain_handler/domain_create.go b/deliveries/http/handlers/domain_handler/domain_create.go new file mode 100644 index 0000000..fb5670e --- /dev/null +++ b/deliveries/http/handlers/domain_handler/domain_create.go @@ -0,0 +1,49 @@ +package domainhandler + +import ( + "fmt" + "net/http" + + domainhandler "github.com/dezh-tech/panda/deliveries/http/handlers/domain_handler/dto" + "github.com/dezh-tech/panda/pkg/validator" + domainService "github.com/dezh-tech/panda/services/domain" + "github.com/labstack/echo/v4" +) + +// CreateDomain creates a new domain. +// +// @Summary Create a new domain +// @Description Accepts a JSON payload to create a new domain with the specified attributes. +// @Tags domain +// @Accept json +// @Produce json +// @Param domain body domainhandler.DomainCreateRequest true "Domain creation payload" +// @Success 200 {object} domainhandler.DomainCreateResponse "Domain created successfully" +// @Failure 400 {object} map[string]string "Bad Request - Invalid input" +// @Failure 500 {object} map[string]string "Internal Server Error" +// @Router /domains [post] +func (h Handler) domainCreate(c echo.Context) error { + req := new(domainhandler.DomainCreateRequest) + if err := c.Bind(req); err != nil { + return err + } + + v := validator.NewValidator() + validationErrors := v.Validate(req) + if validationErrors != nil { + return echo.NewHTTPError(http.StatusBadRequest, &validator.Varror{ValidationErrors: validationErrors}) + } + + resp, err := h.domainSvc.Create(domainService.DomainInsertArgs{ + Domain: req.Domain, + BasePricePerIdentifier: req.BasePricePerIdentifier, + DefaultTTL: req.DefaultTTL, + Status: req.Status, + }) + if err != nil { + fmt.Println(err) + return echo.NewHTTPError(http.StatusBadRequest, err) + } + + return c.JSON(http.StatusOK, &domainhandler.DomainCreateResponse{ID: resp.ID}) +} diff --git a/deliveries/http/handlers/domain_handler/dto/domain_request.go b/deliveries/http/handlers/domain_handler/dto/domain_request.go new file mode 100644 index 0000000..ed5fcf0 --- /dev/null +++ b/deliveries/http/handlers/domain_handler/dto/domain_request.go @@ -0,0 +1,8 @@ +package domainhandler + +type DomainCreateRequest struct { + Domain string `json:"domain" validate:"required,hostname" form:"domain" query:"domain"` + BasePricePerIdentifier uint `json:"base_price_per_identifier" validate:"required,min=1" form:"base_price_per_identifier" query:"base_price_per_identifier"` + DefaultTTL uint32 `json:"default_ttl" validate:"required,min=1" form:"default_ttl" query:"default_ttl"` + Status string `json:"status" validate:"required,oneof=active inactive" form:"status" query:"status"` +} diff --git a/deliveries/http/handlers/domain_handler/dto/domain_response.go b/deliveries/http/handlers/domain_handler/dto/domain_response.go new file mode 100644 index 0000000..6024018 --- /dev/null +++ b/deliveries/http/handlers/domain_handler/dto/domain_response.go @@ -0,0 +1,5 @@ +package domainhandler + +type DomainCreateResponse struct { + ID interface{} `json:"id"` +} diff --git a/deliveries/http/handlers/domain_handler/handler.go b/deliveries/http/handlers/domain_handler/handler.go new file mode 100644 index 0000000..ff9b84e --- /dev/null +++ b/deliveries/http/handlers/domain_handler/handler.go @@ -0,0 +1,13 @@ +package domainhandler + +import domainService "github.com/dezh-tech/panda/services/domain" + +type Handler struct { + domainSvc domainService.DomainService +} + +func New(domainSvc domainService.DomainService) Handler { + return Handler{ + domainSvc: domainSvc, + } +} diff --git a/deliveries/http/handlers/domain_handler/router.go b/deliveries/http/handlers/domain_handler/router.go new file mode 100644 index 0000000..6ea7f5c --- /dev/null +++ b/deliveries/http/handlers/domain_handler/router.go @@ -0,0 +1,11 @@ +package domainhandler + +import ( + "github.com/labstack/echo/v4" +) + +func (h Handler) SetRoutes(e *echo.Echo) { + userGroup := e.Group("/domains") + + userGroup.POST("", h.domainCreate) +} diff --git a/deliveries/http/http_handlers.go b/deliveries/http/http_handlers.go new file mode 100644 index 0000000..4b13332 --- /dev/null +++ b/deliveries/http/http_handlers.go @@ -0,0 +1,33 @@ +package http + +import ( + domainhandler "github.com/dezh-tech/panda/deliveries/http/handlers/domain_handler" + _ "github.com/dezh-tech/panda/docs" + "github.com/labstack/echo/v4" + echoSwagger "github.com/swaggo/echo-swagger" +) + +// @title Panda Swagger +// @version 1.0 +// @description This is a sample server Petstore server. +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host localhost:8080 +// @BasePath / + +type HttpHandlers struct { + user domainhandler.Handler +} + +func (h *HttpHandlers) Start(r *echo.Echo) { + h.user.SetRoutes(r) + + r.GET("/swagger/*", echoSwagger.WrapHandler) +} diff --git a/deliveries/http/http_server.go b/deliveries/http/http_server.go new file mode 100644 index 0000000..4f1696d --- /dev/null +++ b/deliveries/http/http_server.go @@ -0,0 +1,45 @@ +package http + +import ( + "fmt" + + domainhandler "github.com/dezh-tech/panda/deliveries/http/handlers/domain_handler" + domainService "github.com/dezh-tech/panda/services/domain" + "github.com/labstack/echo/v4" +) + +type Server struct { + Router *echo.Echo + config Config + handlers HttpHandlers +} + +func New(config Config, userSvc domainService.DomainService) Server { + return Server{ + Router: echo.New(), + config: config, + + handlers: HttpHandlers{ + user: domainhandler.New(userSvc), + }, + } +} + +func (s Server) Start() error { + s.handlers.Start(s.Router) + + address := fmt.Sprintf(":%d", s.config.Port) + if err := s.Router.Start(address); err != nil { + return err + } + + return nil +} + +func (s Server) Stop() error { + if err := s.Router.Close(); err != nil { + return err + } + + return nil +} diff --git a/delivery/http/middleware/auth.go b/deliveries/http/middlewares/auth.go similarity index 100% rename from delivery/http/middleware/auth.go rename to deliveries/http/middlewares/auth.go diff --git a/deliveries/http/response.go b/deliveries/http/response.go new file mode 100644 index 0000000..27c1780 --- /dev/null +++ b/deliveries/http/response.go @@ -0,0 +1,7 @@ +package http + +type Response struct { + Success bool `json:"success"` + Message string `json:"message"` + Data interface{} `json:"data"` +} diff --git a/delivery/http/server.go b/delivery/http/server.go deleted file mode 100644 index 509988a..0000000 --- a/delivery/http/server.go +++ /dev/null @@ -1,42 +0,0 @@ -package http - -import ( - "fmt" - - userh "github.com/dezh-tech/geb/delivery/http/user_handler" - users "github.com/dezh-tech/geb/service/user" - "github.com/labstack/echo/v4" -) - -type Server struct { - config Config - userHandler userh.Handler - Router *echo.Echo -} - -func New(config Config, userSvc users.Service) Server { - return Server{ - Router: echo.New(), - config: config, - userHandler: userh.New(userSvc), - } -} - -func (s Server) Start() error { - s.userHandler.SetRoutes(s.Router) - - address := fmt.Sprintf(":%d", s.config.Port) - if err := s.Router.Start(address); err != nil { - return err - } - - return nil -} - -func (s Server) Stop() error { - if err := s.Router.Close(); err != nil { - return err - } - - return nil -} diff --git a/delivery/http/user_handler/handler.go b/delivery/http/user_handler/handler.go deleted file mode 100644 index 15545dc..0000000 --- a/delivery/http/user_handler/handler.go +++ /dev/null @@ -1,13 +0,0 @@ -package userhandler - -import "github.com/dezh-tech/geb/service/user" - -type Handler struct { - userSvc user.Service -} - -func New(userSvc user.Service) Handler { - return Handler{ - userSvc: userSvc, - } -} diff --git a/delivery/http/user_handler/profile.go b/delivery/http/user_handler/profile.go deleted file mode 100644 index 6464e39..0000000 --- a/delivery/http/user_handler/profile.go +++ /dev/null @@ -1,19 +0,0 @@ -package userhandler - -import ( - "net/http" - - "github.com/dezh-tech/geb/service/user" - "github.com/labstack/echo/v4" -) - -func (h Handler) userProfile(c echo.Context) error { - pubkey, _ := c.Get("pubkey").(string) // not safe! - - resp, err := h.userSvc.Profile(user.ProfileRequest{Pubkey: pubkey}) - if err != nil { - return echo.NewHTTPError(http.StatusNotFound, "not found") - } - - return c.JSON(http.StatusOK, resp) -} diff --git a/delivery/http/user_handler/router.go b/delivery/http/user_handler/router.go deleted file mode 100644 index 383d3d1..0000000 --- a/delivery/http/user_handler/router.go +++ /dev/null @@ -1,13 +0,0 @@ -package userhandler - -import ( - "github.com/dezh-tech/geb/delivery/http/middleware" - "github.com/labstack/echo/v4" -) - -func (h Handler) SetRoutes(e *echo.Echo) { - userGroup := e.Group("/users") - - userGroup.GET("/profile", h.userProfile, - middleware.Auth) -} diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..609ddf9 --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,135 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/domains": { + "post": { + "description": "Accepts a JSON payload to create a new domain with the specified attributes.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "domain" + ], + "summary": "Create a new domain", + "parameters": [ + { + "description": "Domain creation payload", + "name": "domain", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/domainhandler.DomainCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "Domain created successfully", + "schema": { + "$ref": "#/definitions/domainhandler.DomainCreateResponse" + } + }, + "400": { + "description": "Bad Request - Invalid input", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "definitions": { + "domainhandler.DomainCreateRequest": { + "type": "object", + "required": [ + "base_price_per_identifier", + "default_ttl", + "domain", + "status" + ], + "properties": { + "base_price_per_identifier": { + "type": "integer", + "minimum": 1 + }, + "default_ttl": { + "type": "integer", + "minimum": 1 + }, + "domain": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive" + ] + } + } + }, + "domainhandler.DomainCreateResponse": { + "type": "object", + "properties": { + "id": {} + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "localhost:8080", + BasePath: "/", + Schemes: []string{}, + Title: "Panda Swagger", + Description: "This is a sample server Petstore server.", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..7b8e30e --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,111 @@ +{ + "swagger": "2.0", + "info": { + "description": "This is a sample server Petstore server.", + "title": "Panda Swagger", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0" + }, + "host": "localhost:8080", + "basePath": "/", + "paths": { + "/domains": { + "post": { + "description": "Accepts a JSON payload to create a new domain with the specified attributes.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "domain" + ], + "summary": "Create a new domain", + "parameters": [ + { + "description": "Domain creation payload", + "name": "domain", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/domainhandler.DomainCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "Domain created successfully", + "schema": { + "$ref": "#/definitions/domainhandler.DomainCreateResponse" + } + }, + "400": { + "description": "Bad Request - Invalid input", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "definitions": { + "domainhandler.DomainCreateRequest": { + "type": "object", + "required": [ + "base_price_per_identifier", + "default_ttl", + "domain", + "status" + ], + "properties": { + "base_price_per_identifier": { + "type": "integer", + "minimum": 1 + }, + "default_ttl": { + "type": "integer", + "minimum": 1 + }, + "domain": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive" + ] + } + } + }, + "domainhandler.DomainCreateResponse": { + "type": "object", + "properties": { + "id": {} + } + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..eb2a644 --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,77 @@ +basePath: / +definitions: + domainhandler.DomainCreateRequest: + properties: + base_price_per_identifier: + minimum: 1 + type: integer + default_ttl: + minimum: 1 + type: integer + domain: + type: string + status: + enum: + - active + - inactive + type: string + required: + - base_price_per_identifier + - default_ttl + - domain + - status + type: object + domainhandler.DomainCreateResponse: + properties: + id: {} + type: object +host: localhost:8080 +info: + contact: + email: support@swagger.io + name: API Support + url: http://www.swagger.io/support + description: This is a sample server Petstore server. + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + termsOfService: http://swagger.io/terms/ + title: Panda Swagger + version: "1.0" +paths: + /domains: + post: + consumes: + - application/json + description: Accepts a JSON payload to create a new domain with the specified + attributes. + parameters: + - description: Domain creation payload + in: body + name: domain + required: true + schema: + $ref: '#/definitions/domainhandler.DomainCreateRequest' + produces: + - application/json + responses: + "200": + description: Domain created successfully + schema: + $ref: '#/definitions/domainhandler.DomainCreateResponse' + "400": + description: Bad Request - Invalid input + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: Create a new domain + tags: + - domain +swagger: "2.0" diff --git a/entity/user.go b/entity/user.go deleted file mode 100644 index 22e0360..0000000 --- a/entity/user.go +++ /dev/null @@ -1,6 +0,0 @@ -package entity - -type User struct { - Name string `bson:"name"` - Pubkey string `bson:"pubkey"` -} diff --git a/go.mod b/go.mod index f31baed..1374c3f 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/dezh-tech/geb +module github.com/dezh-tech/panda go 1.23.3 @@ -15,27 +15,47 @@ require ( ) require ( + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/PuerkitoBio/purell v1.2.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.13.6 // indirect - github.com/kr/pretty v0.3.0 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/labstack/gommon v0.4.2 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/montanaflynn/stats v0.7.1 // indirect - github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/swaggo/echo-swagger v1.4.1 // indirect + github.com/swaggo/files/v2 v2.0.2 // indirect + github.com/swaggo/swag v1.16.4 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect - golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect + golang.org/x/tools v0.29.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index f83f62b..2d69e18 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,9 @@ +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/purell v1.2.1 h1:QsZ4TjvwiMpat6gBCBxEQI0rcS9ehtkKtSpiUnd9N28= +github.com/PuerkitoBio/purell v1.2.1/go.mod h1:ZwHcC/82TOaovDi//J/804umJFFmbOHPngi8iYYv/Eo= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -10,10 +16,28 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= +github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= @@ -25,12 +49,15 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -39,8 +66,14 @@ github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaa github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -56,11 +89,20 @@ github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93Ge github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/swaggo/echo-swagger v1.4.1 h1:Yf0uPaJWp1uRtDloZALyLnvdBeoEL5Kc7DtnjzO/TUk= +github.com/swaggo/echo-swagger v1.4.1/go.mod h1:C8bSi+9yH2FLZsnhqMZLIZddpUxZdBYuNHbtaS1Hljc= +github.com/swaggo/files/v2 v2.0.2 h1:Bq4tgS/yxLB/3nwOMcul5oLEUKa877Ykgz3CJMVbQKU= +github.com/swaggo/files/v2 v2.0.2/go.mod h1:TVqetIzZsO9OhHX1Am9sRf9LdrFZqoK49N37KON/jr0= +github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A= +github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= @@ -90,12 +132,16 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= @@ -110,6 +156,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -121,6 +169,8 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= @@ -135,5 +185,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/infrastructure/database/config.go b/infrastructures/database/config.go similarity index 100% rename from infrastructure/database/config.go rename to infrastructures/database/config.go diff --git a/infrastructure/database/database.go b/infrastructures/database/database.go similarity index 100% rename from infrastructure/database/database.go rename to infrastructures/database/database.go diff --git a/infrastructure/grpc_client/buf/buf.gen.yaml b/infrastructures/grpc_client/buf/buf.gen.yaml similarity index 100% rename from infrastructure/grpc_client/buf/buf.gen.yaml rename to infrastructures/grpc_client/buf/buf.gen.yaml diff --git a/infrastructure/grpc_client/client.go b/infrastructures/grpc_client/client.go similarity index 91% rename from infrastructure/grpc_client/client.go rename to infrastructures/grpc_client/client.go index 041fba6..231cf46 100644 --- a/infrastructure/grpc_client/client.go +++ b/infrastructures/grpc_client/client.go @@ -3,7 +3,7 @@ package grpcclient import ( "context" - pb "github.com/dezh-tech/geb/infrastructure/grpc_client/gen" + pb "github.com/dezh-tech/panda/infrastructures/grpc_client/gen" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) diff --git a/infrastructure/grpc_client/config.go b/infrastructures/grpc_client/config.go similarity index 100% rename from infrastructure/grpc_client/config.go rename to infrastructures/grpc_client/config.go diff --git a/infrastructure/grpc_client/gen/example.pb.go b/infrastructures/grpc_client/gen/example.pb.go similarity index 100% rename from infrastructure/grpc_client/gen/example.pb.go rename to infrastructures/grpc_client/gen/example.pb.go diff --git a/infrastructure/grpc_client/gen/example_grpc.pb.go b/infrastructures/grpc_client/gen/example_grpc.pb.go similarity index 100% rename from infrastructure/grpc_client/gen/example_grpc.pb.go rename to infrastructures/grpc_client/gen/example_grpc.pb.go diff --git a/infrastructure/grpc_client/proto/example.proto b/infrastructures/grpc_client/proto/example.proto similarity index 100% rename from infrastructure/grpc_client/proto/example.proto rename to infrastructures/grpc_client/proto/example.proto diff --git a/infrastructure/redis/config.go b/infrastructures/redis/config.go similarity index 100% rename from infrastructure/redis/config.go rename to infrastructures/redis/config.go diff --git a/infrastructure/redis/redis.go b/infrastructures/redis/redis.go similarity index 100% rename from infrastructure/redis/redis.go rename to infrastructures/redis/redis.go diff --git a/makefile b/makefile index a3ca699..28bfb8a 100644 --- a/makefile +++ b/makefile @@ -13,7 +13,6 @@ devtools: go install mvdan.cc/gofumpt@latest go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.35 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.5 - go install github.com/pactus-project/protoc-gen-doc/cmd/protoc-gen-doc@v0.0.0-20240815105130-84e89d0170e4 go install github.com/bufbuild/buf/cmd/buf@v1.47 ### Testing @@ -35,8 +34,11 @@ check: golangci-lint run --timeout=20m0s ### Building -build: - go build -o build/project cmd/main.go +build: swag + go build -o build/panda cmd/main.go + +swag: + swag init -g ./deliveries/http/http_handlers.go ### Proto proto: diff --git a/pkg/validator/validation_err.go b/pkg/validator/validation_err.go new file mode 100644 index 0000000..699e26e --- /dev/null +++ b/pkg/validator/validation_err.go @@ -0,0 +1,6 @@ +package validator + +type Varror struct { + Error string `json:"error"` + ValidationErrors []*ValidationError `json:"validation_errors,omitempty"` +} \ No newline at end of file diff --git a/pkg/validator/validator.go b/pkg/validator/validator.go new file mode 100644 index 0000000..d04e3dd --- /dev/null +++ b/pkg/validator/validator.go @@ -0,0 +1,80 @@ +package validator + +import ( + "sync" + + "github.com/go-playground/locales/en" + ut "github.com/go-playground/universal-translator" + "github.com/go-playground/validator/v10" + en_translations "github.com/go-playground/validator/v10/translations/en" +) + +var ( + validateInstance *Validator + validatorLock = &sync.Mutex{} + validate = validator.New() + + localeEN = en.New() + uni = ut.New(localeEN, localeEN) + translator, _ = uni.GetTranslator("en") +) + +type Validator struct{} + +// Validator initializes and returns a singleton instance of the validator. +func NewValidator() *Validator { + if validateInstance == nil { + validatorLock.Lock() + defer validatorLock.Unlock() + + if validateInstance == nil { + validateInstance = &Validator{} + registerTranslations() + } + } + + return validateInstance +} + +// Validate validates a given struct and returns custom validation errors. +func (*Validator) Validate(s interface{}) []*ValidationError { + err := validate.Struct(s) + if err == nil { + return nil + } + + if validationErrors, ok := err.(validator.ValidationErrors); ok { + return formatValidationErrors(validationErrors) + } + + // Return a generic error if the type assertion fails + return []*ValidationError{ + { + Field: "unknown", + Message: err.Error(), + }, + } +} + +// registerTranslations adds translations for validation error messages. +func registerTranslations() { + en_translations.RegisterDefaultTranslations(validate, translator) +} + +// formatValidationErrors formats the validation errors for API responses. +func formatValidationErrors(errs validator.ValidationErrors) []*ValidationError { + var errors []*ValidationError + for _, err := range errs { + errors = append(errors, &ValidationError{ + Field: err.Field(), + Message: err.Translate(translator), + }) + } + return errors +} + +// ValidationError represents a single validation error. +type ValidationError struct { + Field string `json:"field"` + Message string `json:"message"` +} \ No newline at end of file diff --git a/repositories/domain/domain.go b/repositories/domain/domain.go new file mode 100644 index 0000000..bd60b8b --- /dev/null +++ b/repositories/domain/domain.go @@ -0,0 +1,65 @@ +package domain + +import ( + "context" + "errors" + "time" + + "github.com/dezh-tech/panda/infrastructures/database" + schema "github.com/dezh-tech/panda/schemas" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +type Domain struct { + db *database.Database +} + +const SCHEMA_NAME = "users" + +func New(db *database.Database) Domain { + return Domain{ + db: db, + } +} + +func (u Domain) Add(d schema.Domain) (*mongo.InsertOneResult, error) { + collection := u.db.Client.Database(u.db.DBName).Collection(SCHEMA_NAME) + + ctx, cancel := context.WithTimeout(context.Background(), u.db.QueryTimeout) + defer cancel() + + res, err := collection.InsertOne(ctx, bson.M{ + "Domain": d.Domain, + "BasePricePerIdentifier": d.BasePricePerIdentifier, + "DefaultTTL": d.DefaultTTL, + "Status": d.Status, + + "CreatedAt": time.Now(), + "UpdatedAt": time.Now(), + }) + if err != nil { + return nil, err + } + + return res, nil +} + +func (u Domain) GetByDomain(domain string) (*schema.Domain, error) { + collection := u.db.Client.Database(u.db.DBName).Collection(SCHEMA_NAME) + + ctx, cancel := context.WithTimeout(context.Background(), u.db.QueryTimeout) + defer cancel() + + var d *schema.Domain + err := collection.FindOne(ctx, bson.M{"Domain": domain}).Decode(&d) + if err != nil { + if errors.Is(err, mongo.ErrNoDocuments) { + return d, nil + } + + return d, err + } + + return d, nil +} diff --git a/repository/user/user.go b/repository/user/user.go deleted file mode 100644 index 12b9d74..0000000 --- a/repository/user/user.go +++ /dev/null @@ -1,57 +0,0 @@ -package user - -import ( - "context" - "errors" - - "github.com/dezh-tech/geb/entity" - "github.com/dezh-tech/geb/infrastructure/database" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" -) - -type User struct { - db *database.Database -} - -func New(db *database.Database) User { - return User{ - db: db, - } -} - -func (u User) Add(usr entity.User) error { - collection := u.db.Client.Database(u.db.DBName).Collection("users") - - ctx, cancel := context.WithTimeout(context.Background(), u.db.QueryTimeout) - defer cancel() - - _, err := collection.InsertOne(ctx, bson.M{ - "name": usr.Name, - "pubkey": usr.Pubkey, - }) - if err != nil { - return err - } - - return nil -} - -func (u User) GetByPubkey(pubkey string) (entity.User, error) { - collection := u.db.Client.Database(u.db.DBName).Collection("users") - - ctx, cancel := context.WithTimeout(context.Background(), u.db.QueryTimeout) - defer cancel() - - var usr entity.User - err := collection.FindOne(ctx, bson.M{"pubkey": pubkey}).Decode(&usr) - if err != nil { - if errors.Is(err, mongo.ErrNoDocuments) { - return usr, nil - } - - return usr, err - } - - return usr, nil -} diff --git a/schema.md b/schema.md new file mode 100644 index 0000000..7f7368d --- /dev/null +++ b/schema.md @@ -0,0 +1,108 @@ +# **Panda NIP-05 Identifier System Database Schemas** + +This document outlines the MongoDB schemas for a system designed to sell and resolve NIP-05 identifiers. + +--- + +## **1. Users Collection** + +Stores user information and credentials. + +### **Collection Name**: `Users` +### **Type**: User Management + +| **Field** | **Type** | **Constraints** | **Description** | +|-------------------|-------------|-----------------------------------------------|------------------------------------------------------| +| `_id` | ObjectId | Unique, Indexed | Unique identifier for the user. | +| `npub` | string | Required, Unique, Indexed | Nostr public key (e.g., npub...). | +| `passwordHash` | string | Required | Hashed password. | +| `createdAt` | ISODate | Required | Account creation timestamp. | +| `updatedAt` | ISODate | Required | Last updated timestamp. | + +--- + +## **2. Domains Collection** + +Defines the available domains for identifiers and their pricing. + +### **Collection Name**: `Domains` +### **Type**: Domain Management + +| **Field** | **Type** | **Constraints** | **Description** | +|-------------------------|-------------|-----------------------------------------------|------------------------------------------------------| +| `_id` | ObjectId | Unique, Indexed | Unique identifier for the domain. | +| `domain` | string | Required, Unique, Indexed | Domain name (e.g., "example.com"). | +| `basePricePerIdentifier` | number | Required | Cost per identifier (in sats). | +| `defaultTTL` | number | Optional | Default Time-to-Live for JSON cache (in seconds). | +| `status` | string | Required, Indexed | Status of the domain (e.g., "active", "inactive"). | +| `createdAt` | ISODate | Required | Creation timestamp. | +| `updatedAt` | ISODate | Required | Last updated timestamp. | + +--- + +## **3. Identifiers Collection** + +Represents individual NIP-05 identifiers. + +### **Collection Name**: `Identifiers` +### **Type**: Identifier Management + +| **Field** | **Type** | **Constraints** | **Description** | +|-------------------|-------------|-----------------------------------------------|------------------------------------------------------| +| `_id` | ObjectId | Unique, Indexed | Unique identifier for the NIP-05 identifier. | +| `name` | string | Required | Identifier name (e.g., "alice"). | +| `domainId` | ObjectId | Required, Indexed | Reference to the `Domains` collection. | +| `fullIdentifier` | string | Required, Unique, Indexed | Full identifier (e.g., "alice@example.com"). | +| `userId` | ObjectId | Required, Indexed | Reference to the `Users` collection. | +| `expiresAt` | ISODate | Required | Expiration date of the identifier. | +| `status` | string | Required, Indexed | Status of the identifier (e.g., "active", "inactive"). | +| `createdAt` | ISODate | Required | Creation timestamp. | +| `updatedAt` | ISODate | Required | Last updated timestamp. | + +--- + +## **4. Transactions Collection** + +Tracks all financial transactions, including payments for identifiers or other services. + +### **Collection Name**: `Transactions` +### **Type**: Financial Management + +| **Field** | **Type** | **Constraints** | **Description** | +|----------------------|-------------|-----------------------------------------------|------------------------------------------------------| +| `_id` | ObjectId | Unique, Indexed | Unique identifier for the transaction. | +| `transactionId` | string | Required, Unique, Indexed | Unique ID for the transaction (e.g., UUID). | +| `userId` | ObjectId | Required, Indexed | Reference to the `Users` collection. | +| `domainId` | ObjectId | Optional, Indexed | Reference to the `Domains` collection. | +| `identifierId` | ObjectId | Optional, Indexed | Reference to the `Identifiers` collection. | +| `amount` | number | Required | Amount paid (e.g., in sats or fiat). | +| `currency` | string | Required | Currency type (e.g., "BTC", "USD"). | +| `type` | string | Required, Indexed | Transaction type (e.g., "purchase", "renewal"). | +| `paymentProcessor` | string | Optional | Payment processor used (e.g., "Stripe", "Bitcoin"). | +| `paymentDetails` | object | Optional | Additional details from the payment processor. | +| `paymentDetails.referenceId` | string | Optional, Indexed | Payment processor's reference ID. | +| `paymentDetails.method` | string | Optional | Payment method (e.g., "credit_card"). | +| `paymentDetails.confirmedAt` | ISODate | Optional | When the payment was confirmed (if applicable). | +| `paymentStatus` | string | Required, Indexed | Payment status (e.g., "completed", "pending"). | +| `status` | string | Required, Indexed | Overall transaction status (e.g., "active"). | +| `createdAt` | ISODate | Required | Transaction creation timestamp. | +| `updatedAt` | ISODate | Required | Last updated timestamp. | + +--- + +## **5. ResolveRecords Collection** + +Stores resolution records for identifiers, similar to DNS records. + +### **Collection Name**: `ResolveRecords` +### **Type**: Resolution Management + +| **Field** | **Type** | **Constraints** | **Description** | +|-------------------|-------------|-----------------------------------------------|------------------------------------------------------| +| `_id` | ObjectId | Unique, Indexed | Unique identifier for the resolution record. | +| `identifierId` | ObjectId | Required, Indexed | Reference to the `Identifiers` collection. | +| `type` | string | Required, Indexed | Record type (e.g., "NOSTR", "CNAME", "URL", "TXT"). | +| `value` | string | Required | Record value (e.g., public key, alias, URL). | +| `priority` | number | Optional | Priority for sorting multiple records. | +| `createdAt` | ISODate | Required | Creation timestamp. | +| `updatedAt` | ISODate | Required | Last updated timestamp. | diff --git a/schemas/base.go b/schemas/base.go new file mode 100644 index 0000000..98fcd92 --- /dev/null +++ b/schemas/base.go @@ -0,0 +1,6 @@ +package schema + +type Base struct { + CreatedAt string `bson:"CreatedAt"` + UpdatedAt string `bson:"UpdatedAt"` +} diff --git a/schemas/domain.go b/schemas/domain.go new file mode 100644 index 0000000..99e9d46 --- /dev/null +++ b/schemas/domain.go @@ -0,0 +1,10 @@ +package schema + +type Domain struct { + Domain string `bson:"Domain"` + BasePricePerIdentifier uint `bson:"BasePricePerIdentifier"` + DefaultTTL uint32 `bson:"DefaultTTL"` + Status string `bson:"Status"` + + Base +} diff --git a/service/user/profile.go b/service/user/profile.go deleted file mode 100644 index d5b727e..0000000 --- a/service/user/profile.go +++ /dev/null @@ -1,20 +0,0 @@ -package user - -import "errors" - -type ProfileRequest struct { - Pubkey string -} - -type ProfileResponse struct { - Name string `json:"name"` -} - -func (s Service) Profile(req ProfileRequest) (ProfileResponse, error) { - user, err := s.repo.GetByPubkey(req.Pubkey) - if err != nil { - return ProfileResponse{}, errors.New("can't get the profile") // todo::: move to errors.go - } - - return ProfileResponse{Name: user.Name}, nil -} diff --git a/service/user/service.go b/service/user/service.go deleted file mode 100644 index e8d7f8f..0000000 --- a/service/user/service.go +++ /dev/null @@ -1,18 +0,0 @@ -package user - -import ( - "github.com/dezh-tech/geb/entity" -) - -type Repository interface { - Add(usr entity.User) error - GetByPubkey(pubkey string) (entity.User, error) -} - -type Service struct { - repo Repository -} - -func New(repo Repository) Service { - return Service{repo: repo} -} diff --git a/service/.keep b/services/.gitkeep similarity index 100% rename from service/.keep rename to services/.gitkeep diff --git a/services/domain/domain_create.go b/services/domain/domain_create.go new file mode 100644 index 0000000..9b803ed --- /dev/null +++ b/services/domain/domain_create.go @@ -0,0 +1,44 @@ +package domainService + +import ( + "github.com/dezh-tech/panda/pkg/validator" + schema "github.com/dezh-tech/panda/schemas" +) + +type DomainInsertArgs struct { + Domain string + BasePricePerIdentifier uint + DefaultTTL uint32 + Status string +} + +type DomainInsertRes struct { + ID interface{} +} + +func (s DomainService) Create(req DomainInsertArgs) (*DomainInsertRes, *validator.Varror) { + // Check if the domain already exists + domain, err := s.repo.GetByDomain(req.Domain) + if err != nil { + return nil, &validator.Varror{Error: err.Error()} + } + + if domain != nil { + return nil, &validator.Varror{Error: ErrIsExist.Error()} + } + + // Add the domain to the repository + id, err := s.repo.Add(schema.Domain{ + Domain: req.Domain, + BasePricePerIdentifier: req.BasePricePerIdentifier, + DefaultTTL: req.DefaultTTL, + Status: req.Status, + }) + + if err != nil { + return nil, &validator.Varror{Error: err.Error()} + } + + // Return the response + return &DomainInsertRes{ID: id.InsertedID}, nil +} diff --git a/services/domain/domain_error.go b/services/domain/domain_error.go new file mode 100644 index 0000000..0ac4af6 --- /dev/null +++ b/services/domain/domain_error.go @@ -0,0 +1,9 @@ +package domainService + +import "errors" + +var ( + Err = errors.New("something went wrong") + ErrNotFound = errors.New("domain not found") + ErrIsExist = errors.New("domain exist") +) \ No newline at end of file diff --git a/services/domain/domain_service.go b/services/domain/domain_service.go new file mode 100644 index 0000000..cac75eb --- /dev/null +++ b/services/domain/domain_service.go @@ -0,0 +1,21 @@ +package domainService + +import ( + schema "github.com/dezh-tech/panda/schemas" + "github.com/dezh-tech/panda/pkg/validator" + "go.mongodb.org/mongo-driver/mongo" +) + +type Repository interface { + Add(usr schema.Domain) (*mongo.InsertOneResult, error) + GetByDomain(domain string) (*schema.Domain, error) +} + +type DomainService struct { + repo Repository + validator *validator.Validator +} + +func New(repo Repository) DomainService { + return DomainService{repo: repo, validator: validator.NewValidator()} +} diff --git a/services/domain/domain_validator.go b/services/domain/domain_validator.go new file mode 100644 index 0000000..2909ab0 --- /dev/null +++ b/services/domain/domain_validator.go @@ -0,0 +1,7 @@ +package domainService + +type insertDomainValidation struct { + Domain string `validate:"required,url"` + BasePricePerIdentifier uint `validate:"required"` + Status string `validate:"oneof=ACTIVE INACTIVE"` +} \ No newline at end of file