Files
bot-pontos/backend/internal/bootstrap/bootstrap.go
2026-10-23 22:31:02 -03:00

61 lines
1.7 KiB
Go

// Package bootstrap é o composition root: monta o app.Service com os adapters
// reais. Usado pela api, pelo worker e pela CLI.
package bootstrap
import (
"context"
"fmt"
"log/slog"
"github.com/jackc/pgx/v5/pgxpool"
"botpontos/internal/adapters/crypto"
"botpontos/internal/adapters/feriados"
"botpontos/internal/adapters/pontomais"
"botpontos/internal/adapters/postgres"
"botpontos/internal/adapters/telegram"
"botpontos/internal/app"
"botpontos/internal/config"
)
// Built é o serviço montado com todos os adapters reais.
type Built struct {
Service *app.Service
Pool *pgxpool.Pool
Telegram *telegram.Client
}
// Build abre o banco e monta o serviço com os adapters reais.
func Build(ctx context.Context, cfg config.Config, logger *slog.Logger) (*Built, error) {
if err := cfg.RequireCrypto(); err != nil {
return nil, err
}
keyring, err := crypto.NewKeyring(cfg.Crypto.Key, int16(cfg.Crypto.KeyVersion),
cfg.Crypto.PreviousKey, int16(cfg.Crypto.PreviousKeyVersion))
if err != nil {
return nil, fmt.Errorf("chave de criptografia: %w", err)
}
pool, err := postgres.OpenPool(ctx, cfg.DB, logger)
if err != nil {
return nil, err
}
tg := telegram.NewClient(cfg.Telegram.Token)
var holidays app.HolidayProvider
if client := feriados.NewClient(cfg.Holidays.BaseURL, cfg.Holidays.APIKey, cfg.Holidays.Location); client.Configured() {
holidays = client
}
svc := app.New(app.Deps{
Store: postgres.NewStore(pool),
Points: pontomais.NewClient(cfg.PontoMais.AuthURL, cfg.PontoMais.HistoryURL, cfg.PontoMais.Timeout, keyring),
Messenger: tg,
Holidays: holidays,
Cipher: keyring,
Config: cfg,
Logger: logger,
})
return &Built{Service: svc, Pool: pool, Telegram: tg}, nil
}