Skip to content

feat(core): project track.album_id in postgres list + get + insert + update - #209

Merged
InstaZDLL merged 2 commits into
mainfrom
feat/core-track-album-id-projection
Jun 8, 2026
Merged

feat(core): project track.album_id in postgres list + get + insert + update#209
InstaZDLL merged 2 commits into
mainfrom
feat/core-track-album-id-projection

Conversation

@InstaZDLL

@InstaZDLL InstaZDLL commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Summary

Closes the asymmetry documented in the server's CLAUDE.md (and in the desktop `project_sprint_4_web_progress.md` follow-ups note).

Phase 4.d.0.1 (server PR #34) added the `album` table + the nullable `track.album_id` FK. Phase 4.d.0.4 (server PR #36) added the album drill-down endpoint which projects the real value. The legacy `/api/v1/profiles/{p}/libraries/{l}/tracks` collection still NULL-projected the column because the SELECT lives here in waveflow-core and predates the album surface — so the desktop / web client saw `album_id = null` on the per-library track list even when the row was materialised by the apply pipeline.

This PR swaps every `NULL::bigint AS album_id` for `t.album_id` (or `album_id` in the RETURNING blocks) in 4 sites:

  • `PostgresTrackRepository::list_for_library` (SELECT)
  • `PostgresTrackRepository::get_for_library` (SELECT)
  • `PostgresTrackRepository::insert_for_library` (RETURNING)
  • `PostgresTrackRepository::update_for_library` (RETURNING)

INSERT doesn't set `album_id` (the column list deliberately excludes it — track→album materialisation owns that field via the sync apply pipeline, not the CRUD write path), so RETURNING projects `null` for freshly inserted rows. UPDATE doesn't touch it either, so RETURNING projects whatever's stored. Both correct.

The module-level doc comment now calls out that `album_id` is the projected-real case; the remaining NULL casts (`album_title`, `artist_`, `artwork_`) stay until their materialisation paths land server-side.

Test plan

  • `cargo check --manifest-path src-tauri/Cargo.toml -p waveflow-core --features postgres --no-default-features` clean
  • `cargo check --manifest-path src-tauri/Cargo.toml --workspace --all-targets` clean (covers the sqlite consumer in `crates/app` — no impact since it doesn't go through these methods)
  • `cargo test -p waveflow-core --features postgres --lib --no-run` builds clean
  • `cargo fmt --all` clean
  • CI runs the full suite

No desktop behavior change — `crates/app` consumes `waveflow-core` via the `sqlite` feature flag which routes through the sqlite repos, not the postgres ones touched here.

Follow-up

A small PR on waveflow-server bumps the `waveflow-core` git rev in `Cargo.toml` to pick this up once this lands on `main`.

Summary by CodeRabbit

  • Bug Fixes
    • Correction : les identifiants d'album sont désormais retournés correctement lors de la récupération et de l'énumération des pistes depuis la bibliothèque, au lieu de valeurs vides.

…update

Closes the asymmetry documented on the server's CLAUDE.md and in
the desktop's 4.d.0.4 follow-ups note. Phase 4.d.0.1 added the
`album` table + the nullable `track.album_id` FK; phase 4.d.0.4
added the album drill-down endpoint which projects the real value.
The legacy `/tracks` collection still NULL-projected the column
because the SELECT lived here in waveflow-core and the migration
predates the album surface.

Swap every `NULL::bigint AS album_id` for `t.album_id` (or
`album_id` in the RETURNING blocks) in:
- `PostgresTrackRepository::list_for_library`
- `PostgresTrackRepository::get_for_library`
- `PostgresTrackRepository::insert_for_library` (RETURNING)
- `PostgresTrackRepository::update_for_library` (RETURNING)

INSERT doesn't set `album_id` (the column list deliberately
excludes it — track materialisation owns that field via the sync
apply pipeline, not the CRUD path), so RETURNING projects NULL for
freshly inserted rows. UPDATE doesn't touch it either, so RETURNING
projects whatever's stored. Both correct.

Refresh the module-level doc comment to call out the asymmetry
closure — the other NULL casts (`album_title`, `artist_*`,
`artwork_*`) stay until those materialisation paths land.

waveflow-server picks this up via a follow-up rev bump in
`Cargo.toml`; no behavior change on the desktop side (this crate
is also consumed by `crates/app` via the `sqlite` feature, which
doesn't go through these methods).

Signed-off-by: InstaZDLL <github.105mh@8shield.net>
@InstaZDLL InstaZDLL added the scope: backend Rust/Tauri backend (src-tauri/) label Jun 8, 2026
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Le dépôt PostgreSQL projette maintenant album_id comme valeur réelle depuis la table track au lieu d'une constante NULL. Les trois opérations de données (list_for_library, get_for_library, insert_for_library) retournent désormais l'ID d'album réel, et la documentation interne précise ce changement d'état.

Changes

Projection correcte d'album_id dans le référentiel de pistes

Couche / Fichier(s) Résumé
Requêtes et documentation album_id
src-tauri/crates/core/src/repository/postgres/track.rs
Le commentaire du module clarifie que album_id est désormais projeté réellement au lieu de NULL. Les trois requêtes (list_for_library ligne 76, get_for_library ligne 132, insert_for_library ligne 208) remplacent NULL::bigint AS album_id par t.album_id ou album_id pour retourner la valeur réelle de la base de données.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Possibly related PRs

  • InstaZDLL/WaveFlow#186: Le PR principal ajuste la projection SQL dans track.rs pour projeter album_id depuis track au lieu d'un NULL, ce qui modifie directement la même construction de TrackRow introduite par ce PR.
  • InstaZDLL/WaveFlow#187: Le correctif pour projeter album_id dans les requêtes SQL list_for_library/get_for_library est directement lié aux modifications de projection TrackRow SELECT de ce PR.

Suggested labels

type: feat, size: m, scope: backend

Poem

🎵 NULL s'envole, album_id résonne enfin,
Dans les requêtes SQL qui brille sans fin,
La piste retrouve son identité oubliée,
Trois requêtes harmonisées, une donnée libérée! 🎶

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Le titre suit précisément la convention Conventional Commits et décrit clairement le changement principal : projeter track.album_id réel dans quatre opérations SQL (list, get, insert, update).
Description check ✅ Passed La description couvre complètement le contexte historique, les quatre sites modifiés, le raisonnement sur INSERT/UPDATE, la stratégie de test locale et le plan de suivi. Elle remplit les sections du template.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/core-track-album-id-projection

Comment @coderabbitai help to get the list of available commands and usage tips.

@InstaZDLL InstaZDLL added type: feat New feature size: s 10-50 lines labels Jun 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src-tauri/crates/core/src/repository/postgres/track.rs (1)

281-285: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

update_for_library renvoie encore album_id à NULL

La clause RETURNING de l’UPDATE projette NULL::bigint AS album_id. Ça crée une incohérence avec list_for_library, get_for_library et insert_for_library, et peut faire perdre album_id dans la réponse juste après une mise à jour.

💡 Correctif proposé
           RETURNING id,
                     library_id,
                     title,
-                    NULL::bigint  AS album_id,
+                    album_id,
                     NULL::text    AS album_title,
                     NULL::bigint  AS artist_id,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src-tauri/crates/core/src/repository/postgres/track.rs` around lines 281 -
285, La clause RETURNING de update_for_library renvoie album_id et album_title
comme NULL (NULL::bigint AS album_id, NULL::text AS album_title), ce qui casse
la cohérence avec list_for_library, get_for_library et insert_for_library et
fait perdre album_id après un UPDATE; modifie la requête dans la fonction
update_for_library pour retourner les colonnes réelles album_id et album_title
(pas des NULL) dans la clause RETURNING afin d'aligner le format de la réponse
avec list_for_library/get_for_library/insert_for_library et préserver la valeur
d'album_id après la mise à jour.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src-tauri/crates/core/src/repository/postgres/track.rs`:
- Around line 281-285: La clause RETURNING de update_for_library renvoie
album_id et album_title comme NULL (NULL::bigint AS album_id, NULL::text AS
album_title), ce qui casse la cohérence avec list_for_library, get_for_library
et insert_for_library et fait perdre album_id après un UPDATE; modifie la
requête dans la fonction update_for_library pour retourner les colonnes réelles
album_id et album_title (pas des NULL) dans la clause RETURNING afin d'aligner
le format de la réponse avec list_for_library/get_for_library/insert_for_library
et préserver la valeur d'album_id après la mise à jour.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3359636b-d892-4fda-a866-3bed466c5238

📥 Commits

Reviewing files that changed from the base of the PR and between 4bec4bf and b793b16.

📒 Files selected for processing (1)
  • src-tauri/crates/core/src/repository/postgres/track.rs

@InstaZDLL InstaZDLL self-assigned this Jun 8, 2026
CR catch on PR #209: the previous commit projected `album_id` in
list / get / insert but missed `update_for_library`'s RETURNING
clause — `replace_all` matched the 19-space indent of the other
RETURNING block but not the 20-space indent here, so the UPDATE
path silently kept `NULL::bigint AS album_id` and a successful
PATCH would have nulled the field in the response.

Swap that one site too. `album_title` stays NULL across all four
methods (matches the documented "remaining NULL casts stay until
their materialisation path lands" — only `album_id` had a
schema-side column to project against).

Signed-off-by: InstaZDLL <github.105mh@8shield.net>
@InstaZDLL

Copy link
Copy Markdown
Owner Author

@coderabbitai resolved album_id in 60550e1 — missed the update_for_library RETURNING site in the previous commit (indent mismatch: 19 spaces vs 20 in the other RETURNING block, my replace_all only caught the matching indent). All 4 sites now project album_id consistently.

album_title skipped: the other 3 methods (list / get / insert RETURNING) also project NULL::text AS album_title because the SELECT doesn't join album to fetch the title — the wire shape stays uniform at {album_id: Option<i64>, album_title: None} across the 4 paths, matching the module doc that calls out "the remaining NULL casts (album_title, artist_, artwork_) stay until their materialisation paths land server-side." Projecting the real title here alone would re-introduce the asymmetry this PR exists to close.

@InstaZDLL
InstaZDLL merged commit 4354fec into main Jun 8, 2026
13 checks passed
@InstaZDLL
InstaZDLL deleted the feat/core-track-album-id-projection branch June 8, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: backend Rust/Tauri backend (src-tauri/) size: s 10-50 lines type: feat New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant