Ignore:
Timestamp:
09/30/2026 08:22:57 AM (3 hours ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
31680c3
Parents:
ca260d1
Message:

Outbox serves the same Note as /ap/notes/:id — no more column list

The hub could not find soundfabrics' hashtags. Fetched on its own
(/ap/notes/:id) a post carries #kawaii; read from the outbox, it does not.
outboxSlice loaded posts with a hand-kept column list, and that list fails
silently: a forgotten column is undefined, buildNote decides without it,
and nothing errors. tags was missing — and so were poll_json (a poll left
the outbox as a plain note), quote_uri/quote_actor (a quote post lost its
quote), cover_alt and language.

This was the fourth time. fan_only once sent a friends-only post out as
public; paid once put the full text of a paid post in the outbox. Each fix
added a name to the list and a warning above it. The note route has always
used SELECT *, so the outbox now does the same: the two paths can no longer
drift apart.

The new test compares the WHOLE object, outbox against the single Note,
rather than a handful of fields — a column added later that the outbox
doesn't carry fails it immediately. Verified it goes red on the old code.

Co-Authored-By: Claude Opus 5.5 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/ActivityPubService.js

    rca260d1 r76bd53c  
    11591159  const gaten = (n) => Array.from({ length: n }, () => '?').join(',');
    11601160  const posts = postIds.length ? db.prepare(
    1161     // fan_only en ap_visibility MOETEN mee. buildNote adresseert hierop, en
    1162     // zonder deze twee kolommen is post.fan_only altijd undefined: elke
    1163     // fan-only post ging dan de outbox uit met to: as:Public, terwijl hij
    1164     // alleen aan vrienden geserveerd wordt. Een volger kreeg dus een
    1165     // vrienden-post met een publiek etiket erop, en die mag hij dan publiek
    1166     // boosten. Gevonden tijdens de FEP-1580 end-to-end test (shaer-fuyo).
    1167     // EN paid + excerpt, om exact dezelfde reden (Barts melding, 15-8). Zonder
    1168     // `paid` is post.paid hier `undefined`, dan slaat buildNote zijn redactie
    1169     // over en gaat de VOLLEDIGE tekst van een betaalde post de outbox uit. Zo
    1170     // kwam een post via een hub-actor gewoon te lezen. `excerpt` moet mee omdat
    1171     // de teaser daaruit komt; zonder dat veld valt hij terug op de eerste
    1172     // alinea van precies de tekst die verborgen hoort te blijven.
     1161    // ALLE KOLOMMEN, zoals /ap/notes/:id ook doet. Hier stond een lijst, en
     1162    // die faalde stil: een vergeten kolom is `undefined` en geen fout, en
     1163    // buildNote besluit dan zonder dat veld. Het ging vier keer mis voordat
     1164    // deze regel er stond --
     1165    //   fan_only/ap_visibility: een vriendenpost ging de deur uit als publiek
     1166    //     (shaer-fuyo);
     1167    //   paid/excerpt: de VOLLEDIGE tekst van een betaalde post stond in de
     1168    //     outbox (Barts melding, 15-8);
     1169    //   tags, poll_json, quote_uri/quote_actor, cover_alt, language: geen
     1170    //     hashtags, een peiling als gewone post, een citaat zonder citaat
     1171    //     (Robin, 30-9 -- de hub vond de tags van soundfabrics niet, want die
     1172    //     staan niet in de tekst en kwamen alleen via de outbox binnen).
    11731173    //
    1174     // Dit is een KOLOMMENLIJST, en die faalt stil: een vergeten kolom is
    1175     // `undefined` en niet een fout. Wie hier een veld toevoegt waar buildNote
    1176     // op beslist, moet het HIER ook toevoegen.
    1177     `SELECT id, slug, title, excerpt, content, cover_image_url, cover_video_url, nsfw, content_warning,
    1178             c2s_attachments, quote_json, embed_json, published_at, created_at,
    1179             fan_only, ap_visibility, paid, paid_min_cents
    1180        FROM posts WHERE id IN (${gaten(postIds.length)})`).all(...postIds) : [];
     1174    // De outbox en de losse Note horen HETZELFDE object te zijn; wie een post
     1175    // op twee manieren ophaalt, hoort geen twee verschillende berichten te
     1176    // zien. test/outbox-gelijk-aan-note.test.js legt dat vast, voor elk veld,
     1177    // ook voor velden die er later bijkomen.
     1178    `SELECT * FROM posts WHERE id IN (${gaten(postIds.length)})`).all(...postIds) : [];
    11811179  const tracks = trackIds.length ? db.prepare(
    11821180    `SELECT ${TRACK_KOLOMMEN}
Note: See TracChangeset for help on using the changeset viewer.