diff --git a/plugins/EXTRACTING-A-PLUGIN.md b/plugins/EXTRACTING-A-PLUGIN.md index c85317d8..d630307a 100644 --- a/plugins/EXTRACTING-A-PLUGIN.md +++ b/plugins/EXTRACTING-A-PLUGIN.md @@ -168,23 +168,28 @@ avoid is not a wrong call; it is a tree left half-moved with a question attached - **Already half-disabled**: `hono.ts` mount and `schema.ts` export are commented out since 2026-08-13; `officer_db/src/index.ts:49` is still live. So the tree is mid-migration already. -### The per-user shape, which is why music was chosen +### The per-user model is NOT tonight's work -```ts -personal: ['/favorites', '/now-playing', '/playlists', '/queue'], -``` +`personal: ['/favorites', '/now-playing', '/playlists', '/queue']` on music's registry entry, the four +user-scoped tables, and the question of what a member's grant *means* — **all of it stays exactly as it +is. Do not design it, do not improve it, do not think about it.** It will be built inside the plugin +later, which is the whole reason the platform's answer is a uniform read/write and nothing more. -No `readOnlyWrites`. Note `/queue` — **no such route exists**, in the sidecar or the frontend. Dead or -aspirational; find out which. +Two facts that make leaving it alone safe rather than lazy: -Four tables, all `userId` + cascade to `users.id`: `music_favorites`, `music_playlists`, -`music_playlist_items`, `music_now_playing` (composite PK `(userId, device)`). +- **The web frontend does not use those routes at all.** Favourites, playlists and now-playing are used + only by the phone and tablet apps. Nothing you can see in a browser depends on them, so nothing in this + extraction can regress by carrying them across untouched. +- `/queue` is in that list and **no such route exists**, in the sidecar or anywhere else. Dead or + aspirational. Carry it as-is; do not investigate. -**And the mismatch that makes music the interesting case:** the state is per-user, the library is one -global directory. `MUSIC_ROOT = join(homedir(), 'Music')`, and `stream-audio.ts` and `cliamp-ws.ts` each -take `homedir()` as their root independently. So a granted member's favourites are theirs, while -`/stream` serves them the **owner's** files and cliamp spawns a process in the **owner's** home. The -app-store entry promises a configurable `library` folder and **nothing reads it**. +Move the routes, the tables and the queries verbatim. `userId` keeps arriving from `X-Officer-User` and +the queries keep scoping by it, exactly as today. + +**The one mechanical consequence you cannot avoid:** `registry.test.ts` tests the `personal` mechanism +*through* the music entry, and `registry.ts` uses music as its worked example in prose. Removing the +entry breaks those tests. Re-anchor them on another entry that has `personal` — the smallest edit that +makes them green and still test the mechanism. That is a test fix, not a redesign. ### How to decide the three, if you want a default @@ -206,8 +211,7 @@ left in the platform is a documented seam; a piece left dangling is a bug. `assertCapabilityTotality` is **not** part of this. It is worth fixing eventually and the cliamp routes are the live example of the drift it cannot see, but both are someone else's evening. -**Do not** invent music's per-user visibility model during the move. Extract with the semantics it has, or -the two changes tangle and a bug in either is a bug in both. + ---