166 lines
5.5 KiB
Go
166 lines
5.5 KiB
Go
package processor
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"apskel-pos-be/internal/entities"
|
|
"apskel-pos-be/internal/mappers"
|
|
"apskel-pos-be/internal/models"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type UserDeviceRepository interface {
|
|
Create(ctx context.Context, device *entities.UserDevice) error
|
|
GetByID(ctx context.Context, id uuid.UUID) (*entities.UserDevice, error)
|
|
GetByDeviceID(ctx context.Context, deviceID string, userID uuid.UUID) (*entities.UserDevice, error)
|
|
GetByUserID(ctx context.Context, userID uuid.UUID) ([]*entities.UserDevice, error)
|
|
Update(ctx context.Context, device *entities.UserDevice) error
|
|
Delete(ctx context.Context, id uuid.UUID) error
|
|
DeleteByUserID(ctx context.Context, userID uuid.UUID) error
|
|
List(ctx context.Context, filters map[string]interface{}, limit, offset int) ([]*entities.UserDevice, int64, error)
|
|
}
|
|
|
|
type UserDeviceProcessor interface {
|
|
RegisterDevice(ctx context.Context, req *models.RegisterUserDeviceRequest) (*models.UserDeviceResponse, error)
|
|
UpdateDevice(ctx context.Context, id uuid.UUID, req *models.UpdateUserDeviceRequest) (*models.UserDeviceResponse, error)
|
|
DeleteDevice(ctx context.Context, id uuid.UUID) error
|
|
GetDeviceByID(ctx context.Context, id uuid.UUID) (*models.UserDeviceResponse, error)
|
|
GetDevicesByUserID(ctx context.Context, userID uuid.UUID) ([]*models.UserDeviceResponse, error)
|
|
ListDevices(ctx context.Context, filters map[string]interface{}, page, limit int) ([]*models.UserDeviceResponse, int, error)
|
|
}
|
|
|
|
type UserDeviceProcessorImpl struct {
|
|
userDeviceRepo UserDeviceRepository
|
|
}
|
|
|
|
func NewUserDeviceProcessorImpl(userDeviceRepo UserDeviceRepository) *UserDeviceProcessorImpl {
|
|
return &UserDeviceProcessorImpl{
|
|
userDeviceRepo: userDeviceRepo,
|
|
}
|
|
}
|
|
|
|
func (p *UserDeviceProcessorImpl) RegisterDevice(ctx context.Context, req *models.RegisterUserDeviceRequest) (*models.UserDeviceResponse, error) {
|
|
// Upsert: if device already registered for this user, update it
|
|
existing, err := p.userDeviceRepo.GetByDeviceID(ctx, req.DeviceID, req.UserID)
|
|
if err == nil && existing != nil {
|
|
existing.DeviceName = req.DeviceName
|
|
existing.DeviceType = req.DeviceType
|
|
existing.Platform = req.Platform
|
|
existing.FCMToken = req.FCMToken
|
|
existing.AppVersion = req.AppVersion
|
|
existing.OsVersion = req.OsVersion
|
|
existing.IPAddress = req.IPAddress
|
|
now := time.Now()
|
|
existing.LastActiveAt = &now
|
|
|
|
if err := p.userDeviceRepo.Update(ctx, existing); err != nil {
|
|
return nil, fmt.Errorf("failed to update device: %w", err)
|
|
}
|
|
|
|
return mappers.UserDeviceEntityToResponse(existing), nil
|
|
}
|
|
|
|
deviceEntity := &entities.UserDevice{
|
|
UserID: req.UserID,
|
|
DeviceID: req.DeviceID,
|
|
DeviceName: req.DeviceName,
|
|
DeviceType: req.DeviceType,
|
|
Platform: req.Platform,
|
|
FCMToken: req.FCMToken,
|
|
AppVersion: req.AppVersion,
|
|
OsVersion: req.OsVersion,
|
|
IPAddress: req.IPAddress,
|
|
}
|
|
|
|
now := time.Now()
|
|
deviceEntity.LastActiveAt = &now
|
|
|
|
if err := p.userDeviceRepo.Create(ctx, deviceEntity); err != nil {
|
|
return nil, fmt.Errorf("failed to register device: %w", err)
|
|
}
|
|
|
|
return mappers.UserDeviceEntityToResponse(deviceEntity), nil
|
|
}
|
|
|
|
func (p *UserDeviceProcessorImpl) UpdateDevice(ctx context.Context, id uuid.UUID, req *models.UpdateUserDeviceRequest) (*models.UserDeviceResponse, error) {
|
|
deviceEntity, err := p.userDeviceRepo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("device not found: %w", err)
|
|
}
|
|
|
|
if req.DeviceName != "" {
|
|
deviceEntity.DeviceName = req.DeviceName
|
|
}
|
|
if req.DeviceType != "" {
|
|
deviceEntity.DeviceType = req.DeviceType
|
|
}
|
|
if req.Platform != "" {
|
|
deviceEntity.Platform = req.Platform
|
|
}
|
|
if req.FCMToken != "" {
|
|
deviceEntity.FCMToken = req.FCMToken
|
|
}
|
|
if req.AppVersion != "" {
|
|
deviceEntity.AppVersion = req.AppVersion
|
|
}
|
|
if req.OsVersion != "" {
|
|
deviceEntity.OsVersion = req.OsVersion
|
|
}
|
|
|
|
now := time.Now()
|
|
deviceEntity.LastActiveAt = &now
|
|
|
|
if err := p.userDeviceRepo.Update(ctx, deviceEntity); err != nil {
|
|
return nil, fmt.Errorf("failed to update device: %w", err)
|
|
}
|
|
|
|
return mappers.UserDeviceEntityToResponse(deviceEntity), nil
|
|
}
|
|
|
|
func (p *UserDeviceProcessorImpl) DeleteDevice(ctx context.Context, id uuid.UUID) error {
|
|
_, err := p.userDeviceRepo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return fmt.Errorf("device not found: %w", err)
|
|
}
|
|
|
|
if err := p.userDeviceRepo.Delete(ctx, id); err != nil {
|
|
return fmt.Errorf("failed to delete device: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p *UserDeviceProcessorImpl) GetDeviceByID(ctx context.Context, id uuid.UUID) (*models.UserDeviceResponse, error) {
|
|
deviceEntity, err := p.userDeviceRepo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("device not found: %w", err)
|
|
}
|
|
|
|
return mappers.UserDeviceEntityToResponse(deviceEntity), nil
|
|
}
|
|
|
|
func (p *UserDeviceProcessorImpl) GetDevicesByUserID(ctx context.Context, userID uuid.UUID) ([]*models.UserDeviceResponse, error) {
|
|
deviceEntities, err := p.userDeviceRepo.GetByUserID(ctx, userID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get devices: %w", err)
|
|
}
|
|
|
|
return mappers.UserDeviceEntitiesToResponses(deviceEntities), nil
|
|
}
|
|
|
|
func (p *UserDeviceProcessorImpl) ListDevices(ctx context.Context, filters map[string]interface{}, page, limit int) ([]*models.UserDeviceResponse, int, error) {
|
|
offset := (page - 1) * limit
|
|
deviceEntities, total, err := p.userDeviceRepo.List(ctx, filters, limit, offset)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("failed to list devices: %w", err)
|
|
}
|
|
|
|
deviceResponses := mappers.UserDeviceEntitiesToResponses(deviceEntities)
|
|
totalPages := int((total + int64(limit) - 1) / int64(limit))
|
|
|
|
return deviceResponses, totalPages, nil
|
|
}
|