feat(store,runner,web): channel unavailability notice (migration 013)
YouTube channels that 404 on playlist discovery (deleted/private) are now: 1. Wrapped in domain.ErrChannelUnavailable by the YouTube adapter (instead of a generic error), so the runner can identify them without string-matching. 2. Stored per-user in channel_errors (migration 013, RLS-guarded) via runner's new UpsertChannelError path — removed from the generic Errors counter, counted separately as ChannelUnavailable. 3. Shown on the account page under "Unavailable channels" with name, chip-warn badge, and first-seen date, so users know why some subscribed channels produce no videos.
This commit is contained in:
@@ -2,7 +2,22 @@
|
||||
// the standard library — no providers, no storage, no AI. See docs/data-model.md.
|
||||
package domain
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ErrChannelUnavailable is returned by a VideoSource when a channel's upload
|
||||
// playlist returns HTTP 404 — the channel was deleted or made private. The runner
|
||||
// stores these so the account page can surface them to the user.
|
||||
type ErrChannelUnavailable struct {
|
||||
ChannelID string
|
||||
ChannelTitle string
|
||||
}
|
||||
|
||||
func (e *ErrChannelUnavailable) Error() string {
|
||||
return fmt.Sprintf("channel %q (%s) unavailable: playlist not found", e.ChannelTitle, e.ChannelID)
|
||||
}
|
||||
|
||||
// Provider identifies a video platform.
|
||||
type Provider string
|
||||
|
||||
Reference in New Issue
Block a user