mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
212 lines
6.1 KiB
Go
212 lines
6.1 KiB
Go
package service
|
|
|
|
import (
|
|
"bugulma/backend/internal/domain"
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/datatypes"
|
|
)
|
|
|
|
// Context keys for extracting user/org info from context
|
|
type contextKey string
|
|
|
|
const (
|
|
userIDKey contextKey = "user_id"
|
|
orgIDKey contextKey = "org_id"
|
|
)
|
|
|
|
// getUserFromContext extracts user ID from context
|
|
func getUserFromContext(ctx context.Context) string {
|
|
if userID, ok := ctx.Value(userIDKey).(string); ok {
|
|
return userID
|
|
}
|
|
return "system" // Default fallback
|
|
}
|
|
|
|
// getOrgFromContext extracts organization ID from context
|
|
func getOrgFromContext(ctx context.Context) string {
|
|
if orgID, ok := ctx.Value(orgIDKey).(string); ok {
|
|
return orgID
|
|
}
|
|
return "" // Will be determined from entity
|
|
}
|
|
|
|
// ResourceFlowService handles business logic for resource flows
|
|
type ResourceFlowService struct {
|
|
repo domain.ResourceFlowRepository
|
|
eventBus domain.EventBus
|
|
}
|
|
|
|
// NewResourceFlowService creates a new resource flow service
|
|
func NewResourceFlowService(repo domain.ResourceFlowRepository, eventBus domain.EventBus) *ResourceFlowService {
|
|
return &ResourceFlowService{
|
|
repo: repo,
|
|
eventBus: eventBus,
|
|
}
|
|
}
|
|
|
|
// CreateResourceFlowRequest represents the request to create a resource flow
|
|
type CreateResourceFlowRequest struct {
|
|
OrganizationID string
|
|
SiteID string
|
|
Direction domain.ResourceDirection
|
|
Type domain.ResourceType
|
|
Quality domain.Quality
|
|
Quantity domain.Quantity
|
|
TimeProfile domain.TimeProfile
|
|
EconomicData domain.EconomicData
|
|
Constraints domain.Constraints
|
|
ServiceDetails domain.ServiceDetails
|
|
PrecisionLevel domain.PrecisionLevel
|
|
SourceType domain.SourceType
|
|
}
|
|
|
|
// Create creates a new resource flow
|
|
func (s *ResourceFlowService) Create(ctx context.Context, req CreateResourceFlowRequest) (*domain.ResourceFlow, error) {
|
|
qualityJSON, _ := json.Marshal(req.Quality)
|
|
quantityJSON, _ := json.Marshal(req.Quantity)
|
|
timeProfileJSON, _ := json.Marshal(req.TimeProfile)
|
|
economicDataJSON, _ := json.Marshal(req.EconomicData)
|
|
constraintsJSON, _ := json.Marshal(req.Constraints)
|
|
serviceDetailsJSON, _ := json.Marshal(req.ServiceDetails)
|
|
|
|
rf := &domain.ResourceFlow{
|
|
ID: uuid.New().String(),
|
|
OrganizationID: req.OrganizationID,
|
|
SiteID: req.SiteID,
|
|
Direction: req.Direction,
|
|
Type: req.Type,
|
|
Quality: datatypes.JSON(qualityJSON),
|
|
Quantity: datatypes.JSON(quantityJSON),
|
|
TimeProfile: datatypes.JSON(timeProfileJSON),
|
|
EconomicData: datatypes.JSON(economicDataJSON),
|
|
Constraints: datatypes.JSON(constraintsJSON),
|
|
ServiceDetails: datatypes.JSON(serviceDetailsJSON),
|
|
PrecisionLevel: req.PrecisionLevel,
|
|
SourceType: req.SourceType,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
if err := s.repo.Create(ctx, rf); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Publish event
|
|
userID := getUserFromContext(ctx)
|
|
if s.eventBus != nil {
|
|
event := domain.Event{
|
|
Type: domain.EventTypeResourceFlowCreated,
|
|
EntityID: rf.ID,
|
|
OrgID: rf.OrganizationID,
|
|
UserID: userID,
|
|
Timestamp: time.Now(),
|
|
Payload: map[string]interface{}{
|
|
"resource_type": string(rf.Type),
|
|
"direction": string(rf.Direction),
|
|
"site_id": rf.SiteID,
|
|
},
|
|
}
|
|
if err := s.eventBus.Publish(event); err != nil {
|
|
// Log error but don't fail the operation
|
|
// Event publishing should not block the main operation
|
|
// TODO: Add proper logging here
|
|
}
|
|
}
|
|
|
|
return rf, nil
|
|
}
|
|
|
|
// GetByID retrieves a resource flow by ID
|
|
func (s *ResourceFlowService) GetByID(ctx context.Context, id string) (*domain.ResourceFlow, error) {
|
|
return s.repo.GetByID(ctx, id)
|
|
}
|
|
|
|
// GetBySiteID retrieves resource flows at a specific site
|
|
func (s *ResourceFlowService) GetBySiteID(ctx context.Context, siteID string) ([]*domain.ResourceFlow, error) {
|
|
return s.repo.GetBySiteID(ctx, siteID)
|
|
}
|
|
|
|
// GetByOrganizationID retrieves resource flows owned by an organization
|
|
func (s *ResourceFlowService) GetByOrganizationID(ctx context.Context, organizationID string) ([]*domain.ResourceFlow, error) {
|
|
return s.repo.GetByOrganizationID(ctx, organizationID)
|
|
}
|
|
|
|
// List retrieves all resource flows with optional filtering
|
|
func (s *ResourceFlowService) List(ctx context.Context) ([]*domain.ResourceFlow, error) {
|
|
return s.repo.GetAll(ctx)
|
|
}
|
|
|
|
// GetByTypeAndDirection retrieves resource flows by type and direction
|
|
func (s *ResourceFlowService) GetByTypeAndDirection(ctx context.Context, resType domain.ResourceType, direction domain.ResourceDirection) ([]*domain.ResourceFlow, error) {
|
|
return s.repo.GetByTypeAndDirection(ctx, resType, direction)
|
|
}
|
|
|
|
// Update updates a resource flow
|
|
func (s *ResourceFlowService) Update(ctx context.Context, rf *domain.ResourceFlow) error {
|
|
rf.UpdatedAt = time.Now()
|
|
if err := s.repo.Update(ctx, rf); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Publish event
|
|
userID := getUserFromContext(ctx)
|
|
if s.eventBus != nil {
|
|
event := domain.Event{
|
|
Type: domain.EventTypeResourceFlowUpdated,
|
|
EntityID: rf.ID,
|
|
OrgID: rf.OrganizationID,
|
|
UserID: userID,
|
|
Timestamp: time.Now(),
|
|
Payload: map[string]interface{}{
|
|
"resource_type": string(rf.Type),
|
|
"direction": string(rf.Direction),
|
|
"site_id": rf.SiteID,
|
|
},
|
|
}
|
|
if err := s.eventBus.Publish(event); err != nil {
|
|
// Log error but don't fail the operation
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Delete deletes a resource flow
|
|
func (s *ResourceFlowService) Delete(ctx context.Context, id string) error {
|
|
// Get the resource flow before deleting to publish event with details
|
|
rf, err := s.repo.GetByID(ctx, id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := s.repo.Delete(ctx, id); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Publish event
|
|
userID := getUserFromContext(ctx)
|
|
if s.eventBus != nil {
|
|
event := domain.Event{
|
|
Type: domain.EventTypeResourceFlowDeleted,
|
|
EntityID: id,
|
|
OrgID: rf.OrganizationID,
|
|
UserID: userID,
|
|
Timestamp: time.Now(),
|
|
Payload: map[string]interface{}{
|
|
"resource_type": string(rf.Type),
|
|
"direction": string(rf.Direction),
|
|
"site_id": rf.SiteID,
|
|
},
|
|
}
|
|
if err := s.eventBus.Publish(event); err != nil {
|
|
// Log error but don't fail the operation
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|