Changeset 279ca0b in Klonkt for src/routes/posts.js


Ignore:
Timestamp:
08/06/2026 12:42:50 PM (5 weeks ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
32a4ffb
Parents:
bedd7a6
git-author:
Robin <roboburr@…> (08/06/2026 12:42:40 PM)
git-committer:
roboburr <roboburr@…> (08/06/2026 12:42:50 PM)
Message:

De derde reactiebron ook naar ap_my_reactions (shaer-ipb)

ap_interactions.acted_like/acted_boost -- wat JIJ deed met een reactie onder je
eigen post -- was de derde bron van 'heb ik hierop gereageerd'. shaer-9e9 trok de
andere twee samen en liet deze staan omdat hij op het interactie-rij-id
gesleuteld was en de tussentabel op de object-URI.

De betekeniskeuze die de bead eerst wilde beantwoorden: dezelfde note, geliket
als comment en als post, wordt EEN feit. Er gaat immers ook maar een Like de
fediverse in; twee knoppen die los van elkaar aan konden staan voor hetzelfde
object was eerder een bug dan een feature. Mechanisch blijkt dat al veilig:
markLiked en markBoosted zijn kale UPDATEs op ap_timeline die nul rijen raken als
de URI daar niet staat, en upsertBoostedNote draait alleen met opts.note mee.

Volgorde zoals bij shaer-9e9, en om dezelfde reden -- een leespad dat naar de
tussentabel wijst terwijl de rijen nog in de kolommen staan laat reacties STIL
verdwijnen:

schrijven fedi-react roept setReaction aan; acted_* loopt nog als afgeleide

mee, hetzelfde vangnet dat ap_timeline.liked na shaer-9e9 is. Ook de
toggle leest nu uit de tussentabel: las de knop de ene bron en de
richting de andere, dan stuurt een divergentie een Undo voor iets dat
nooit verstuurd is.

migreren REACTIONS_MIGRATION_VERSION 1 -> 2, derde stap erbij. Een bump laat

alle stappen opnieuw lopen; ze zijn alle drie idempotent. Rijen
zonder object_uri vallen af, en dat verliest per constructie niets:
fedi-react eist een object_uri voordat acted_* gezet kan worden.

lezen getInteractions doet een batch-lookup langs dezelfde sleutel als de

schrijfkant, dus geen N+1 in een drukke thread.

Het backfill-script zou anders vals alarm slaan: een reactie op een COMMENT hoort
geen tijdlijnrij te hebben, dus die telt niet meer als wees. Er is een controle
bij voor acted_* zonder tegenhanger.

Gemeten op een kopie van dev: scheefActed 1 -> 0, tussentabel 19 -> 20, wees
onveranderd. Suite 472/472. Gecontroleerd dat de tests bijten: laat het leespad
weer uit de kolom lezen en vier van de zes vallen om.

De karakteriseringstest zette de versievlag hard op 1 en zou bij elke bump
omvallen zonder dat er iets stuk is; die toetst nu het gedrag (ouder = opnieuw,
gelijk of hoger = overslaan) in plaats van het getal.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    rbedd7a6 r279ca0b  
    15571557  const kind = req.body.kind === 'boost' ? 'boost' : 'like';
    15581558  if (parent && parent.post_id === post.id && parent.object_uri) {
    1559     if (kind === 'boost') {
    1560       // Toggle: boost an unboosted comment, or retract it (Undo Announce) if already boosted.
    1561       const on = !parent.acted_boost;
    1562       ActivityPubService.sendInteraction(site, on ? 'boost' : 'unboost', parent.object_uri, parent.actor_uri)
    1563         .catch((e) => console.warn('[AP] reaction failed:', e.message));
    1564       ActivityPubService.setInteractionBoosted(parent.id, on);
    1565     } else {
    1566       // Toggle: like an unliked comment, or un-favourite (Undo Like) if already liked.
    1567       const on = !parent.acted_like;
    1568       ActivityPubService.sendInteraction(site, on ? 'like' : 'unlike', parent.object_uri, parent.actor_uri)
    1569         .catch((e) => console.warn('[AP] reaction failed:', e.message));
    1570       ActivityPubService.setInteractionLiked(parent.id, on);
    1571     }
     1559    // Toggle: react, or retract it (Undo Announce / Undo Like) if already on.
     1560    // De stand komt uit dezelfde bron als de knop die je zag; leest de toggle uit
     1561    // de kolom en de knop uit de tussentabel, dan draait een divergentie de
     1562    // richting om en stuur je een Undo voor iets dat nooit is verstuurd.
     1563    const ik = ActivityPubService.getReaction(site.slug, parent.object_uri);
     1564    const on = kind === 'boost' ? !ik.boosted : !ik.liked;
     1565    ActivityPubService.sendInteraction(site, on ? kind : `un${kind}`, parent.object_uri, parent.actor_uri)
     1566      .catch((e) => console.warn('[AP] reaction failed:', e.message));
     1567    // De tussentabel is de waarheid (shaer-ipb), gesleuteld op object_uri -- net
     1568    // als de Like die hierboven de fediverse in gaat. acted_* blijft voorlopig
     1569    // als afgeleide meelopen, hetzelfde vangnet dat ap_timeline.liked na
     1570    // shaer-9e9 is: pas weghalen als deze migratie een release heeft ingelopen.
     1571    ActivityPubService.setReaction(site.slug, parent.object_uri, kind, on);
     1572    if (kind === 'boost') ActivityPubService.setInteractionBoosted(parent.id, on);
     1573    else ActivityPubService.setInteractionLiked(parent.id, on);
    15721574  }
    15731575  res.redirect(`${res.locals.siteUrlBase || ''}/${post.slug}#fediverse`);
Note: See TracChangeset for help on using the changeset viewer.