v26.05.27.1: subscriptions hub + post-card merge + sidecar audit #29
Reference in New Issue
Block a user
Delete Branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Eight commits, three themes:
1. Subscriptions hub restructure (
9322c98). Collapses/credentialsand/downloadsinto a single/subscriptionsparent with three internal subtabs (Subscriptions default | Downloads | Settings) — tab state via?tab=query param, mirroring ArtistView's pattern. Adopts GS visual language across all three: color-codedPlatformChip, GS-style Downloads dashboard (stat chips + popover filter + maintenance menu + retry-per-row), GS-style credentials card grid in Settings. Pulls download + schedule settings out ofSettings → Importinto the new Settings subtab. New backend endpointGET /api/downloads/stats?window_hours=(pinned by two integration tests)./credentialsand/downloadskeep working as bookmark-safety redirects into the new?tab=form.2. PostCard absorbs PostModal (
4d2c464). The wider PostCard layout had enough real estate to be the canonical post surface, so the modal is collapsed in. Compact state unchanged. Click-to-expand inline: full title, mosaic of ALL post images via PostImageGrid (lazy-loaded uncapped thumbnails via getPostFull), full sanitized-HTML description, attachments as downloadable pills. Mosaic image clicks still open ImageViewer scoped to the post. Per-card local state —usePostModalStoredeleted.3. Sidecar audit fixes (
ae8c78a,bd3f996,b7b313c,aa28bdd). Audit of one sample sidecar per platform on the operator's/mnt/Data/Patreon/archive surfaced three parser bugs that had been silently corrupting non-Patreon Posts since FC-3 shipped:idvspost_id: gallery-dl puts the per-attachment id inidand the actual post id inpost_id. Reorder the external_post_id chain to(post_id, id, index, message_id)so SubscribeStar's multi-image posts no longer fragment into N rows.post_urlwas the file CDN URL. New_derive_post_url(platform, data)synthesizes proper permalinks per platform; Patreon's bareurl(a real permalink) stays as-is.messagebody field not captured — added to the description fallback chain.titlealways empty (separate fix already shipped inae8c78afor the parser + alembic 0024 backfill).12 new sidecar-util tests pin per-platform parsing behavior.
Migrations
Two destructive migrations land in this release:
alembic 0024_backfill_post_title_from_description— backfills the synthesized title for existing Post rows wherepost_title IS NULL OR ''and a description is present. Idempotent.alembic 0025_fix_subscribestar_post_ids— walks each SubscribeStar / HF / Discord Post, reads its sidecar from disk (ImageRecord.path→ sidecar JSON), overwritesexternal_post_id(subscribestar only) +post_url(all three). After updates, merges SubscribeStar Post groups under one source that now share an external_post_id (same ImageProvenance pre-delete + repoint dance as alembic 0022). Pure-SQL Pixivpost_urlbackfill in the same migration. Idempotent. Migration logs per-platform counts (read N sidecars, updated N Posts, N had no resolvable sidecar) to stdout.After this release, the only Posts still pointing at file URLs are those whose ImageRecord.path doesn't resolve on disk at migration time (orphan filesystem state) — a future deep-scan would catch the rest.
Infrastructure
b8ad17cbuild.yml race fix. Cutting a release fires both the push-to-main and push-to-tag workflows in parallel. main-push's sign-extension takes 1–5 min for AMO; tag-push's build-web's "Download signed XPI" raced past it and 404'd on the missingext-<version>release every time (operator hit this on v26.05.27.0). Wrap the release lookup in a 20-iteration sleep+retry loop (30s × 20 = 10 min upper bound) so tag-push naturally waits for main-push's sign step.Test plan
:latestpulled, services force-recreated, alembic 0024 + 0025 applied cleanlyread N sidecarsper platform (subscribestar/HF/discord) on the operator's database/subscriptionslands on Subscriptions subtab by default;?tab=downloadsand?tab=settingswork; legacy/credentialsand/downloadsredirect into the hubpost_urlresolves tosubscribestar.com/posts/<id>not a CDN URLSELECT external_post_id, COUNT(*) FROM post JOIN source ON ... WHERE platform='subscribestar' GROUP BY 1 HAVING COUNT(*) > 1→ 0 rows)