From fe48b7caeefdaa82fd0d79a6130a975642d13c8c Mon Sep 17 00:00:00 2001 From: FernandoJVideira <03.pleaser-minster@icloud.com> Date: Tue, 25 Aug 2026 21:32:54 +0100 Subject: [PATCH] feat: wire organizations into main.go template for both HTTP and gRPC --- assets/templates/main.go.tpl | 87 ++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/assets/templates/main.go.tpl b/assets/templates/main.go.tpl index 5c160b4..7f42193 100644 --- a/assets/templates/main.go.tpl +++ b/assets/templates/main.go.tpl @@ -49,8 +49,6 @@ import ( {{ end }} "github.com/jackc/pgx/v5/pgxpool" _ "github.com/jackc/pgx/v5/stdlib" - - ) var interruptSignals = []os.Signal{ @@ -59,25 +57,24 @@ var interruptSignals = []os.Signal{ syscall.SIGINT, } -// @title Simple Bank API +// @title App Template API // @version 1.0 -// @description API for Simple Bank application +// @description REST API template: accounts (register/login/email verification/refresh tokens) and multi-tenant organizations (members/invites) already wired up. // @termsOfService http://swagger.io/terms/ -// @contact.name API Support -// @contact.email support@simplebank.com +// @contact.name App Template // @license.name MIT // @license.url https://opensource.org/licenses/MIT // @host localhost:8080 -// @BasePath /v1 +// @BasePath /api/v1 // @schemes http https // @securityDefinitions.apikey BearerAuth // @in header // @name Authorization -// @description Type "Bearer" followed by a space and JWT token. +// @description PASETO access token. Format: "Bearer ". Some endpoints also accept the equivalent value via the "access_token" cookie. func main() { config, err := config.LoadConfig(".") if err != nil { @@ -86,6 +83,7 @@ func main() { if config.Environment == "development" { log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) + zerolog.SetGlobalLevel(zerolog.DebugLevel) } ctx, cancel := signal.NotifyContext(context.Background(), interruptSignals...) @@ -114,15 +112,20 @@ func main() { userService := service.NewUserService(store, taskDist) authService := service.NewAuthService(store, tokenMaker, config) + orgService := service.NewOrganizationService(store, taskDist) wg, ctx := errgroup.WithContext(ctx) {{ if not .UseGRPC }} - runGinServer(ctx, wg, config, store, taskDist, tokenMaker, userService, authService) + services := api.Services{ + UserService: userService, + AuthService: authService, + OrganizationService: orgService, + } + runGinServer(ctx, wg, config, store, taskDist, tokenMaker, services) {{ else }} - // Assuming you want Gateway AND gRPC when gRPC is selected - runGatewayServer(ctx, wg, config, store, taskDist, tokenMaker, userService, authService) - runGrpcServer(ctx, wg, config, store, taskDist, tokenMaker, userService, authService) + runGatewayServer(ctx, wg, config, store, taskDist, tokenMaker, userService, authService, orgService) + runGrpcServer(ctx, wg, config, store, taskDist, tokenMaker, userService, authService, orgService) {{ end }} runTaskProcessor(ctx, wg, redisOpt, store, config) @@ -133,8 +136,19 @@ func main() { } } -func runTaskProcessor(ctx context.Context, wg *errgroup.Group, redisOpt asynq.RedisClientOpt, store db.Store, config config.Config) { - mailer := mailer.NewGmailSender(config.EmailSenderName, config.EmailSender, config.EmailPassword) +func runTaskProcessor( + ctx context.Context, + wg *errgroup.Group, + redisOpt asynq.RedisClientOpt, + store db.Store, + config config.Config, +) { + mailer := mailer.NewSMTPSender( + config.EmailSenderName, + config.EmailSender, + config.EmailPassword, + config.SMTPAddr, + ) taskProcessor := worker.NewRedisTaskProcessor(redisOpt, store, mailer, config) log.Info().Msg("start task processor") if err := taskProcessor.Start(); err != nil { @@ -164,8 +178,16 @@ func runDBMigration(migrationURL, dbSource string) { } {{ if not .UseGRPC }} -func runGinServer(ctx context.Context, wg *errgroup.Group, config config.Config, store db.Store, td worker.TaskDistributor, tokenMaker auth.Maker, userService service.UserService, authService service.AuthService) { - s, err := api.NewServer(config, store, td, tokenMaker, userService, authService) +func runGinServer( + ctx context.Context, + wg *errgroup.Group, + config config.Config, + store db.Store, + td worker.TaskDistributor, + tokenMaker auth.Maker, + services api.Services, +) { + s, err := api.NewServer(config, store, td, tokenMaker, services) if err != nil { log.Fatal().Err(err).Msg("cannot create server") } @@ -194,8 +216,18 @@ func runGinServer(ctx context.Context, wg *errgroup.Group, config config.Config, {{ end }} {{ if .UseGRPC }} -func runGrpcServer(ctx context.Context, wg *errgroup.Group, config config.Config, store db.Store, taskDistributor worker.TaskDistributor, tokenMaker auth.Maker, userService service.UserService, authService service.AuthService) { - server, err := gapi.NewServer(config, store, taskDistributor, tokenMaker, userService, authService) +func runGrpcServer( + ctx context.Context, + wg *errgroup.Group, + config config.Config, + store db.Store, + td worker.TaskDistributor, + tokenMaker auth.Maker, + userService service.UserService, + authService service.AuthService, + organizationService service.OrganizationService, +) { + server, err := gapi.NewServer(config, store, td, tokenMaker, userService, authService, organizationService) if err != nil { log.Fatal().Err(err).Msg("cannot create server:") } @@ -203,7 +235,7 @@ func runGrpcServer(ctx context.Context, wg *errgroup.Group, config config.Config grpcLogger := grpc.UnaryInterceptor(gapi.GrpcLogger) grpcServer := grpc.NewServer(grpcLogger) - pb.RegisterSimpleBankServer(grpcServer, server) + pb.Register{{ .ServiceName }}Server(grpcServer, server) reflection.Register(grpcServer) listener, err := net.Listen("tcp", config.GrpcServerAddr) @@ -233,8 +265,18 @@ func runGrpcServer(ctx context.Context, wg *errgroup.Group, config config.Config }) } -func runGatewayServer(ctx context.Context, wg *errgroup.Group, config config.Config, store db.Store, taskDistributor worker.TaskDistributor, tokenMaker auth.Maker, userService service.UserService, authService service.AuthService) { - server, err := gapi.NewServer(config, store, taskDistributor, tokenMaker, userService, authService) +func runGatewayServer( + ctx context.Context, + wg *errgroup.Group, + config config.Config, + store db.Store, + td worker.TaskDistributor, + tokenMaker auth.Maker, + userService service.UserService, + authService service.AuthService, + organizationService service.OrganizationService, +) { + server, err := gapi.NewServer(config, store, td, tokenMaker, userService, authService, organizationService) if err != nil { log.Fatal().Err(err).Msg("cannot create server:") } @@ -250,7 +292,7 @@ func runGatewayServer(ctx context.Context, wg *errgroup.Group, config config.Con grpcMux := runtime.NewServeMux(opts) - err = pb.RegisterSimpleBankHandlerServer(ctx, grpcMux, server) + err = pb.Register{{ .ServiceName }}HandlerServer(ctx, grpcMux, server) if err != nil { log.Fatal().Err(err).Msg("cannot register handler server") } @@ -318,6 +360,5 @@ func runGatewayServer(ctx context.Context, wg *errgroup.Group, config config.Con log.Info().Msg("HTTP gateway server shut down") return nil }) - } {{ end }}