fix: restore missing interface methods and cleanup syntax in usecase.go and postgres.go
This commit is contained in:
parent
5464678ae5
commit
fa9ddbdeef
2 changed files with 133 additions and 126 deletions
|
|
@ -1607,6 +1607,8 @@ func (r *Repository) CreateAddress(ctx context.Context, address *domain.Address)
|
||||||
|
|
||||||
_, err := r.db.NamedExecContext(ctx, query, address)
|
_, err := r.db.NamedExecContext(ctx, query, address)
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) ListAddresses(ctx context.Context, entityID uuid.UUID) ([]domain.Address, error) {
|
func (r *Repository) ListAddresses(ctx context.Context, entityID uuid.UUID) ([]domain.Address, error) {
|
||||||
var addresses []domain.Address
|
var addresses []domain.Address
|
||||||
query := `SELECT id, entity_id, title, zip_code, street, number, complement, district, city, state, latitude, longitude, created_at, updated_at FROM addresses WHERE entity_id = $1 ORDER BY created_at DESC`
|
query := `SELECT id, entity_id, title, zip_code, street, number, complement, district, city, state, latitude, longitude, created_at, updated_at FROM addresses WHERE entity_id = $1 ORDER BY created_at DESC`
|
||||||
|
|
@ -1620,10 +1622,6 @@ func (r *Repository) ListAllAddresses(ctx context.Context) ([]domain.Address, er
|
||||||
err := r.db.SelectContext(ctx, &addresses, query)
|
err := r.db.SelectContext(ctx, &addresses, query)
|
||||||
return addresses, err
|
return addresses, err
|
||||||
}
|
}
|
||||||
// If no rows, SelectContext returns nil error but empty slice if initialized, or maybe error?
|
|
||||||
// sqlx returns error if slice is empty? No, SelectContext handles empty result by returning empty slice usually.
|
|
||||||
return addresses, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Repository) GetAddress(ctx context.Context, id uuid.UUID) (*domain.Address, error) {
|
func (r *Repository) GetAddress(ctx context.Context, id uuid.UUID) (*domain.Address, error) {
|
||||||
var addr domain.Address
|
var addr domain.Address
|
||||||
|
|
|
||||||
|
|
@ -1,107 +1,107 @@
|
||||||
package usecase
|
package usecase
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gofrs/uuid/v5"
|
"github.com/gofrs/uuid/v5"
|
||||||
|
|
||||||
"github.com/saveinmed/backend-go/internal/domain"
|
"github.com/saveinmed/backend-go/internal/domain"
|
||||||
"github.com/saveinmed/backend-go/internal/infrastructure/mapbox"
|
"github.com/saveinmed/backend-go/internal/infrastructure/mapbox"
|
||||||
"github.com/saveinmed/backend-go/internal/infrastructure/notifications"
|
"github.com/saveinmed/backend-go/internal/infrastructure/notifications"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Repository defines the persistence contract for all core entities.
|
// Repository defines the persistence contract for all core entities.
|
||||||
// Implementations live in internal/repository/postgres/.
|
|
||||||
type Repository interface {
|
type Repository interface {
|
||||||
CreateCompany(ctx context.Context, company *domain.Company) error
|
CreateCompany(ctx context.Context, company *domain.Company) error
|
||||||
ListCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.Company, int64, error)
|
ListCompanies(ctx context.Context, filter domain.CompanyFilter) ([]domain.Company, int64, error)
|
||||||
GetCompany(ctx context.Context, id uuid.UUID) (*domain.Company, error)
|
GetCompany(ctx context.Context, id uuid.UUID) (*domain.Company, error)
|
||||||
UpdateCompany(ctx context.Context, company *domain.Company) error
|
UpdateCompany(ctx context.Context, company *domain.Company) error
|
||||||
DeleteCompany(ctx context.Context, id uuid.UUID) error
|
DeleteCompany(ctx context.Context, id uuid.UUID) error
|
||||||
|
|
||||||
CreateProduct(ctx context.Context, product *domain.Product) error
|
CreateProduct(ctx context.Context, product *domain.Product) error
|
||||||
BatchCreateProducts(ctx context.Context, products []domain.Product) error
|
BatchCreateProducts(ctx context.Context, products []domain.Product) error
|
||||||
ListProducts(ctx context.Context, filter domain.ProductFilter) ([]domain.Product, int64, error)
|
ListProducts(ctx context.Context, filter domain.ProductFilter) ([]domain.Product, int64, error)
|
||||||
SearchProducts(ctx context.Context, filter domain.ProductSearchFilter) ([]domain.ProductWithDistance, int64, error)
|
SearchProducts(ctx context.Context, filter domain.ProductSearchFilter) ([]domain.ProductWithDistance, int64, error)
|
||||||
ListRecords(ctx context.Context, filter domain.RecordSearchFilter) ([]domain.Product, int64, error)
|
ListRecords(ctx context.Context, filter domain.RecordSearchFilter) ([]domain.Product, int64, error)
|
||||||
GetProduct(ctx context.Context, id uuid.UUID) (*domain.Product, error)
|
GetProduct(ctx context.Context, id uuid.UUID) (*domain.Product, error)
|
||||||
UpdateProduct(ctx context.Context, product *domain.Product) error
|
UpdateProduct(ctx context.Context, product *domain.Product) error
|
||||||
DeleteProduct(ctx context.Context, id uuid.UUID) error
|
DeleteProduct(ctx context.Context, id uuid.UUID) error
|
||||||
AdjustInventory(ctx context.Context, productID uuid.UUID, delta int64, reason string) (*domain.InventoryItem, 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)
|
ListInventory(ctx context.Context, filter domain.InventoryFilter) ([]domain.InventoryItem, int64, error)
|
||||||
CreateInventoryItem(ctx context.Context, item *domain.InventoryItem) error
|
CreateInventoryItem(ctx context.Context, item *domain.InventoryItem) error
|
||||||
GetInventoryItem(ctx context.Context, id uuid.UUID) (*domain.InventoryItem, error)
|
GetInventoryItem(ctx context.Context, id uuid.UUID) (*domain.InventoryItem, error)
|
||||||
UpdateInventoryItem(ctx context.Context, item *domain.InventoryItem) error
|
UpdateInventoryItem(ctx context.Context, item *domain.InventoryItem) error
|
||||||
|
|
||||||
CreateOrder(ctx context.Context, order *domain.Order) error
|
CreateOrder(ctx context.Context, order *domain.Order) error
|
||||||
ListOrders(ctx context.Context, filter domain.OrderFilter) ([]domain.Order, int64, error)
|
ListOrders(ctx context.Context, filter domain.OrderFilter) ([]domain.Order, int64, error)
|
||||||
GetOrder(ctx context.Context, id uuid.UUID) (*domain.Order, error)
|
GetOrder(ctx context.Context, id uuid.UUID) (*domain.Order, error)
|
||||||
UpdateOrderStatus(ctx context.Context, id uuid.UUID, status domain.OrderStatus) error
|
UpdateOrderStatus(ctx context.Context, id uuid.UUID, status domain.OrderStatus) error
|
||||||
DeleteOrder(ctx context.Context, id uuid.UUID) error
|
DeleteOrder(ctx context.Context, id uuid.UUID) error
|
||||||
UpdateOrderItems(ctx context.Context, orderID uuid.UUID, items []domain.OrderItem, totalCents int64) error
|
UpdateOrderItems(ctx context.Context, orderID uuid.UUID, items []domain.OrderItem, totalCents int64) error
|
||||||
CreateShipment(ctx context.Context, shipment *domain.Shipment) error
|
CreateShipment(ctx context.Context, shipment *domain.Shipment) error
|
||||||
GetShipmentByOrderID(ctx context.Context, orderID uuid.UUID) (*domain.Shipment, error)
|
GetShipmentByOrderID(ctx context.Context, orderID uuid.UUID) (*domain.Shipment, error)
|
||||||
|
|
||||||
CreateUser(ctx context.Context, user *domain.User) error
|
CreateUser(ctx context.Context, user *domain.User) error
|
||||||
ListUsers(ctx context.Context, filter domain.UserFilter) ([]domain.User, int64, error)
|
ListUsers(ctx context.Context, filter domain.UserFilter) ([]domain.User, int64, error)
|
||||||
GetUser(ctx context.Context, id uuid.UUID) (*domain.User, error)
|
GetUser(ctx context.Context, id uuid.UUID) (*domain.User, error)
|
||||||
GetUserByUsername(ctx context.Context, username string) (*domain.User, error)
|
GetUserByUsername(ctx context.Context, username string) (*domain.User, error)
|
||||||
GetUserByEmail(ctx context.Context, email string) (*domain.User, error)
|
GetUserByEmail(ctx context.Context, email string) (*domain.User, error)
|
||||||
UpdateUser(ctx context.Context, user *domain.User) error
|
UpdateUser(ctx context.Context, user *domain.User) error
|
||||||
DeleteUser(ctx context.Context, id uuid.UUID) error
|
DeleteUser(ctx context.Context, id uuid.UUID) error
|
||||||
|
|
||||||
AddCartItem(ctx context.Context, item *domain.CartItem) (*domain.CartItem, error)
|
AddCartItem(ctx context.Context, item *domain.CartItem) (*domain.CartItem, error)
|
||||||
ListCartItems(ctx context.Context, buyerID uuid.UUID) ([]domain.CartItem, error)
|
ListCartItems(ctx context.Context, buyerID uuid.UUID) ([]domain.CartItem, error)
|
||||||
DeleteCartItem(ctx context.Context, id uuid.UUID, buyerID uuid.UUID) error
|
DeleteCartItem(ctx context.Context, id uuid.UUID, buyerID uuid.UUID) error
|
||||||
DeleteCartItemByProduct(ctx context.Context, buyerID, productID uuid.UUID) error
|
DeleteCartItemByProduct(ctx context.Context, buyerID, productID uuid.UUID) error
|
||||||
ClearCart(ctx context.Context, buyerID uuid.UUID) error
|
ClearCart(ctx context.Context, buyerID uuid.UUID) error
|
||||||
ReplaceCart(ctx context.Context, buyerID uuid.UUID, items []domain.CartItem) error
|
ReplaceCart(ctx context.Context, buyerID uuid.UUID, items []domain.CartItem) error
|
||||||
|
|
||||||
CreateReview(ctx context.Context, review *domain.Review) error
|
CreateReview(ctx context.Context, review *domain.Review) error
|
||||||
GetCompanyRating(ctx context.Context, companyID uuid.UUID) (*domain.CompanyRating, error)
|
GetCompanyRating(ctx context.Context, companyID uuid.UUID) (*domain.CompanyRating, error)
|
||||||
ListReviews(ctx context.Context, filter domain.ReviewFilter) ([]domain.Review, int64, error)
|
ListReviews(ctx context.Context, filter domain.ReviewFilter) ([]domain.Review, int64, error)
|
||||||
|
|
||||||
SellerDashboard(ctx context.Context, sellerID uuid.UUID) (*domain.SellerDashboard, error)
|
SellerDashboard(ctx context.Context, sellerID uuid.UUID) (*domain.SellerDashboard, error)
|
||||||
AdminDashboard(ctx context.Context, since time.Time) (*domain.AdminDashboard, error)
|
AdminDashboard(ctx context.Context, since time.Time) (*domain.AdminDashboard, error)
|
||||||
|
|
||||||
GetShippingSettings(ctx context.Context, vendorID uuid.UUID) (*domain.ShippingSettings, error)
|
GetShippingSettings(ctx context.Context, vendorID uuid.UUID) (*domain.ShippingSettings, error)
|
||||||
UpsertShippingSettings(ctx context.Context, settings *domain.ShippingSettings) error
|
UpsertShippingSettings(ctx context.Context, settings *domain.ShippingSettings) error
|
||||||
ListShipments(ctx context.Context, filter domain.ShipmentFilter) ([]domain.Shipment, int64, error)
|
ListShipments(ctx context.Context, filter domain.ShipmentFilter) ([]domain.Shipment, int64, error)
|
||||||
|
|
||||||
CreateDocument(ctx context.Context, doc *domain.CompanyDocument) error
|
CreateDocument(ctx context.Context, doc *domain.CompanyDocument) error
|
||||||
ListDocuments(ctx context.Context, companyID uuid.UUID) ([]domain.CompanyDocument, error)
|
ListDocuments(ctx context.Context, companyID uuid.UUID) ([]domain.CompanyDocument, error)
|
||||||
RecordLedgerEntry(ctx context.Context, entry *domain.LedgerEntry) error
|
RecordLedgerEntry(ctx context.Context, entry *domain.LedgerEntry) error
|
||||||
GetLedger(ctx context.Context, companyID uuid.UUID, limit, offset int) ([]domain.LedgerEntry, int64, error)
|
GetLedger(ctx context.Context, companyID uuid.UUID, limit, offset int) ([]domain.LedgerEntry, int64, error)
|
||||||
GetBalance(ctx context.Context, companyID uuid.UUID) (int64, error)
|
GetBalance(ctx context.Context, companyID uuid.UUID) (int64, error)
|
||||||
CreateWithdrawal(ctx context.Context, withdrawal *domain.Withdrawal) error
|
CreateWithdrawal(ctx context.Context, withdrawal *domain.Withdrawal) error
|
||||||
ListWithdrawals(ctx context.Context, companyID uuid.UUID) ([]domain.Withdrawal, error)
|
ListWithdrawals(ctx context.Context, companyID uuid.UUID) ([]domain.Withdrawal, error)
|
||||||
|
|
||||||
// Stock Reservations
|
// Stock Reservations
|
||||||
ReserveStock(ctx context.Context, res *domain.StockReservation) error
|
ReserveStock(ctx context.Context, res *domain.StockReservation) error
|
||||||
CompleteReservation(ctx context.Context, reservationID uuid.UUID) error
|
CompleteReservation(ctx context.Context, reservationID uuid.UUID) error
|
||||||
ExpireReservations(ctx context.Context) error
|
ExpireReservations(ctx context.Context) error
|
||||||
GetActiveReservations(ctx context.Context, inventoryItemID uuid.UUID) (int64, error)
|
GetActiveReservations(ctx context.Context, inventoryItemID uuid.UUID) (int64, error)
|
||||||
|
|
||||||
GetPaymentGatewayConfig(ctx context.Context, provider string) (*domain.PaymentGatewayConfig, error)UpsertPaymentGatewayConfig(ctx context.Context, config *domain.PaymentGatewayConfig) error
|
GetPaymentGatewayConfig(ctx context.Context, provider string) (*domain.PaymentGatewayConfig, error)
|
||||||
GetSellerPaymentAccount(ctx context.Context, sellerID uuid.UUID) (*domain.SellerPaymentAccount, error)
|
UpsertPaymentGatewayConfig(ctx context.Context, config *domain.PaymentGatewayConfig) error
|
||||||
UpsertSellerPaymentAccount(ctx context.Context, account *domain.SellerPaymentAccount) 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
|
CreateAddress(ctx context.Context, address *domain.Address) error
|
||||||
ListAddresses(ctx context.Context, entityID uuid.UUID) ([]domain.Address, error)
|
ListAddresses(ctx context.Context, entityID uuid.UUID) ([]domain.Address, error)
|
||||||
GetAddress(ctx context.Context, id uuid.UUID) (*domain.Address, error)
|
ListAllAddresses(ctx context.Context) ([]domain.Address, error)
|
||||||
UpdateAddress(ctx context.Context, address *domain.Address) error
|
GetAddress(ctx context.Context, id uuid.UUID) (*domain.Address, error)
|
||||||
DeleteAddress(ctx context.Context, id uuid.UUID) error
|
UpdateAddress(ctx context.Context, address *domain.Address) error
|
||||||
ListAllAddresses(ctx context.Context) ([]domain.Address, error)
|
DeleteAddress(ctx context.Context, id uuid.UUID) error
|
||||||
GeocodeAllAddresses(ctx context.Context) (int, error)
|
GeocodeAllAddresses(ctx context.Context) (int, error)
|
||||||
|
StartStockCleanupWorker(ctx context.Context)
|
||||||
|
|
||||||
ListManufacturers(ctx context.Context) ([]string, error)
|
ListManufacturers(ctx context.Context) ([]string, error)
|
||||||
ListCategories(ctx context.Context) ([]string, error)
|
ListCategories(ctx context.Context) ([]string, error)
|
||||||
GetProductByEAN(ctx context.Context, ean string) (*domain.Product, error)
|
GetProductByEAN(ctx context.Context, ean string) (*domain.Product, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaymentGateway abstracts the payment provider (Mercado Pago, Asaas, etc.).
|
// PaymentGateway abstracts the payment provider (Mercado Pago, Asaas, etc.).
|
||||||
// Implementations live in internal/infrastructure/payments/.
|
|
||||||
type PaymentGateway interface {
|
type PaymentGateway interface {
|
||||||
CreatePreference(ctx context.Context, order *domain.Order, payer *domain.User, sellerAcc *domain.SellerPaymentAccount) (*domain.PaymentPreference, error)
|
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)
|
CreatePayment(ctx context.Context, order *domain.Order, token, issuerID, paymentMethodID string, installments int, payer *domain.User, sellerAcc *domain.SellerPaymentAccount) (*domain.PaymentResult, error)
|
||||||
|
|
@ -109,61 +109,70 @@ type PaymentGateway interface {
|
||||||
CreateBoletoPayment(ctx context.Context, order *domain.Order, payer *domain.User) (*domain.BoletoPaymentResult, error)
|
CreateBoletoPayment(ctx context.Context, order *domain.Order, payer *domain.User) (*domain.BoletoPaymentResult, error)
|
||||||
GetPaymentStatus(ctx context.Context, paymentID string) (*domain.PaymentWebhookEvent, error)
|
GetPaymentStatus(ctx context.Context, paymentID string) (*domain.PaymentWebhookEvent, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service orchestrates all business use cases.
|
// 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 {
|
type Service struct {
|
||||||
repo Repository
|
repo Repository
|
||||||
pay PaymentGateway
|
pay PaymentGateway
|
||||||
mapbox *mapbox.Client
|
mapbox *mapbox.Client
|
||||||
notify notifications.NotificationService
|
notify notifications.NotificationService
|
||||||
marketplaceCommission float64
|
marketplaceCommission float64
|
||||||
buyerFeeRate float64
|
buyerFeeRate float64
|
||||||
jwtSecret []byte
|
jwtSecret []byte
|
||||||
tokenTTL time.Duration
|
tokenTTL time.Duration
|
||||||
passwordPepper string
|
passwordPepper string
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// passwordResetTTL is the validity window for password-reset JWTs.
|
// passwordResetTTL is the validity window for password-reset JWTs.
|
||||||
passwordResetTTL = 30 * time.Minute
|
passwordResetTTL = 30 * time.Minute
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewService wires all dependencies and returns a ready-to-use Service.
|
// NewService wires all dependencies and returns a ready-to-use Service.
|
||||||
func NewService(
|
func NewService(
|
||||||
repo Repository,
|
repo Repository,
|
||||||
pg PaymentGateway,
|
pg PaymentGateway,
|
||||||
mb *mapbox.Client,
|
mb *mapbox.Client,
|
||||||
notify notifications.NotificationService,
|
notify notifications.NotificationService,
|
||||||
commission, buyerFeeRate float64,
|
commission, buyerFeeRate float64,
|
||||||
jwtSecret string,
|
jwtSecret string,
|
||||||
tokenTTL time.Duration,
|
tokenTTL time.Duration,
|
||||||
pepper string,
|
pepper string,
|
||||||
) *Service {
|
) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
pay: pg,
|
pay: pg,
|
||||||
mapbox: mb,
|
mapbox: mb,
|
||||||
notify: notify,
|
notify: notify,
|
||||||
marketplaceCommission: commission,
|
marketplaceCommission: commission,
|
||||||
buyerFeeRate: buyerFeeRate,
|
buyerFeeRate: buyerFeeRate,
|
||||||
jwtSecret: []byte(jwtSecret),
|
jwtSecret: []byte(jwtSecret),
|
||||||
tokenTTL: tokenTTL,
|
tokenTTL: tokenTTL,
|
||||||
passwordPepper: pepper,
|
passwordPepper: pepper,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNotificationService exposes the notification service for push handlers.
|
// GetNotificationService exposes the notification service for push handlers.
|
||||||
func (s *Service) GetNotificationService() notifications.NotificationService {
|
func (s *Service) GetNotificationService() notifications.NotificationService {
|
||||||
return s.notify
|
return s.notify
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteAddress handles address removal logic.
|
||||||
|
func (s *Service) DeleteAddress(ctx context.Context, id uuid.UUID) error {
|
||||||
|
return s.repo.DeleteAddress(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListManufacturers returns manufacturers from the repo.
|
||||||
|
func (s *Service) ListManufacturers(ctx context.Context) ([]string, error) {
|
||||||
|
return s.repo.ListManufacturers(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCategories returns categories from the repo.
|
||||||
|
func (s *Service) ListCategories(ctx context.Context) ([]string, error) {
|
||||||
|
return s.repo.ListCategories(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProductByEAN finds a product by its EAN code.
|
||||||
|
func (s *Service) GetProductByEAN(ctx context.Context, ean string) (*domain.Product, error) {
|
||||||
|
return s.repo.GetProductByEAN(ctx, ean)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue