saveinmed/backend/internal/usecase/usecase.go
caio-machado-dev bf85072bff chore: remove legacy services and restructure monorepo
- remove backend-old (Medusa), saveinmed-frontend (Next.js/Appwrite) and marketplace dirs
- split Go usecases by domain and move notifications/payments to infrastructure
- reorganize frontend pages into auth, dashboard and marketplace modules
- add Makefile, docker-compose.yml and architecture docs
2026-02-25 16:51:34 -03:00

160 lines
8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package usecase
import (
"context"
"time"
"github.com/gofrs/uuid/v5"
"github.com/saveinmed/backend-go/internal/domain"
"github.com/saveinmed/backend-go/internal/infrastructure/mapbox"
"github.com/saveinmed/backend-go/internal/infrastructure/notifications"
)
// Repository defines the persistence contract for all core entities.
// Implementations live in internal/repository/postgres/.
type Repository interface {
CreateCompany(ctx context.Context, company *domain.Company) error
ListCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.Company, int64, error)
GetCompany(ctx context.Context, id uuid.UUID) (*domain.Company, error)
UpdateCompany(ctx context.Context, company *domain.Company) error
DeleteCompany(ctx context.Context, id uuid.UUID) error
CreateProduct(ctx context.Context, product *domain.Product) error
BatchCreateProducts(ctx context.Context, products []domain.Product) error
ListProducts(ctx context.Context, filter domain.ProductFilter) ([]domain.Product, int64, error)
SearchProducts(ctx context.Context, filter domain.ProductSearchFilter) ([]domain.ProductWithDistance, int64, error)
ListRecords(ctx context.Context, filter domain.RecordSearchFilter) ([]domain.Product, int64, error)
GetProduct(ctx context.Context, id uuid.UUID) (*domain.Product, error)
UpdateProduct(ctx context.Context, product *domain.Product) error
DeleteProduct(ctx context.Context, id uuid.UUID) error
AdjustInventory(ctx context.Context, productID uuid.UUID, delta int64, reason string) (*domain.InventoryItem, error)
ListInventory(ctx context.Context, filter domain.InventoryFilter) ([]domain.InventoryItem, int64, error)
CreateInventoryItem(ctx context.Context, item *domain.InventoryItem) error
GetInventoryItem(ctx context.Context, id uuid.UUID) (*domain.InventoryItem, error)
UpdateInventoryItem(ctx context.Context, item *domain.InventoryItem) error
CreateOrder(ctx context.Context, order *domain.Order) error
ListOrders(ctx context.Context, filter domain.OrderFilter) ([]domain.Order, int64, error)
GetOrder(ctx context.Context, id uuid.UUID) (*domain.Order, error)
UpdateOrderStatus(ctx context.Context, id uuid.UUID, status domain.OrderStatus) error
DeleteOrder(ctx context.Context, id uuid.UUID) error
UpdateOrderItems(ctx context.Context, orderID uuid.UUID, items []domain.OrderItem, totalCents int64) error
CreateShipment(ctx context.Context, shipment *domain.Shipment) error
GetShipmentByOrderID(ctx context.Context, orderID uuid.UUID) (*domain.Shipment, error)
CreateUser(ctx context.Context, user *domain.User) error
ListUsers(ctx context.Context, filter domain.UserFilter) ([]domain.User, int64, error)
GetUser(ctx context.Context, id uuid.UUID) (*domain.User, error)
GetUserByUsername(ctx context.Context, username string) (*domain.User, error)
GetUserByEmail(ctx context.Context, email string) (*domain.User, error)
UpdateUser(ctx context.Context, user *domain.User) error
DeleteUser(ctx context.Context, id uuid.UUID) error
AddCartItem(ctx context.Context, item *domain.CartItem) (*domain.CartItem, error)
ListCartItems(ctx context.Context, buyerID uuid.UUID) ([]domain.CartItem, error)
DeleteCartItem(ctx context.Context, id uuid.UUID, buyerID uuid.UUID) error
DeleteCartItemByProduct(ctx context.Context, buyerID, productID uuid.UUID) error
ClearCart(ctx context.Context, buyerID uuid.UUID) error
ReplaceCart(ctx context.Context, buyerID uuid.UUID, items []domain.CartItem) error
CreateReview(ctx context.Context, review *domain.Review) error
GetCompanyRating(ctx context.Context, companyID uuid.UUID) (*domain.CompanyRating, error)
ListReviews(ctx context.Context, filter domain.ReviewFilter) ([]domain.Review, int64, error)
SellerDashboard(ctx context.Context, sellerID uuid.UUID) (*domain.SellerDashboard, error)
AdminDashboard(ctx context.Context, since time.Time) (*domain.AdminDashboard, error)
GetShippingSettings(ctx context.Context, vendorID uuid.UUID) (*domain.ShippingSettings, error)
UpsertShippingSettings(ctx context.Context, settings *domain.ShippingSettings) error
ListShipments(ctx context.Context, filter domain.ShipmentFilter) ([]domain.Shipment, int64, error)
CreateDocument(ctx context.Context, doc *domain.CompanyDocument) error
ListDocuments(ctx context.Context, companyID uuid.UUID) ([]domain.CompanyDocument, error)
RecordLedgerEntry(ctx context.Context, entry *domain.LedgerEntry) error
GetLedger(ctx context.Context, companyID uuid.UUID, limit, offset int) ([]domain.LedgerEntry, int64, error)
GetBalance(ctx context.Context, companyID uuid.UUID) (int64, error)
CreateWithdrawal(ctx context.Context, withdrawal *domain.Withdrawal) error
ListWithdrawals(ctx context.Context, companyID uuid.UUID) ([]domain.Withdrawal, error)
GetPaymentGatewayConfig(ctx context.Context, provider string) (*domain.PaymentGatewayConfig, error)
UpsertPaymentGatewayConfig(ctx context.Context, config *domain.PaymentGatewayConfig) error
GetSellerPaymentAccount(ctx context.Context, sellerID uuid.UUID) (*domain.SellerPaymentAccount, error)
UpsertSellerPaymentAccount(ctx context.Context, account *domain.SellerPaymentAccount) error
CreateAddress(ctx context.Context, address *domain.Address) error
ListAddresses(ctx context.Context, entityID uuid.UUID) ([]domain.Address, error)
GetAddress(ctx context.Context, id uuid.UUID) (*domain.Address, error)
UpdateAddress(ctx context.Context, address *domain.Address) error
DeleteAddress(ctx context.Context, id uuid.UUID) error
ListManufacturers(ctx context.Context) ([]string, error)
ListCategories(ctx context.Context) ([]string, error)
GetProductByEAN(ctx context.Context, ean string) (*domain.Product, error)
}
// PaymentGateway abstracts the payment provider (Mercado Pago, Asaas, etc.).
// Implementations live in internal/infrastructure/payments/.
type PaymentGateway interface {
CreatePreference(ctx context.Context, order *domain.Order, payer *domain.User, sellerAcc *domain.SellerPaymentAccount) (*domain.PaymentPreference, error)
CreatePayment(ctx context.Context, order *domain.Order, token, issuerID, paymentMethodID string, installments int, payer *domain.User, sellerAcc *domain.SellerPaymentAccount) (*domain.PaymentResult, error)
}
// Service orchestrates all business use cases.
// Methods are split across domain-specific files in this package:
// - auth_usecase.go authentication, JWT, password reset
// - company_usecase.go company registration, KYC, shipping options
// - product_usecase.go catalogue, inventory management
// - order_usecase.go order lifecycle and state machine
// - shipping_usecase.go shipping calculation and configuration
// - cart_usecase.go cart operations and B2B discounts
// - payment_usecase.go payment preferences and webhook handling
// - review_usecase.go buyer reviews and ratings
// - user_usecase.go user CRUD
// - address_usecase.go address management
// - dashboard_usecase.go seller and admin KPI dashboards
type Service struct {
repo Repository
pay PaymentGateway
mapbox *mapbox.Client
notify notifications.NotificationService
marketplaceCommission float64
buyerFeeRate float64
jwtSecret []byte
tokenTTL time.Duration
passwordPepper string
}
const (
// passwordResetTTL is the validity window for password-reset JWTs.
passwordResetTTL = 30 * time.Minute
)
// NewService wires all dependencies and returns a ready-to-use Service.
func NewService(
repo Repository,
pg PaymentGateway,
mb *mapbox.Client,
notify notifications.NotificationService,
commission, buyerFeeRate float64,
jwtSecret string,
tokenTTL time.Duration,
pepper string,
) *Service {
return &Service{
repo: repo,
pay: pg,
mapbox: mb,
notify: notify,
marketplaceCommission: commission,
buyerFeeRate: buyerFeeRate,
jwtSecret: []byte(jwtSecret),
tokenTTL: tokenTTL,
passwordPepper: pepper,
}
}
// GetNotificationService exposes the notification service for push handlers.
func (s *Service) GetNotificationService() notifications.NotificationService {
return s.notify
}