From b4aa096ac34dba0f846bb67c139aa6e7407eb114 Mon Sep 17 00:00:00 2001 From: Mathias Date: Tue, 2 Jun 2026 16:24:18 +0200 Subject: [PATCH] feat(usecase): implement ProcessNewVideo core path Resolve transcript -> summarize -> deliver, or skip when no usable transcript. Sinks fail independently: a failing sink does not abort the others and successful deliveries are kept; per-sink errors are returned joined. Makes the two scaffolded acceptance scenarios GREEN. Co-Authored-By: Claude Opus 4.8 (1M context) --- internal/usecase/engine.go | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/internal/usecase/engine.go b/internal/usecase/engine.go index f1e69db..e47980e 100644 --- a/internal/usecase/engine.go +++ b/internal/usecase/engine.go @@ -11,6 +11,7 @@ package usecase import ( "context" "errors" + "fmt" "gitea.d-ma.be/mathias/tapir/internal/domain" "gitea.d-ma.be/mathias/tapir/internal/ports" @@ -43,5 +44,29 @@ type ProcessResult struct { // resolve transcript -> (summarize -> deliver) | skip. // See docs/use-cases/summarize_new_video.feature. func (e *Engine) ProcessNewVideo(ctx context.Context, v domain.Video) (ProcessResult, error) { - return ProcessResult{}, ErrNotImplemented + t, err := e.Source.FetchTranscript(ctx, v) + if err != nil { + return ProcessResult{Video: v}, fmt.Errorf("fetch transcript: %w", err) + } + if !t.HasText() { + // No usable transcript: record the skip, produce no summary, deliver nothing + // (captions-first, ADR-007; the watcher uses this to avoid reprocessing). + return ProcessResult{Video: v, Skipped: true, Reason: "no transcript"}, nil + } + + sum, err := e.AI.Summarize(ctx, v, t) + if err != nil { + return ProcessResult{Video: v}, fmt.Errorf("summarize: %w", err) + } + + // Sinks fail independently: a failing sink must not abort the others, and + // successful deliveries are not dropped. Collect every error, return them joined. + var errs []error + for _, sink := range e.Sinks { + if err := sink.Deliver(ctx, sum); err != nil { + errs = append(errs, fmt.Errorf("deliver to %s: %w", sink.Name(), err)) + } + } + + return ProcessResult{Video: v, Summary: &sum}, errors.Join(errs...) }