fix(portals): keep a pin readable under every identity of its film

Two defects in the pin/position subsystem, both reported in review.

A pin was stored under the movie's most-trusted key alone and its other
keys retired. But a movie's identity GROWS: the film keyed `tmdb:438631`
today was `title:dune:2021` before enrichment, and reopening it cold asks
for the poorer key first. The preference was therefore ignored until
enrichment landed — and permanently when enrichment is off or never
answers. The decision is now written under every key in `write` (never
the yearless form, which every remake shares), one upsert per key plus
the leftover retirement in the same transaction. `setVodSourcePin` also
reports failure for a pin with no usable key instead of claiming a write
it never made.

The primary button asked whether the pinned copy's position had loaded
by testing presence rather than identity, so re-pinning left it wearing
the previous copy's timecode until the new lookup returned.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5 committed 2026-07-29 19:32:14 +02:00
1 parent e0ebbeafed
commit 45fca81504
16 files changed
+326 -78

No files matched your search

@@ -87,10 +87,19 @@ export class VodSourcePinService {
}
/**
* Store the pin, retiring `retireKeys` in the same transaction — a
* half-applied change has no honest outcome to report.
* Store the pin, also under `aliasKeys`, retiring `retireKeys` — all in
* the same transaction, because a half-applied change has no honest
* outcome to report.
*
* @param aliasKeys further keys naming exactly this film. A movie's
* identity grows as enrichment lands, and a pin recorded only under the
* richest key is invisible to the next reopen that has not been enriched.
*/
async set(pin: VodSourcePin, retireKeys: string[] = []): Promise<boolean> {
async set(
pin: VodSourcePin,
retireKeys: string[] = [],
aliasKeys: string[] = []
): Promise<boolean> {
if (!this.isAvailable) {
return false;
}
@@ -98,7 +107,8 @@ export class VodSourcePinService {
try {
const result = await window.electron.dbSetVodSourcePin(
pin,
retireKeys
retireKeys,
aliasKeys
);
return result?.success === true;
} catch (error) {