172 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
package application
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
 | 
						|
	filestorage "git.coopgo.io/coopgo-apps/parcoursmob/core/utils/storage"
 | 
						|
	mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
						|
	"github.com/google/uuid"
 | 
						|
)
 | 
						|
 | 
						|
// DocumentConfig defines entity-specific document configuration
 | 
						|
type DocumentConfig struct {
 | 
						|
	// Storage prefix for this entity type
 | 
						|
	StoragePrefix string
 | 
						|
 | 
						|
	// Namespace for account validation (empty if no validation needed)
 | 
						|
	AccountNamespace string
 | 
						|
 | 
						|
	// Whether to validate against MobilityAccounts service
 | 
						|
	RequiresAccountValidation bool
 | 
						|
 | 
						|
	// Custom validator function (optional)
 | 
						|
	CustomValidator func(ctx context.Context, entityID string) error
 | 
						|
}
 | 
						|
 | 
						|
// Pre-configured document configs for each entity type
 | 
						|
var (
 | 
						|
	BeneficiaryDocumentConfig = DocumentConfig{
 | 
						|
		StoragePrefix:             filestorage.PREFIX_BENEFICIARIES,
 | 
						|
		AccountNamespace:          "parcoursmob_beneficiaries",
 | 
						|
		RequiresAccountValidation: true,
 | 
						|
	}
 | 
						|
 | 
						|
	SolidarityDriverDocumentConfig = DocumentConfig{
 | 
						|
		StoragePrefix:             filestorage.PREFIX_SOLIDARITY_TRANSPORT_DRIVERS,
 | 
						|
		AccountNamespace:          "solidarity_drivers",
 | 
						|
		RequiresAccountValidation: true,
 | 
						|
	}
 | 
						|
 | 
						|
	OrganizedCarpoolDriverDocumentConfig = DocumentConfig{
 | 
						|
		StoragePrefix:             filestorage.PREFIX_ORGANIZED_CARPOOL_DRIVERS,
 | 
						|
		AccountNamespace:          "organized_carpool_drivers",
 | 
						|
		RequiresAccountValidation: true,
 | 
						|
	}
 | 
						|
 | 
						|
	BookingDocumentConfig = DocumentConfig{
 | 
						|
		StoragePrefix:             filestorage.PREFIX_BOOKINGS,
 | 
						|
		RequiresAccountValidation: false,
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
// AddDocument adds a document for any entity with validation
 | 
						|
func (h *ApplicationHandler) AddDocument(
 | 
						|
	ctx context.Context,
 | 
						|
	config DocumentConfig,
 | 
						|
	entityID string,
 | 
						|
	file io.Reader,
 | 
						|
	filename string,
 | 
						|
	fileSize int64,
 | 
						|
	documentType string,
 | 
						|
	documentName string,
 | 
						|
) error {
 | 
						|
	// Perform validation if required
 | 
						|
	if config.RequiresAccountValidation {
 | 
						|
		if err := h.validateAccountForDocument(ctx, entityID, config.AccountNamespace); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Custom validation if provided
 | 
						|
	if config.CustomValidator != nil {
 | 
						|
		if err := config.CustomValidator(ctx, entityID); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Generate unique file ID
 | 
						|
	fileid := uuid.NewString()
 | 
						|
 | 
						|
	// Prepare metadata
 | 
						|
	metadata := map[string]string{
 | 
						|
		"type": documentType,
 | 
						|
		"name": documentName,
 | 
						|
	}
 | 
						|
 | 
						|
	// Construct file path
 | 
						|
	filepath := fmt.Sprintf("%s/%s_%s", entityID, fileid, filename)
 | 
						|
 | 
						|
	// Store file
 | 
						|
	return h.filestorage.Put(file, config.StoragePrefix, filepath, fileSize, metadata)
 | 
						|
}
 | 
						|
 | 
						|
// GetDocument retrieves a document for any entity with validation
 | 
						|
func (h *ApplicationHandler) GetDocument(
 | 
						|
	ctx context.Context,
 | 
						|
	config DocumentConfig,
 | 
						|
	entityID string,
 | 
						|
	document string,
 | 
						|
) (io.Reader, *filestorage.FileInfo, error) {
 | 
						|
	// Perform validation if required
 | 
						|
	if config.RequiresAccountValidation {
 | 
						|
		if err := h.validateAccountForDocument(ctx, entityID, config.AccountNamespace); err != nil {
 | 
						|
			return nil, nil, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Custom validation if provided
 | 
						|
	if config.CustomValidator != nil {
 | 
						|
		if err := config.CustomValidator(ctx, entityID); err != nil {
 | 
						|
			return nil, nil, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Retrieve file
 | 
						|
	filepath := fmt.Sprintf("%s/%s", entityID, document)
 | 
						|
	return h.filestorage.Get(config.StoragePrefix, filepath)
 | 
						|
}
 | 
						|
 | 
						|
// ListDocuments retrieves all documents for an entity
 | 
						|
func (h *ApplicationHandler) ListDocuments(
 | 
						|
	config DocumentConfig,
 | 
						|
	entityID string,
 | 
						|
) []filestorage.FileInfo {
 | 
						|
	prefix := fmt.Sprintf("%s/%s", config.StoragePrefix, entityID)
 | 
						|
	return h.filestorage.List(prefix)
 | 
						|
}
 | 
						|
 | 
						|
// DeleteDocument deletes a document for any entity with validation
 | 
						|
func (h *ApplicationHandler) DeleteDocument(
 | 
						|
	ctx context.Context,
 | 
						|
	config DocumentConfig,
 | 
						|
	entityID string,
 | 
						|
	document string,
 | 
						|
) error {
 | 
						|
	// Perform validation if required
 | 
						|
	if config.RequiresAccountValidation {
 | 
						|
		if err := h.validateAccountForDocument(ctx, entityID, config.AccountNamespace); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Custom validation if provided
 | 
						|
	if config.CustomValidator != nil {
 | 
						|
		if err := config.CustomValidator(ctx, entityID); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Delete file
 | 
						|
	filepath := fmt.Sprintf("%s/%s", entityID, document)
 | 
						|
	return h.filestorage.Delete(config.StoragePrefix, filepath)
 | 
						|
}
 | 
						|
 | 
						|
// validateAccountForDocument validates entity against MobilityAccounts service
 | 
						|
func (h *ApplicationHandler) validateAccountForDocument(ctx context.Context, accountID string, expectedNamespace string) error {
 | 
						|
	resp, err := h.services.GRPC.MobilityAccounts.GetAccount(ctx, &mobilityaccounts.GetAccountRequest{
 | 
						|
		Id: accountID,
 | 
						|
	})
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	if resp.Account.Namespace != expectedNamespace {
 | 
						|
		return fmt.Errorf("account %s is not of type %s (namespace: %s)",
 | 
						|
			accountID, expectedNamespace, resp.Account.Namespace)
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 |