CI / build-and-test (push) Successful in 14m43s
7.3: capturedAt/source au registre + 6 adaptateurs + module provenance.ts + ?debug=1 (search-transport.mjs). 7.4: ProviderHealthService + badge source degradee. 7.6: squelettes par provider + snapshots progressifs + transport NDJSON /api/search. 8.1: ProviderAdapter unifie (search enveloppe + channelContent/channelMeta/capabilities) via getProviderAdapter + test de contrat offline.
67 lines
2.4 KiB
TypeScript
67 lines
2.4 KiB
TypeScript
import type { ChannelMeta } from './channel.model';
|
|
import type { ProviderLongId } from '../providers/provider-ids';
|
|
|
|
/**
|
|
* Vue « grille » d'une vidéo. Miroir du contrat `Suggestion` v2
|
|
* (server/providers/registry.mjs) — voir src/app/search/api.v1.ts.
|
|
*
|
|
* Règle structurante (phase 2.1) : une métadonnée absente reste `undefined`.
|
|
* `durationSec: 0` est interdit : les règles de classification s'appuient sur
|
|
* « pas de durée connue » pour distinguer une verticale d'un short.
|
|
*/
|
|
export interface VideoItem {
|
|
id: string; // id vidéo canonicalisé
|
|
provider: ProviderLongId;
|
|
title: string;
|
|
thumbnailUrl: string;
|
|
/** Secondes, > 0. `undefined` = inconnue. */
|
|
durationSec?: number;
|
|
channelName?: string;
|
|
channelExternalId?: string;
|
|
channelAvatarUrl?: string;
|
|
channelMeta?: ChannelMeta;
|
|
viewCount?: number;
|
|
/**
|
|
* Phase 7.3 — spectateurs EN DIRECT (Twitch `viewer_count`). Ce n'est pas un
|
|
* compteur de vues : à n'afficher que si `isLive === true`.
|
|
*/
|
|
viewers?: number;
|
|
/** ISO 8601. */
|
|
publishedAt?: string;
|
|
// Provider-specific routing hints
|
|
slug?: string; // Odysee slug when available
|
|
channel?: string; // Twitch channel when item represents a channel/live
|
|
// Live status (only providers exposing it, e.g. Twitch, set these)
|
|
type?: string; // e.g. 'live' | 'channel' | 'video'
|
|
isLive?: boolean; // true when actually broadcasting now
|
|
isShort?: boolean; // true when the provider flagged a Short/clip
|
|
kind?: string; // e.g. Twitch 'vod' | 'clip'
|
|
game?: string; // e.g. Twitch game/category name
|
|
width?: number; // video width in px (orientation signal, when exposed)
|
|
height?: number; // video height in px (orientation signal, when exposed)
|
|
|
|
// --- v2 (phase 1 + 2) ---
|
|
likes?: number;
|
|
dislikes?: number;
|
|
uploaderAvatar?: string;
|
|
description?: string;
|
|
tags?: string[];
|
|
/** BCP-47. */
|
|
language?: string;
|
|
hasSubtitles?: boolean;
|
|
embeddable?: boolean;
|
|
/** Libellés bruts : permettent d'afficher une valeur approchée plutôt qu'un vide. */
|
|
durationRaw?: string;
|
|
viewCountRaw?: string;
|
|
|
|
// --- Phase 7.3 : provenance ---
|
|
/**
|
|
* Epoch ms : instant RÉEL de la collecte. `undefined` = inconnu (jamais
|
|
* `Date.now()` côté front : une donnée vieille de 4 min ne doit pas passer
|
|
* pour fraîche).
|
|
*/
|
|
capturedAt?: number;
|
|
/** Voie de collecte : `innertube` / `api` / `scrape` / `cache`… */
|
|
source?: string;
|
|
}
|