Function bodies 586 total
main function · go · L29-L196 (168 LOC)cmd/api/main.go
func main() {
// Initialize Logger
logger.Init()
logger.Info("🚀 Starting FlowEngine API Server...")
// --- Security ---
tokenService := security.NewTokenService()
// --- Context for initial setup and graceful shutdown ---
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// --- Persistence & Cache Initialization ---
var workflowRepo workflow.Repository
var instanceRepo instance.Repository
var timerRepo timer.Repository // Add Timer Repo
var cch cache.Cache
// Try to initialize Redis cache
redisAddr := os.Getenv("REDIS_ADDR")
if redisAddr != "" {
logger.Info("⚡ Connecting to Redis cache...", "addr", redisAddr)
redisConfig := cache.GetRedisConfigFromEnv()
redisClient, err := cache.GetRedisClient(ctx, redisConfig)
if err != nil {
logger.Warn("❌ Failed to connect to Redis. Proceeding without cache.", "error", err)
cch = nil
} else {
cch = cache.NewRedisCache(redisClient)
logger.Info("✅ Connected to Redis cache")
defer cache.getEnv function · go · L199-L205 (7 LOC)cmd/api/main.go
func getEnv(key, defaultValue string) string {
value := os.Getenv(key)
if value == "" {
return defaultValue
}
return value
}NewEventTracker function · go · L32-L36 (5 LOC)cmd/demo/main.go
func NewEventTracker() *EventTracker {
return &EventTracker{
events: make([]event.DomainEvent, 0),
}
}Track method · go · L38-L40 (3 LOC)cmd/demo/main.go
func (et *EventTracker) Track(events []event.DomainEvent) {
et.events = append(et.events, events...)
}PrintSummary method · go · L42-L57 (16 LOC)cmd/demo/main.go
func (et *EventTracker) PrintSummary() {
fmt.Printf("\n%s%s=== 📊 Domain Events Summary ===%s\n", colorBold, colorCyan, colorReset)
fmt.Printf("Total events generated: %s%d%s\n\n", colorBold, len(et.events), colorReset)
// Group by type
eventsByType := make(map[string]int)
for _, evt := range et.events {
eventsByType[evt.Type()]++
}
for eventType, count := range eventsByType {
fmt.Printf(" %s%-30s%s: %d\n", colorYellow, eventType, colorReset, count)
}
fmt.Println()
}PrintDetailed method · go · L59-L74 (16 LOC)cmd/demo/main.go
func (et *EventTracker) PrintDetailed() {
fmt.Printf("\n%s%s=== 🔍 Detailed Event Log ===%s\n", colorBold, colorPurple, colorReset)
for i, evt := range et.events {
fmt.Printf("\n%s[Event %d/%d]%s\n", colorBold, i+1, len(et.events), colorReset)
fmt.Printf(" Type: %s%s%s\n", colorYellow, evt.Type(), colorReset)
fmt.Printf(" Aggregate ID: %s\n", evt.AggregateID())
fmt.Printf(" Occurred At: %s\n", evt.OccurredAt().Format(time.RFC3339))
payload := evt.Payload()
payloadJSON, _ := json.MarshalIndent(payload, " ", " ")
fmt.Printf(" Payload:\n %s\n", string(payloadJSON))
}
fmt.Println()
}printHeader function · go · L76-L78 (3 LOC)cmd/demo/main.go
func printHeader(title string) {
fmt.Printf("\n%s%s=== %s ===%s\n", colorBold, colorBlue, title, colorReset)
}About: code-quality intelligence by Repobility · https://repobility.com
printSuccess function · go · L80-L82 (3 LOC)cmd/demo/main.go
func printSuccess(message string) {
fmt.Printf("%s✅ %s%s\n", colorGreen, message, colorReset)
}printInfo function · go · L84-L86 (3 LOC)cmd/demo/main.go
func printInfo(message string) {
fmt.Printf("%sℹ️ %s%s\n", colorCyan, message, colorReset)
}printError function · go · L88-L90 (3 LOC)cmd/demo/main.go
func printError(message string) {
fmt.Printf("%s❌ %s%s\n", colorRed, message, colorReset)
}printSubHeader function · go · L92-L94 (3 LOC)cmd/demo/main.go
func printSubHeader(title string) {
fmt.Printf("\n%s--- %s ---%s\n", colorYellow, title, colorReset)
}NewWorkflowEmulator function · go · L24-L32 (9 LOC)cmd/emulator/main.go
func NewWorkflowEmulator() *WorkflowEmulator {
return &WorkflowEmulator{
workflows: make(map[string]*workflow.Workflow),
instances: make(map[string]*instance.Instance),
dispatcher: event.NewInMemoryDispatcher(),
systemActor: shared.NewID(),
scanner: bufio.NewScanner(os.Stdin),
}
}Run method · go · L34-L125 (92 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) Run() {
we.printWelcome()
for {
fmt.Print("\n> ")
if !we.scanner.Scan() {
break
}
input := strings.TrimSpace(we.scanner.Text())
if input == "" {
continue
}
parts := strings.Fields(input)
command := parts[0]
switch command {
case "help", "h":
we.printHelp()
case "create-workflow", "cw":
we.createWorkflow()
case "list-workflows", "lw":
we.listWorkflows()
case "show-workflow", "sw":
if len(parts) < 2 {
fmt.Println("❌ Usage: show-workflow <name>")
continue
}
we.showWorkflow(parts[1])
case "create-instance", "ci":
if len(parts) < 2 {
fmt.Println("❌ Usage: create-instance <workflow-name>")
continue
}
we.createInstance(parts[1])
case "list-instances", "li":
we.listInstances()
case "show-instance", "si":
if len(parts) < 2 {
fmt.Println("❌ Usage: show-instance <id>")
continue
}
we.showInstance(parts[1])
case "transition", "t":
if len(parts) < 3 {
fmt.PrprintWelcome method · go · L127-L136 (10 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) printWelcome() {
fmt.Println("\n╔════════════════════════════════════════════════════════════╗")
fmt.Println("║ ║")
fmt.Println("║ 🎮 FlowEngine Interactive Emulator 🎮 ║")
fmt.Println("║ ║")
fmt.Println("║ Create workflows, run instances, and test transitions ║")
fmt.Println("║ Type 'help' to see available commands ║")
fmt.Println("║ ║")
fmt.Println("╚════════════════════════════════════════════════════════════╝")
}printHelp method · go · L138-L161 (24 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) printHelp() {
fmt.Println("\n📚 Available Commands:")
fmt.Println("\n Workflow Management:")
fmt.Println(" create-workflow (cw) - Create a new workflow interactively")
fmt.Println(" list-workflows (lw) - List all workflows")
fmt.Println(" show-workflow <name> (sw) - Show workflow details")
fmt.Println("\n Instance Management:")
fmt.Println(" create-instance <workflow> (ci) - Create a new instance")
fmt.Println(" list-instances (li) - List all instances")
fmt.Println(" show-instance <id> (si) - Show instance details")
fmt.Println("\n Instance Operations:")
fmt.Println(" transition <id> <event> (t) - Execute a transition")
fmt.Println(" pause <id> - Pause an instance")
fmt.Println(" resume <id> - Resume a paused instance")
fmt.Println(" complete <id> - Complete an instance")
fmt.Println(" cancel <id> Open data scored by Repobility · https://repobility.com
createWorkflow method · go · L163-L282 (120 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) createWorkflow() {
fmt.Println("\n📋 Creating New Workflow")
// Get workflow name
fmt.Print(" Workflow name: ")
we.scanner.Scan()
name := strings.TrimSpace(we.scanner.Text())
if name == "" {
fmt.Println("❌ Name cannot be empty")
return
}
// Get initial state
fmt.Print(" Initial state ID: ")
we.scanner.Scan()
initialStateID := strings.TrimSpace(we.scanner.Text())
fmt.Print(" Initial state name: ")
we.scanner.Scan()
initialStateName := strings.TrimSpace(we.scanner.Text())
initialState, err := workflow.NewState(initialStateID, initialStateName)
if err != nil {
fmt.Printf("❌ Error creating state: %v\n", err)
return
}
// Create workflow
wf, err := workflow.NewWorkflow(name, initialState, we.systemActor)
if err != nil {
fmt.Printf("❌ Error creating workflow: %v\n", err)
return
}
// Track events
we.dispatcher.DispatchBatch(nil, wf.DomainEvents())
// Add more states
fmt.Println("\n Add additional states (enter empty ID listWorkflows method · go · L284-L298 (15 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) listWorkflows() {
if len(we.workflows) == 0 {
fmt.Println("\n📋 No workflows created yet. Use 'create-workflow' to create one.")
return
}
fmt.Println("\n📋 Available Workflows:")
for name, wf := range we.workflows {
fmt.Printf(" • %s [ID: %s, States: %d, Events: %d]\n",
name,
wf.ID().String()[:8],
len(wf.States()),
len(wf.Events()))
}
}showWorkflow method · go · L300-L333 (34 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) showWorkflow(name string) {
wf, exists := we.workflows[name]
if !exists {
fmt.Printf("❌ Workflow '%s' not found\n", name)
return
}
fmt.Printf("\n📋 Workflow: %s\n", wf.Name())
fmt.Printf(" ID: %s\n", wf.ID().String())
fmt.Printf(" Version: %s\n", wf.Version().String())
fmt.Printf(" Initial State: %s\n", wf.InitialState().ID)
fmt.Println("\n States:")
for _, state := range wf.States() {
marker := ""
if state.IsFinal {
marker = " [FINAL]"
}
fmt.Printf(" • %s - %s%s\n", state.ID, state.Name, marker)
}
fmt.Println("\n Events:")
for _, event := range wf.Events() {
sources := event.Sources
sourceIDs := make([]string, len(sources))
for i, s := range sources {
sourceIDs[i] = s.ID
}
fmt.Printf(" • %s: %v → %s\n",
event.Name,
sourceIDs,
event.Destination.ID)
}
}createInstance method · go · L335-L363 (29 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) createInstance(workflowName string) {
wf, exists := we.workflows[workflowName]
if !exists {
fmt.Printf("❌ Workflow '%s' not found\n", workflowName)
return
}
inst, err := instance.NewInstance(
wf.ID(),
wf.Name(),
wf.InitialState().ID,
we.systemActor,
)
if err != nil {
fmt.Printf("❌ Error creating instance: %v\n", err)
return
}
// Track events
we.dispatcher.DispatchBatch(nil, inst.DomainEvents())
shortID := inst.ID().String()[:8]
we.instances[shortID] = inst
fmt.Printf("\n✅ Instance created: %s\n", shortID)
fmt.Printf(" Workflow: %s\n", inst.WorkflowName())
fmt.Printf(" State: %s\n", inst.CurrentState())
fmt.Printf(" Status: %s\n", inst.Status())
}listInstances method · go · L365-L379 (15 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) listInstances() {
if len(we.instances) == 0 {
fmt.Println("\n🎬 No instances created yet. Use 'create-instance <workflow>' to create one.")
return
}
fmt.Println("\n🎬 Active Instances:")
for id, inst := range we.instances {
fmt.Printf(" • %s: %s [State: %s, Status: %s]\n",
id,
inst.WorkflowName(),
inst.CurrentState(),
inst.Status())
}
}showInstance method · go · L381-L401 (21 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) showInstance(id string) {
inst, exists := we.instances[id]
if !exists {
fmt.Printf("❌ Instance '%s' not found\n", id)
return
}
fmt.Printf("\n🎬 Instance: %s\n", id)
fmt.Printf(" Workflow: %s [%s]\n", inst.WorkflowName(), inst.WorkflowID().String()[:8])
fmt.Printf(" Current State: %s\n", inst.CurrentState())
if inst.HasSubState() {
fmt.Printf(" Sub-State: %s\n", inst.CurrentSubState().ID())
}
fmt.Printf(" Status: %s\n", inst.Status())
fmt.Printf(" Version: %s\n", inst.Version().String())
fmt.Printf(" Transitions: %d\n", inst.TransitionCount())
fmt.Printf(" Created: %s\n", inst.CreatedAt().Time().Format("2006-01-02 15:04:05"))
if !inst.CompletedAt().IsZero() {
fmt.Printf(" Completed: %s\n", inst.CompletedAt().Time().Format("2006-01-02 15:04:05"))
}
}executeTransition method · go · L403-L446 (44 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) executeTransition(id, eventName string) {
inst, exists := we.instances[id]
if !exists {
fmt.Printf("❌ Instance '%s' not found\n", id)
return
}
// Find workflow
var wf *workflow.Workflow
for _, w := range we.workflows {
if w.ID().Equals(inst.WorkflowID()) {
wf = w
break
}
}
if wf == nil {
fmt.Println("❌ Workflow not found")
return
}
// Find event
evt, err := wf.GetEvent(eventName)
if err != nil {
fmt.Printf("❌ Event '%s' not found in workflow\n", eventName)
return
}
// Execute transition
metadata := instance.NewTransitionMetadataWithReason(fmt.Sprintf("Manual transition: %s", eventName))
err = inst.Transition(evt.Destination.ID, eventName, we.systemActor, metadata, evt.RequiredData)
if err != nil {
fmt.Printf("❌ Transition failed: %v\n", err)
return
}
// Track events
we.dispatcher.DispatchBatch(nil, inst.DomainEvents())
fmt.Printf("✅ Transition executed: %s\n", eventName)
fmt.Printf(" New State: %s\n", inpauseInstance method · go · L448-L463 (16 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) pauseInstance(id string) {
inst, exists := we.instances[id]
if !exists {
fmt.Printf("❌ Instance '%s' not found\n", id)
return
}
err := inst.Pause(we.systemActor, "Manual pause from emulator")
if err != nil {
fmt.Printf("❌ Pause failed: %v\n", err)
return
}
we.dispatcher.DispatchBatch(nil, inst.DomainEvents())
fmt.Printf("✅ Instance paused: %s\n", id)
}Repobility · code-quality intelligence platform · https://repobility.com
resumeInstance method · go · L465-L480 (16 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) resumeInstance(id string) {
inst, exists := we.instances[id]
if !exists {
fmt.Printf("❌ Instance '%s' not found\n", id)
return
}
err := inst.Resume(we.systemActor)
if err != nil {
fmt.Printf("❌ Resume failed: %v\n", err)
return
}
we.dispatcher.DispatchBatch(nil, inst.DomainEvents())
fmt.Printf("✅ Instance resumed: %s\n", id)
}completeInstance method · go · L482-L497 (16 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) completeInstance(id string) {
inst, exists := we.instances[id]
if !exists {
fmt.Printf("❌ Instance '%s' not found\n", id)
return
}
err := inst.Complete(we.systemActor)
if err != nil {
fmt.Printf("❌ Complete failed: %v\n", err)
return
}
we.dispatcher.DispatchBatch(nil, inst.DomainEvents())
fmt.Printf("✅ Instance completed: %s\n", id)
}cancelInstance method · go · L499-L514 (16 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) cancelInstance(id string) {
inst, exists := we.instances[id]
if !exists {
fmt.Printf("❌ Instance '%s' not found\n", id)
return
}
err := inst.Cancel(we.systemActor, "Manual cancellation from emulator")
if err != nil {
fmt.Printf("❌ Cancel failed: %v\n", err)
return
}
we.dispatcher.DispatchBatch(nil, inst.DomainEvents())
fmt.Printf("✅ Instance canceled: %s\n", id)
}showHistory method · go · L516-L540 (25 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) showHistory(id string) {
inst, exists := we.instances[id]
if !exists {
fmt.Printf("❌ Instance '%s' not found\n", id)
return
}
transitions := inst.GetTransitionHistory()
if len(transitions) == 0 {
fmt.Println("\n📜 No transitions yet")
return
}
fmt.Printf("\n📜 Transition History for %s (%d transitions):\n", id, len(transitions))
for i, trans := range transitions {
fmt.Printf("\n [%d] %s\n", i+1, trans.Event())
fmt.Printf(" %s → %s\n", trans.From(), trans.To())
fmt.Printf(" Time: %s\n", trans.Timestamp().Time().Format("15:04:05"))
metadata := trans.Metadata()
if !metadata.IsEmpty() && metadata.Reason() != "" {
fmt.Printf(" Reason: %s\n", metadata.Reason())
}
}
}showEvents method · go · L542-L560 (19 LOC)cmd/emulator/main.go
func (we *WorkflowEmulator) showEvents() {
events := we.dispatcher.Events()
if len(events) == 0 {
fmt.Println("\n📊 No events recorded yet")
return
}
fmt.Printf("\n📊 Domain Events (%d total):\n", len(events))
// Group by type
byType := make(map[string]int)
for _, evt := range events {
byType[evt.Type()]++
}
for eventType, count := range byType {
fmt.Printf(" • %-30s: %d\n", eventType, count)
}
}main function · go · L562-L565 (4 LOC)cmd/emulator/main.go
func main() {
emulator := NewWorkflowEmulator()
emulator.Run()
}main function · go · L12-L143 (132 LOC)cmd/quick-test/main.go
func main() {
fmt.Println("🧪 FlowEngine Quick Test")
fmt.Println("========================")
actor := shared.NewID()
// ============================================
// 1. Define tu workflow aquí
// ============================================
fmt.Println("📋 Creating Workflow...")
// Estados
draft, _ := workflow.NewState("draft", "Borrador")
review, _ := workflow.NewState("review", "En Revisión")
approved, _ := workflow.NewState("approved", "Aprobado")
approved = approved.AsFinal()
rejected, _ := workflow.NewState("rejected", "Rechazado")
rejected = rejected.AsFinal()
// Crear workflow
wf, _ := workflow.NewWorkflow("Aprobación Simple", draft, actor)
wf.AddState(review)
wf.AddState(approved)
wf.AddState(rejected)
// Eventos (transiciones)
submitEvent, _ := workflow.NewEvent("submit", []workflow.State{draft}, review)
approveEvent, _ := workflow.NewEvent("approve", []workflow.State{review}, approved)
rejectEvent, _ := workflow.NewEvent("reject", []workflow.StateNewCloneInstanceUseCase function · go · L46-L56 (11 LOC)internal/application/instance/clone_instance.go
func NewCloneInstanceUseCase(
instanceRepo instance.Repository,
workflowRepo workflow.Repository,
eventBus event.Dispatcher,
) *CloneInstanceUseCase {
return &CloneInstanceUseCase{
instanceRepo: instanceRepo,
workflowRepo: workflowRepo,
eventBus: eventBus,
}
}Repobility · severity-and-effort ranking · https://repobility.com
Execute method · go · L58-L154 (97 LOC)internal/application/instance/clone_instance.go
func (uc *CloneInstanceUseCase) Execute(ctx context.Context, cmd CloneInstanceCommand) (*CloneInstanceResult, error) {
// 1. Validate Parent
parentID, err := shared.ParseID(cmd.ParentInstanceID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid parent ID")
}
parent, err := uc.instanceRepo.FindByID(ctx, parentID)
if err != nil {
return nil, err
}
if parent.Status() != instance.StatusRunning {
return nil, instance.InstanceNotActiveError(parentID, parent.Status())
}
// 2. Calculate Expiration
duration, err := time.ParseDuration(cmd.TimeoutDuration)
if err != nil {
return nil, instance.InvalidInstanceError("invalid timeout duration format")
}
expiresAt := time.Now().Add(duration)
// 3. Create Clone Group ID
cloneGroupID := uuid.New().String()
// 4. Create Clones
var clonedIDs []string
// Retrieve workflow to get state config?
// For now assume generic "pending" state for clones as per requirements,
// or we use the same workflow definiNewCreateInstanceUseCase function · go · L42-L52 (11 LOC)internal/application/instance/create_instance.go
func NewCreateInstanceUseCase(
workflowRepo workflow.Repository,
instanceRepo instance.Repository,
eventBus event.Dispatcher,
) *CreateInstanceUseCase {
return &CreateInstanceUseCase{
workflowRepo: workflowRepo,
instanceRepo: instanceRepo,
eventBus: eventBus,
}
}Execute method · go · L55-L164 (110 LOC)internal/application/instance/create_instance.go
func (uc *CreateInstanceUseCase) Execute(ctx context.Context, cmd CreateInstanceCommand) (*CreateInstanceResult, error) {
// Validate command
if err := uc.validateCommand(cmd); err != nil {
return nil, err
}
// Parse IDs
workflowID, err := shared.ParseID(cmd.WorkflowID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid workflow ID format")
}
actorID, err := shared.ParseID(cmd.StartedBy)
if err != nil {
return nil, instance.InvalidInstanceError("invalid actor ID format")
}
// Retrieve workflow to get initial state
wf, err := uc.workflowRepo.FindByID(ctx, workflowID)
if err != nil {
return nil, err
}
var inst *instance.Instance
// Check if it's a subprocess (R6.1)
if cmd.ParentID != "" {
parentID, err := shared.ParseID(cmd.ParentID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid parent instance ID format")
}
// Validate parent exists
exists, err := uc.instanceRepo.Exists(ctx, parentID)
if err != nil {
rvalidateCommand method · go · L166-L176 (11 LOC)internal/application/instance/create_instance.go
func (uc *CreateInstanceUseCase) validateCommand(cmd CreateInstanceCommand) error {
if cmd.WorkflowID == "" {
return instance.InvalidInstanceError("workflow ID is required")
}
if cmd.StartedBy == "" {
return instance.InvalidInstanceError("actor ID is required")
}
return nil
}NewGetInstanceUseCase function · go · L46-L50 (5 LOC)internal/application/instance/get_instance.go
func NewGetInstanceUseCase(instanceRepo instance.Repository) *GetInstanceUseCase {
return &GetInstanceUseCase{
instanceRepo: instanceRepo,
}
}Execute method · go · L53-L65 (13 LOC)internal/application/instance/get_instance.go
func (uc *GetInstanceUseCase) Execute(ctx context.Context, instanceID string) (*InstanceDTO, error) {
id, err := shared.ParseID(instanceID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid instance ID format")
}
inst, err := uc.instanceRepo.FindByID(ctx, id)
if err != nil {
return nil, err
}
return uc.toDTO(inst), nil
}ExecuteByWorkflow method · go · L68-L85 (18 LOC)internal/application/instance/get_instance.go
func (uc *GetInstanceUseCase) ExecuteByWorkflow(ctx context.Context, workflowID string) ([]*InstanceDTO, error) {
id, err := shared.ParseID(workflowID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid workflow ID format")
}
instances, err := uc.instanceRepo.FindByWorkflowID(ctx, id)
if err != nil {
return nil, err
}
dtos := make([]*InstanceDTO, len(instances))
for i, inst := range instances {
dtos[i] = uc.toDTO(inst)
}
return dtos, nil
}ExecuteAll method · go · L88-L100 (13 LOC)internal/application/instance/get_instance.go
func (uc *GetInstanceUseCase) ExecuteAll(ctx context.Context) ([]*InstanceDTO, error) {
instances, err := uc.instanceRepo.FindAll(ctx)
if err != nil {
return nil, err
}
dtos := make([]*InstanceDTO, len(instances))
for i, inst := range instances {
dtos[i] = uc.toDTO(inst)
}
return dtos, nil
}About: code-quality intelligence by Repobility · https://repobility.com
ExecuteList method · go · L109-L132 (24 LOC)internal/application/instance/get_instance.go
func (uc *GetInstanceUseCase) ExecuteList(ctx context.Context, pageNumber, pageSize int, workflowID string) (*ListResult, error) {
query := shared.NewListQuery(pageNumber, pageSize)
var wfIDPtr *shared.ID
if workflowID != "" {
id, err := shared.ParseID(workflowID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid workflow ID format")
}
wfIDPtr = &id
}
instances, total, err := uc.instanceRepo.List(ctx, query, wfIDPtr)
if err != nil {
return nil, err
}
dtos := make([]*InstanceDTO, len(instances))
for i, inst := range instances {
dtos[i] = uc.toDTO(inst)
}
return &ListResult{Items: dtos, Total: total}, nil
}ExecuteHistory method · go · L135-L164 (30 LOC)internal/application/instance/get_instance.go
func (uc *GetInstanceUseCase) ExecuteHistory(ctx context.Context, instanceID string) ([]TransitionDTO, error) {
id, err := shared.ParseID(instanceID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid instance ID format")
}
inst, err := uc.instanceRepo.FindByID(ctx, id)
if err != nil {
return nil, err
}
transitions := inst.GetTransitionHistory()
dtos := make([]TransitionDTO, len(transitions))
for i, trans := range transitions {
metadata := trans.Metadata()
dtos[i] = TransitionDTO{
ID: trans.ID().String(),
From: trans.From(),
To: trans.To(),
Event: trans.Event(),
Actor: trans.Actor().String(),
Timestamp: trans.Timestamp().Time().Format("2006-01-02T15:04:05Z07:00"),
Reason: metadata.Reason(),
Feedback: metadata.Feedback(),
Metadata: metadata.Metadata(),
}
}
return dtos, nil
}toDTO method · go · L166-L204 (39 LOC)internal/application/instance/get_instance.go
func (uc *GetInstanceUseCase) toDTO(inst *instance.Instance) *InstanceDTO {
transitions := inst.GetTransitionHistory()
transitionDTOs := make([]TransitionDTO, len(transitions))
for i, trans := range transitions {
metadata := trans.Metadata()
transitionDTOs[i] = TransitionDTO{
ID: trans.ID().String(),
From: trans.From(),
To: trans.To(),
Event: trans.Event(),
Actor: trans.Actor().String(),
Timestamp: trans.Timestamp().Time().Format("2006-01-02T15:04:05Z07:00"),
Reason: metadata.Reason(),
Feedback: metadata.Feedback(),
Metadata: metadata.Metadata(),
}
}
completedAt := ""
if !inst.CompletedAt().IsZero() {
completedAt = inst.CompletedAt().Time().Format("2006-01-02T15:04:05Z07:00")
}
return &InstanceDTO{
ID: inst.ID().String(),
WorkflowID: inst.WorkflowID().String(),
WorkflowName: inst.WorkflowName(),
CurrentState: inst.CurrentState(),
Status: inst.Status().String(),
VersNewTransitionInstanceUseCase function · go · L44-L56 (13 LOC)internal/application/instance/transition_instance.go
func NewTransitionInstanceUseCase(
workflowRepo workflow.Repository,
instanceRepo instance.Repository,
eventBus event.Dispatcher,
engine *instance.Engine,
) *TransitionInstanceUseCase {
return &TransitionInstanceUseCase{
workflowRepo: workflowRepo,
instanceRepo: instanceRepo,
eventBus: eventBus,
engine: engine,
}
}Execute method · go · L59-L176 (118 LOC)internal/application/instance/transition_instance.go
func (uc *TransitionInstanceUseCase) Execute(ctx context.Context, cmd TransitionInstanceCommand) (*TransitionInstanceResult, error) {
// Validate command
if err := uc.validateCommand(cmd); err != nil {
return nil, err
}
// Parse instance ID
instanceID, err := shared.ParseID(cmd.InstanceID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid instance ID format")
}
// Parse actor ID
actorID, err := shared.ParseID(cmd.ActorID)
if err != nil {
return nil, instance.InvalidInstanceError("invalid actor ID format")
}
// Retrieve instance
inst, err := uc.instanceRepo.FindByID(ctx, instanceID)
if err != nil {
return nil, err
}
// Retrieve workflow to validate transition
wf, err := uc.workflowRepo.FindByID(ctx, inst.WorkflowID())
if err != nil {
return nil, err
}
// Get current state
currentState, err := wf.GetState(inst.CurrentState())
if err != nil {
return nil, err
}
// Get event and validate transition
evt, err := wf.GetEvent(cmd.EventvalidateCommand method · go · L178-L192 (15 LOC)internal/application/instance/transition_instance.go
func (uc *TransitionInstanceUseCase) validateCommand(cmd TransitionInstanceCommand) error {
if cmd.InstanceID == "" {
return instance.InvalidInstanceError("instance ID is required")
}
if cmd.Event == "" {
return instance.InvalidInstanceError("event name is required")
}
if cmd.ActorID == "" {
return instance.InvalidInstanceError("actor ID is required")
}
return nil
}NewCreateWorkflowFromYAMLUseCase function · go · L40-L49 (10 LOC)internal/application/workflow/create_workflow_from_yaml.go
func NewCreateWorkflowFromYAMLUseCase(
workflowRepo workflow.Repository,
eventBus event.Dispatcher,
) *CreateWorkflowFromYAMLUseCase {
return &CreateWorkflowFromYAMLUseCase{
workflowRepo: workflowRepo,
eventBus: eventBus,
parser: yamlparser.NewParser(),
}
}Execute method · go · L52-L90 (39 LOC)internal/application/workflow/create_workflow_from_yaml.go
func (uc *CreateWorkflowFromYAMLUseCase) Execute(ctx context.Context, cmd CreateWorkflowFromYAMLCommand) (*CreateWorkflowFromYAMLResult, error) {
// Validate command
if len(cmd.YAMLContent) == 0 {
return nil, workflow.InvalidWorkflowError("YAML content is required")
}
if cmd.CreatedBy == "" {
return nil, workflow.InvalidWorkflowError("creator ID is required")
}
// Parse YAML content
wf, err := uc.parser.ParseBytes(cmd.YAMLContent)
if err != nil {
return nil, err
}
// Persist workflow
if err := uc.workflowRepo.Save(ctx, wf); err != nil {
return nil, err
}
// Dispatch domain events
events := wf.DomainEvents()
if len(events) > 0 {
_ = uc.eventBus.DispatchBatch(ctx, events)
}
return &CreateWorkflowFromYAMLResult{
ID: wf.ID().String(),
Name: wf.Name(),
Description: wf.Description(),
Version: wf.Version().String(),
InitialState: wf.InitialState().ID,
StatesCount: len(wf.States()),
EventsCount: len(wf.Events()),
CreatedOpen data scored by Repobility · https://repobility.com
ExecuteFromReader method · go · L93-L103 (11 LOC)internal/application/workflow/create_workflow_from_yaml.go
func (uc *CreateWorkflowFromYAMLUseCase) ExecuteFromReader(ctx context.Context, reader io.Reader, createdBy string) (*CreateWorkflowFromYAMLResult, error) {
content, err := io.ReadAll(reader)
if err != nil {
return nil, workflow.InvalidWorkflowError("failed to read YAML content: " + err.Error())
}
return uc.Execute(ctx, CreateWorkflowFromYAMLCommand{
YAMLContent: content,
CreatedBy: createdBy,
})
}ExecuteWithDetails method · go · L106-L148 (43 LOC)internal/application/workflow/create_workflow_from_yaml.go
func (uc *CreateWorkflowFromYAMLUseCase) ExecuteWithDetails(ctx context.Context, cmd CreateWorkflowFromYAMLCommand) (*CreateWorkflowFromYAMLResult, error) {
// Validate command
if len(cmd.YAMLContent) == 0 {
return nil, workflow.InvalidWorkflowError("YAML content is required")
}
if cmd.CreatedBy == "" {
return nil, workflow.InvalidWorkflowError("creator ID is required")
}
// Parse YAML with details
result, err := uc.parser.ParseWithDetails(io.NopCloser(
&bytesReader{data: cmd.YAMLContent, pos: 0},
))
if err != nil {
return nil, err
}
wf := result.Workflow
// Persist workflow
if err := uc.workflowRepo.Save(ctx, wf); err != nil {
return nil, err
}
// Dispatch domain events
events := wf.DomainEvents()
if len(events) > 0 {
_ = uc.eventBus.DispatchBatch(ctx, events)
}
return &CreateWorkflowFromYAMLResult{
ID: wf.ID().String(),
Name: wf.Name(),
Description: wf.Description(),
Version: wf.Version().String(),
InitialState: wRead method · go · L156-L163 (8 LOC)internal/application/workflow/create_workflow_from_yaml.go
func (r *bytesReader) Read(p []byte) (n int, err error) {
if r.pos >= len(r.data) {
return 0, io.EOF
}
n = copy(p, r.data[r.pos:])
r.pos += n
return n, nil
}page 1 / 12next ›