package artifacts import ( "path/filepath" "gitea.maximumdirect.net/eric/narratio/internal/config" ) // SessionPaths contains canonical local paths for one session work directory. type SessionPaths struct { WorkspaceRoot string CampaignID string SessionID string Root string InputsDir string AudioDir string TranscriptsDir string TranscriptsRawDir string TranscriptsTrimmedDir string ArtifactsDir string ReportsDir string ConfigDir string LogsDir string CurrentDir string RunsDir string ManifestPath string LockPath string } // SessionWorkDir returns the legacy work directory for one session. func SessionWorkDir(rootDir, sessionID string) string { return filepath.Join(rootDir, config.PathWorkDirSegment, sessionID) } // SessionWorkDirForCampaign returns the canonical campaign-aware work directory for one session. func SessionWorkDirForCampaign(rootDir, campaign, sessionID string) string { return filepath.Join(rootDir, config.PathWorkDirSegment, campaign, sessionID) } // SessionManifestPathForCampaign returns the canonical session manifest path. func SessionManifestPathForCampaign(rootDir, campaign, sessionID string) string { return filepath.Join(SessionWorkDirForCampaign(rootDir, campaign, sessionID), config.PathManifestFile) } // SessionRunsDirForCampaign returns the canonical runs directory for one session. func SessionRunsDirForCampaign(rootDir, campaign, sessionID string) string { return filepath.Join(SessionWorkDirForCampaign(rootDir, campaign, sessionID), config.PathRunsDirSegment) } // SessionRunRootForCampaign returns the canonical run root under runs/{run_id}. func SessionRunRootForCampaign(rootDir, campaign, sessionID, runID string) string { return filepath.Join(SessionRunsDirForCampaign(rootDir, campaign, sessionID), runID) } // SessionRunStageDirForCampaign returns the canonical stage directory under runs/{run_id}/{stage}. func SessionRunStageDirForCampaign(rootDir, campaign, sessionID, runID, stageName string) string { return filepath.Join(SessionRunRootForCampaign(rootDir, campaign, sessionID, runID), stageName) } // SessionRunWorkDir returns the legacy campaign/session/run scoped local work directory. func SessionRunWorkDir(rootDir, campaign, sessionID, runID string) string { return filepath.Join(rootDir, config.PathWorkDirSegment, campaign, sessionID, runID) } // SessionSpoolAudioDir returns the campaign/session/run scoped local spool audio path. func SessionSpoolAudioDir(spoolRoot, campaign, sessionID, runID string) string { return filepath.Join(spoolRoot, campaign, sessionID, runID, config.PathAudioDirSegment) } func buildLegacySessionPaths(workspaceRoot, sessionID string) SessionPaths { root := SessionWorkDir(workspaceRoot, sessionID) return buildSessionPathsFromRoot(workspaceRoot, "", sessionID, root) } func buildSessionPaths(workspaceRoot, campaign, sessionID string) SessionPaths { root := SessionWorkDirForCampaign(workspaceRoot, campaign, sessionID) return buildSessionPathsFromRoot(workspaceRoot, campaign, sessionID, root) } func buildSessionPathsFromRoot(workspaceRoot, campaign, sessionID, root string) SessionPaths { return SessionPaths{ WorkspaceRoot: workspaceRoot, CampaignID: campaign, SessionID: sessionID, Root: root, InputsDir: filepath.Join(root, config.PathInputsDirSegment), AudioDir: filepath.Join(root, config.PathAudioDirSegment), TranscriptsDir: filepath.Join(root, config.PathTranscriptsSegment), TranscriptsRawDir: filepath.Join(root, filepath.FromSlash(config.PathTranscriptsRaw)), TranscriptsTrimmedDir: filepath.Join(root, filepath.FromSlash(config.PathTranscriptsTrimmed)), ArtifactsDir: filepath.Join(root, config.PathArtifactsDirSegment), ReportsDir: filepath.Join(root, config.PathReportsDirSegment), ConfigDir: filepath.Join(root, config.PathConfigDirSegment), LogsDir: filepath.Join(root, config.PathLogsDirSegment), CurrentDir: filepath.Join(root, config.PathCurrentDirSegment), RunsDir: filepath.Join(root, config.PathRunsDirSegment), ManifestPath: filepath.Join(root, config.PathManifestFile), LockPath: filepath.Join(root, config.PathLockFile), } }