mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
Introduce Stripe integration for automatic payment ingestion and refund tracking. Adds new fields to the payment model for Stripe IDs and status, Stripe client driver, sync service, cron job, manual API endpoint, and public webhook handler for real-time updates. Includes tests and documentation. Manual cash entry remains supported.
126 lines
3.4 KiB
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
|
|
}
|