rentease/main.go

126 lines
3.4 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"
)
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 booking.StripeClient
if appConfig.StripeSecretKey != "" {
opts := []stripeclient.Option{}
if appConfig.StripeConnectAccount != "" {
opts = append(opts, stripeclient.WithAccount(appConfig.StripeConnectAccount))
}
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, stripeClient)
if err != nil {
return fmt.Errorf("error creating booking 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,
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
}