feat(db,contracts): W5-C subscription units migration 0025, contracts and mapping
- subscription: status pending (TMDB not ready: searchable/evaluable, not completable), last_searched_at / next_search_at - content_unit (season): episode_total ledger with source / lock / timestamp - acquisition_plan: unit_keys (Slot × unit reservation) and file_selection; drop the one-in-flight-per-slot unique index (checked under slot row lock per unit instead) - new tables slot_deferral, slot_unit (per-unit quality ledger), subscription_history - contracts: SubscriptionParams, SubscriptionHistory, SlotDeferral, SlotUnit, SubscriptionProgress, EpisodeTotalSet, CandidateEvaluation pri/trace/unitKeys and decision deferred; endpoints subscriptions.search/progress/setEpisodeTotal and subscription-history - mapping: evaluation messages via describeViolation, pri/trace passthrough Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
d162d464c4
commit
1dd460d359
9 files changed
+405
-34
No files matched your search
@@ -59,6 +59,10 @@ export type Segment = z.infer<typeof Segment>;
|
||||
export const ContentUnitStatus = z.enum(["provisional", "confirmed", "retired"]);
|
||||
export type ContentUnitStatus = z.infer<typeof ContentUnitStatus>;
|
||||
|
||||
/** 季总集数来源:tmdb 元数据 / 插件注入(只升)/ 人工锁定 / 回退被已覆盖最高集兜住 / 沿用 */
|
||||
export const EpisodeTotalSource = z.enum(["tmdb", "injected", "manual", "covered_floor", "previous"]);
|
||||
export type EpisodeTotalSource = z.infer<typeof EpisodeTotalSource>;
|
||||
|
||||
export const ContentUnit = EntityBase.extend({
|
||||
mediaEntityId: Id,
|
||||
parentUnitId: Id.nullable(),
|
||||
@@ -77,6 +81,12 @@ export const ContentUnit = EntityBase.extend({
|
||||
numberingLocked: z.boolean(),
|
||||
metadata: JsonObject,
|
||||
fieldLocks: z.array(z.string()),
|
||||
/** 季单元的总集数账本(只升;回退不低于已覆盖最高集);null = 未知,追更不结束 */
|
||||
episodeTotal: z.number().int().nonnegative().nullable(),
|
||||
episodeTotalSource: EpisodeTotalSource.nullable(),
|
||||
/** 人工锁定总集数:元数据刷新与注入不再改写 */
|
||||
episodeTotalLocked: z.boolean(),
|
||||
episodeTotalAt: Timestamp.nullable(),
|
||||
});
|
||||
export type ContentUnit = z.infer<typeof ContentUnit>;
|
||||
export const ContentUnitCreate = ContentUnit.omit(SERVER_MANAGED).partial({
|
||||
@@ -93,6 +103,10 @@ export const ContentUnitCreate = ContentUnit.omit(SERVER_MANAGED).partial({
|
||||
numberingLocked: true,
|
||||
metadata: true,
|
||||
fieldLocks: true,
|
||||
episodeTotal: true,
|
||||
episodeTotalSource: true,
|
||||
episodeTotalLocked: true,
|
||||
episodeTotalAt: true,
|
||||
});
|
||||
export type ContentUnitCreate = z.infer<typeof ContentUnitCreate>;
|
||||
export const ContentUnitUpdate = ContentUnitCreate.omit({ mediaEntityId: true }).partial();
|
||||
|
||||
Reference in new issue
Block a user