package stage import ( "context" "fmt" "path/filepath" "gitea.maximumdirect.net/eric/narratio/internal/adapters/notify" "gitea.maximumdirect.net/eric/narratio/internal/adapters/storage" "gitea.maximumdirect.net/eric/narratio/internal/artifacts" "gitea.maximumdirect.net/eric/narratio/internal/manifest" ) const placeholderMessage = "placeholder stage: no real work executed" type placeholderStage struct { name string } func (s placeholderStage) Name() string { return s.name } func (s placeholderStage) Declares() IODecl { return IODecl{ Inputs: []artifacts.Ref{{Kind: "artifact", Category: "input", RelativePath: s.name + ".input.placeholder"}}, Outputs: []artifacts.Ref{{Kind: "artifact", Category: "output", RelativePath: s.name + ".output.placeholder"}}, } } func (s placeholderStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*StageResult, error) { result := &StageResult{ Metadata: map[string]any{ "placeholder": true, "stage": s.name, "message": placeholderMessage, }, } if env == nil || env.Config == nil || env.ArtifactStore == nil { return result, nil } sessionID := m.SessionID if sessionID == "" && env.Config.Session != nil { sessionID = env.Config.Session.SessionID } if sessionID == "" { return result, nil } paths := env.ArtifactStore.SessionPaths(sessionID) switch s.name { case "archive": if env.Storage != nil { req := storage.ArchiveRequest{ SessionID: sessionID, ManifestPath: paths.ManifestPath, Items: []storage.ArchiveItem{{ Kind: "artifact", LocalPath: filepath.Join(paths.ArtifactsDir, "session-log.md"), RemoteKey: "sessions/" + sessionID + "/artifacts/session-log.md", }}, } _, err := env.Storage.Archive(ctx, req) if err != nil { return nil, fmt.Errorf("placeholder archive adapter call failed: %w", err) } } case "notify": if env.Notifier != nil { req := notify.SendRequest{ Subject: "narratio placeholder run complete", Body: "placeholder stage execution finished", Metadata: map[string]string{ "session_id": sessionID, }, } _, err := env.Notifier.Send(ctx, req) if err != nil { return nil, fmt.Errorf("placeholder notify adapter call failed: %w", err) } } } return result, nil } // All returns the canonical ordered stage list for full pipeline execution. func All() []Stage { return []Stage{ prepareStage{}, transcribeStage{}, placeholderStage{name: "normalize"}, mergeStage{}, polishStage{}, analyzeStage{}, placeholderStage{name: "archive"}, placeholderStage{name: "notify"}, } } // Select returns one stage by exact name from the canonical stage set. func Select(name string) (Stage, error) { for _, s := range All() { if s.Name() == name { return s, nil } } return nil, fmt.Errorf("unknown stage %q", name) }