You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/architecture/curated-api.md
+9-9Lines changed: 9 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,12 @@
1
-
# Majestic Curated API — Cloudflare Shared Data Layer
1
+
# Majestic Curated API - Cloudflare Shared Data Layer
2
2
3
3
> **DEPRECATED.** The metadata/enrichment layer described here is superseded by [majestic-canon](../strategy/authoritative-data-distribution-dissection.md#15-canon-architecture--three-layers). Canon uses authoritative data distribution (signed patch packs) instead of live API. This document is retained for historical context and optional live-assist fallback design. **See majestic-canon for the canonical dataset source.**
4
4
5
5
---
6
6
7
7
**Purpose (historical):** Centralize movie, edition, person, and studio data for all paid Majestic server installs. Prior matched movies and editions become available to every paid instance, reducing TMDB/OMDb lookups and improving edition matching accuracy.
8
8
9
-
**Context:** TMDB models Movie as atomic. Multi-version (theatrical vs director's cut, etc.) has been in their backlog since 2019—it requires a parent/child ontology they don't have. Majestic designed Movie → Edition from day one. The Curated API was the interim design. **majestic-canon** is the target: patch-based distribution, not live API.
9
+
**Context:** TMDB models Movie as atomic. Multi-version (theatrical vs director's cut, etc.) has been in their backlog since 2019 - it requires a parent/child ontology they don't have. Majestic designed Movie → Edition from day one. The Curated API was the interim design. **majestic-canon** is the target: patch-based distribution, not live API.
10
10
11
11
**Status:** Deprecated. Superseded by majestic-canon. Optional live-assist fallback only (under 5% of lookups).
12
12
@@ -312,12 +312,12 @@ Not required at launch. Build when telemetry schema exists and installs are live
312
312
## 11. Implementation Order
313
313
314
314
1.**Design doc** (this document) ✓
315
-
2.**Roadmap phase**— Add Phase 1.5 to ROADMAP
316
-
3.**curatedApiClient**— Minimal client: `lookupByTitleYear`, `lookupByUpc`. No-op when unconfigured.
317
-
4.**Scanner integration**— Call client before local DB when parsing filename/folder. Fallback unchanged.
7.**Barcode integration**- Call `GET /editions/upc/:upc` in barcodeService before UPCMDB.
321
321
322
322
---
323
323
@@ -343,4 +343,4 @@ Curated API does not compromise foundational principles. Keep it boring. Keep it
343
343
|**Dataset corrections retroactively alter identity**| Never silently mutate identity_hash or UPC normalization. Dataset improvements must be additive, not destructive. Version-signal any logic change. |
344
344
|**Latency creep**| 500ms is hard. Not advisory. If lookup drifts to 900ms, 1.2s, 2s, scanner UX degrades. Enforce at client. |
345
345
|**Curated API becomes "better TMDB"**| Stay narrow. Store identity-critical edition data, canonical film linkage, deterministic match keys. Do not become a general-purpose metadata mirror, popularity engine, or review aggregation system. Let TMDB chase popularity. Majestic chases correctness. |
346
-
|**Identity vs engagement data mixing**| Alternate overviews, cut-specific runtime, cast differences—fine if identity-critical. Do not store user taste signals, popularity adjustments, ranking hints, or behavioral metadata. The moment you mix identity with engagement, you blur the contract. Curated layer = edition correctness. Nothing else. |
346
+
|**Identity vs engagement data mixing**| Alternate overviews, cut-specific runtime, cast differences - fine if identity-critical. Do not store user taste signals, popularity adjustments, ranking hints, or behavioral metadata. The moment you mix identity with engagement, you blur the contract. Curated layer = edition correctness. Nothing else. |
Reuse `resolveEditionLabelForPoster` logic where applicable.
83
83
84
-
**Critical:** Edition labels must be **deterministic, cached, and not re-derived on every scan** from heuristics. If filename/folder parsing is used, it must produce a **normalized, stored label**— not a live guess. You're building a library, not a regex experiment.
84
+
**Critical:** Edition labels must be **deterministic, cached, and not re-derived on every scan** from heuristics. If filename/folder parsing is used, it must produce a **normalized, stored label**- not a live guess. You're building a library, not a regex experiment.
85
85
86
86
**Label survival:** Labels must survive file deletion and re-add. If a file is removed and later re-imported with the same fingerprint → same edition → same label. Label storage must be anchored to **media_file identity** (fingerprint or media_file_id), not to path. If labels depend on current folder path and get regenerated on re-import, you introduce drift.
87
87
88
88
For media files without disc_edition linkage:
89
89
90
90
- Store derived label (e.g. in media_file or a join table) at scan/match time
91
-
- Anchor to fingerprint or media_file_id — not path
91
+
- Anchor to fingerprint or media_file_id - not path
92
92
- Fallback: "Edition 1", "Edition 2" (deterministic by media_file_id)
93
93
94
94
---
@@ -103,7 +103,7 @@ Criteria (in order):
103
103
2. Resolution descending (4K before 1080p)
104
104
3. media_file_id ascending (tie-breaker)
105
105
106
-
**What we avoid:** Bitrate comparisons, "best HDR wins," audio heuristics, device-dependent reordering. If ordering depends on device, the UI feels unstable — the same movie reorders when device changes. Canonical first. Always.
106
+
**What we avoid:** Bitrate comparisons, "best HDR wins," audio heuristics, device-dependent reordering. If ordering depends on device, the UI feels unstable - the same movie reorders when device changes. Canonical first. Always.
107
107
108
108
---
109
109
@@ -138,9 +138,9 @@ You do not want a movie to show "Playable" while one edition is flagged as corru
138
138
139
139
```
140
140
Editions
141
-
• Theatrical — 4K HDR10 · Direct Play Ready
142
-
• Director's Cut — 1080p SDR · Direct Play Ready
143
-
• Steelbook — DV P7 · Not Supported on Apple TV
141
+
• Theatrical - 4K HDR10 · Direct Play Ready
142
+
• Director's Cut - 1080p SDR · Direct Play Ready
143
+
• Steelbook - DV P7 · Not Supported on Apple TV
144
144
```
145
145
146
146
Each selectable. Each with capability summary + compatibility status.
@@ -154,10 +154,10 @@ Default selection = first (canonical). User can change. Play uses selected editi
154
154
## What Not to Do
155
155
156
156
-**No silent auto-picking** when multiple editions exist
157
-
-**No client-side grouping**— server aggregates
158
-
-**No grid performance degradation**— aggregation is a server concern
159
-
-**No guessing**— explicit selection required
160
-
-**No "best available" collapse**— never auto-play or auto-select "best edition on this device." That is how you become Plex again. Majestic does not optimize away choice. It exposes it.
157
+
-**No client-side grouping**- server aggregates
158
+
-**No grid performance degradation**- aggregation is a server concern
159
+
-**No guessing**- explicit selection required
160
+
-**No "best available" collapse**- never auto-play or auto-select "best edition on this device." That is how you become Plex again. Majestic does not optimize away choice. It exposes it.
161
161
162
162
---
163
163
@@ -169,11 +169,11 @@ Default selection = first (canonical). User can change. Play uses selected editi
169
169
170
170
## Implementation Order
171
171
172
-
1.**Schema (if needed):** Edition label storage — ensure derived labels are cached, not recomputed per request
172
+
1.**Schema (if needed):** Edition label storage - ensure derived labels are cached, not recomputed per request
173
173
2.**API:** New `/library` response shape with `editions` array, `default_edition_index`
174
-
3.**API:** Aggregation logic — group media_files by movie_id, build editions array
174
+
3.**API:** Aggregation logic - group media_files by movie_id, build editions array
Copy file name to clipboardExpand all lines: docs/architecture/identity-layer.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Identity Layer
2
2
3
-
The identity layer defines how Majestic models ownership and edition truth. Edition identity is derived from content-derived inputs—never from paths, filenames, or mutable metadata.
3
+
The identity layer defines how Majestic models ownership and edition truth. Edition identity is derived from content-derived inputs - never from paths, filenames, or mutable metadata.
Copy file name to clipboardExpand all lines: docs/architecture/identity-matching.md
+9-9Lines changed: 9 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,15 +4,15 @@ Majestic matches media files to movies using a deterministic priority order. The
4
4
5
5
## Resolution Order
6
6
7
-
1.**Per-file `.majestic.json`**—`{filename}.majestic.json` in the same directory (e.g. `A New Standard.mkv.majestic.json`). Overrides directory-level for this file only. Use when a shared extras folder contains files from different movies.
7
+
1.**Per-file `.majestic.json`**-`{filename}.majestic.json` in the same directory (e.g. `A New Standard.mkv.majestic.json`). Overrides directory-level for this file only. Use when a shared extras folder contains files from different movies.
8
8
9
-
2.**Directory-level `.majestic.json`**—`.majestic.json` in the file's directory. Applies to all files in that folder. Written automatically when you resolve or re-match in the UI.
9
+
2.**Directory-level `.majestic.json`**-`.majestic.json` in the file's directory. Applies to all files in that folder. Written automatically when you resolve or re-match in the UI.
10
10
11
-
3.**Filename parsing**—`Title (Year).mkv`, `Title (Year) [Steelbook].mkv`, etc.
11
+
3.**Filename parsing**-`Title (Year).mkv`, `Title (Year) [Steelbook].mkv`, etc.
12
12
13
-
4.**Folder name parsing**— Parent directory name.
13
+
4.**Folder name parsing**- Parent directory name.
14
14
15
-
5.**User confirmation**— Unresolved or ambiguous matches appear in Settings → Unresolved.
15
+
5.**User confirmation**- Unresolved or ambiguous matches appear in Settings → Unresolved.
16
16
17
17
## What `.majestic.json` Contains
18
18
@@ -47,10 +47,10 @@ The matcher still **reads** `.majestic.json` if present; it just **skips writing
47
47
48
48
## Why This Design
49
49
50
-
-**DB is source of truth**— Survives rescans, renames, restarts. Scanner respects existing `media_file.movie_id`.
51
-
-**Per-file override**— Shared extras folders (e.g. `Extras/` with files from multiple movies) can use per-file `.majestic.json` to avoid directory-level overreach.
52
-
-**No file mutation**— We never modify the media file itself. Only metadata.
53
-
-**Transparent**— A visible JSON file in the folder. Users who organize by folder can inspect or edit it.
50
+
-**DB is source of truth**- Survives rescans, renames, restarts. Scanner respects existing `media_file.movie_id`.
51
+
-**Per-file override**- Shared extras folders (e.g. `Extras/` with files from multiple movies) can use per-file `.majestic.json` to avoid directory-level overreach.
52
+
-**No file mutation**- We never modify the media file itself. Only metadata.
53
+
-**Transparent**- A visible JSON file in the folder. Users who organize by folder can inspect or edit it.
0 commit comments