rentease/main.go
Ruidy 146787033a
refactor(payment): extract payment logic to new service
Moves all payment-related logic (manual payments, Stripe sync, webhook
handling) from the booking service into a dedicated payment service
(`internal/service/payment`). Updates server, cron, and handler wiring
to
inject and use the new payment service. Adjusts tests, routes, and
documentation to reflect the new separation of concerns.

This improves cohesion, clarifies responsibilities, and prepares for
future payment features. No database schema changes are introduced.
2025-11-21 10:09:30 +01:00

130 lines
3.5 KiB
Go

package main
import (
"context"
"fmt"
"log/slog"
"os"
"os/signal"
"github.com/getsentry/sentry-go"
"github.com/rjNemo/rentease/assets"
"github.com/rjNemo/rentease/internal/config"
"github.com/rjNemo/rentease/internal/driver/database"
"github.com/rjNemo/rentease/internal/driver/logger"
"github.com/rjNemo/rentease/internal/driver/parser"
"github.com/rjNemo/rentease/internal/driver/pdf"
stripeclient "github.com/rjNemo/rentease/internal/driver/stripe"
bookingRepo "github.com/rjNemo/rentease/internal/repository/booking"
"github.com/rjNemo/rentease/internal/server"
"github.com/rjNemo/rentease/internal/service/auth"
"github.com/rjNemo/rentease/internal/service/booking"
"github.com/rjNemo/rentease/internal/service/payment"
)
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
baseLogger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{AddSource: true}))
appConfig, err := config.New(ctx)
if err != nil {
baseLogger.Error("configuration error", slog.Any("error", err))
}
appLogger := logger.New(appConfig.LogLevel)
slog.SetDefault(appLogger)
if err := run(ctx, appConfig, appLogger); err != nil {
appLogger.Error("server exited", slog.Any("error", err))
os.Exit(1)
}
}
func run(ctx context.Context, appConfig *config.Config, appLogger *slog.Logger) error {
// init sentry
if err := sentry.Init(sentry.ClientOptions{
Dsn: appConfig.SentryDsn,
EnableTracing: true,
TracesSampleRate: 1.0,
}); err != nil {
return fmt.Errorf("error initializing sentry %w", err)
}
// init database
db, err := database.New(appConfig.DatabaseURL)
if err != nil {
return fmt.Errorf("error connecting to the database %w", err)
}
if err = database.Migrate(db, &booking.Booking{}, &booking.Item{}, &booking.Payment{}); err != nil {
return fmt.Errorf("error migrating the database %w", err)
}
bookingStore := bookingRepo.NewPgStore(db)
// build pdf client
pc, err := pdf.NewPdfClient()
if err != nil {
return fmt.Errorf("error starting pdf client %w", err)
}
parsingClient := parser.NewBookingAgentParser()
var stripeClient payment.StripeClient
if appConfig.StripeSecretKey != "" {
opts := []stripeclient.Option{}
client, err := stripeclient.New(appConfig.StripeSecretKey, opts...)
if err != nil {
return fmt.Errorf("error creating stripe client: %w", err)
}
stripeClient = client
}
bookingService, err := booking.NewService(appLogger, bookingStore, parsingClient, pc)
if err != nil {
return fmt.Errorf("error creating booking service: %w", err)
}
paymentService, err := payment.NewService(appLogger, bookingStore, stripeClient)
if err != nil {
return fmt.Errorf("error creating payment service: %w", err)
}
// build authentication service
as, err := auth.NewService(
appConfig.SessionSecret,
appConfig.Admin,
appConfig.AdminSecret,
appConfig.APIKey,
)
if err != nil {
return fmt.Errorf("error starting auth service %w", err)
}
port := appConfig.Port
origins := appConfig.Origins
srv, err := server.New(
bookingService,
paymentService,
as,
config.NewHost(), // TODO: move to the database at some point
server.WithPort(port),
server.WithFileSystem(assets.Static),
server.WithDebug(appConfig.Debug),
server.WithSecretKey(appConfig.SecretKey),
server.WithOrigins(origins),
server.WithStripeWebhookSecret(appConfig.StripeWebhookSecret),
)
if err != nil {
return fmt.Errorf("error starting server %w", err)
}
srv.Start(ctx)
return nil
}