// Package domain holds Tapir's core entities. It depends on nothing outside // the standard library — no providers, no storage, no AI. See docs/data-model.md. package domain import "time" // Provider identifies a video platform. type Provider string const ( ProviderYouTube Provider = "youtube" ProviderVimeo Provider = "vimeo" ) // TranscriptSource records how a transcript was obtained (or that there was none). type TranscriptSource string const ( SourceCaptions TranscriptSource = "captions" SourceNone TranscriptSource = "none" ) // User is the Tapir-side profile. At Stage 0 there is exactly one. type User struct { ID string DisplayName string CreatedAt time.Time } // Subscription is a watched channel on a connected account. type Subscription struct { ID string UserID string ConnectionID string ChannelID string ChannelTitle string Active bool } // Video is a single video seen for a user (per-user, not globally deduped — // see docs/data-model.md and DECISIONS.md "Rejected alternatives"). type Video struct { ID string UserID string SubscriptionID string Provider Provider ProviderVideoID string Title string URL string PublishedAt time.Time SeenAt time.Time } // Transcript is the text of a video (or a record that none was available). type Transcript struct { VideoID string UserID string Source TranscriptSource Language string Content string // empty when Source == SourceNone } // HasText reports whether the transcript carries usable text. func (t Transcript) HasText() bool { return t.Source != SourceNone && t.Content != "" } // Summary is the produced output for a video. type Summary struct { ID string UserID string VideoID string Summary string Highlights []string Takeaways []string AIProvider string // "local" | "anthropic" | "openai" | "gemini" AIModel string FallbackUsed bool CreatedAt time.Time }