| 1 | #!/usr/bin/env node
|
|---|
| 2 | //
|
|---|
| 3 | // Reactie-migratie handmatig draaien (shaer-9e9).
|
|---|
| 4 | //
|
|---|
| 5 | // Normaal hoef je dit NIET: migrateReactions() draait bij boot, één keer per
|
|---|
| 6 | // REACTIONS_MIGRATION_VERSION-bump, net als de self-heal. Dit script is er om
|
|---|
| 7 | // vooraf te kijken wat er zou gebeuren, of om het gericht op één instance te
|
|---|
| 8 | // forceren.
|
|---|
| 9 | //
|
|---|
| 10 | // node scripts/backfill-reactions.mjs --dry-run
|
|---|
| 11 | // node scripts/backfill-reactions.mjs # respecteert de versievlag
|
|---|
| 12 | // node scripts/backfill-reactions.mjs --force # ook als de vlag al staat
|
|---|
| 13 | //
|
|---|
| 14 | // Bewust een schil om dezelfde functie die bij boot draait: twee implementaties
|
|---|
| 15 | // van een migratie lopen uiteen, en dan repareert de ene wat de andere niet ziet.
|
|---|
| 16 | //
|
|---|
| 17 | // Wat het doet, en waarom allebei nodig is:
|
|---|
| 18 | //
|
|---|
| 19 | // HERSLEUTELEN De oude interact-route bewaarde de URI waarmee je binnenkwam,
|
|---|
| 20 | // en de bookmarklet geeft de permalink door. Sinds de reacties
|
|---|
| 21 | // op de canonieke object-URI gezocht worden, zouden die rijen
|
|---|
| 22 | // wees zijn. De created_at reist mee.
|
|---|
| 23 | // AANVULLEN Alles wat op oude code via de Krant is gegeven staat alleen in
|
|---|
| 24 | // ap_timeline.liked/boosted. Zonder deze stap toont het als
|
|---|
| 25 | // niet-gereageerd -- en klikt iemand opnieuw, met een tweede
|
|---|
| 26 | // Like de fediverse in als gevolg.
|
|---|
| 27 | // UIT REACTIES De derde bron (shaer-ipb): ap_interactions.acted_like/_boost,
|
|---|
| 28 | // wat jij deed met een reactie ONDER je eigen post. Zelfde
|
|---|
| 29 | // gevolg als hierboven, alleen op een ander oppervlak.
|
|---|
| 30 | //
|
|---|
| 31 | // Wat het NIET kan: bij AANVULLEN de oorspronkelijke reactiedatum herstellen.
|
|---|
| 32 | // Wanneer je reageerde is nergens vastgelegd, dus die rijen krijgen de datum van
|
|---|
| 33 | // nu. Bij hersleutelen blijft de datum wel behouden.
|
|---|
| 34 |
|
|---|
| 35 | import db from '../src/config/database.js';
|
|---|
| 36 | import { migrateReactions } from '../src/services/ActivityPubService.js';
|
|---|
| 37 |
|
|---|
| 38 | const dryRun = process.argv.includes('--dry-run');
|
|---|
| 39 | const force = process.argv.includes('--force');
|
|---|
| 40 |
|
|---|
| 41 | const meet = () => ({
|
|---|
| 42 | tussentabel: db.prepare('SELECT COUNT(*) AS n FROM ap_my_reactions').get().n,
|
|---|
| 43 | liked: db.prepare('SELECT COUNT(*) AS n FROM ap_timeline WHERE liked = 1').get().n,
|
|---|
| 44 | boosted: db.prepare('SELECT COUNT(*) AS n FROM ap_timeline WHERE boosted = 1').get().n,
|
|---|
| 45 | scheef: db.prepare(`
|
|---|
| 46 | SELECT COUNT(*) AS n FROM ap_timeline t
|
|---|
| 47 | WHERE (t.liked = 1 OR t.boosted = 1)
|
|---|
| 48 | AND NOT EXISTS (SELECT 1 FROM ap_my_reactions r
|
|---|
| 49 | WHERE r.site_slug = t.slug AND r.target_uri = t.id)`).get().n,
|
|---|
| 50 | // Een reactie op een COMMENT hoort geen tijdlijnrij te hebben, dus die telt
|
|---|
| 51 | // hier niet als wees -- anders slaat de controle hieronder alarm op precies
|
|---|
| 52 | // wat stap 3 net goed heeft gezet.
|
|---|
| 53 | wees: db.prepare(`
|
|---|
| 54 | SELECT COUNT(*) AS n FROM ap_my_reactions r
|
|---|
| 55 | WHERE NOT EXISTS (SELECT 1 FROM ap_timeline t
|
|---|
| 56 | WHERE t.slug = r.site_slug AND t.id = r.target_uri)
|
|---|
| 57 | AND NOT EXISTS (SELECT 1 FROM ap_interactions i WHERE i.object_uri = r.target_uri)`).get().n,
|
|---|
| 58 | scheefActed: db.prepare(`
|
|---|
| 59 | SELECT COUNT(*) AS n FROM ap_interactions i
|
|---|
| 60 | JOIN posts p ON p.id = i.post_id
|
|---|
| 61 | JOIN sites s ON s.id = p.site_id
|
|---|
| 62 | WHERE (i.acted_like = 1 OR i.acted_boost = 1) AND IFNULL(i.object_uri, '') <> ''
|
|---|
| 63 | AND NOT EXISTS (SELECT 1 FROM ap_my_reactions r
|
|---|
| 64 | WHERE r.site_slug = s.slug AND r.target_uri = i.object_uri)`).get().n,
|
|---|
| 65 | });
|
|---|
| 66 |
|
|---|
| 67 | const voor = meet();
|
|---|
| 68 | console.log('vooraf :', JSON.stringify(voor));
|
|---|
| 69 |
|
|---|
| 70 | const uit = migrateReactions({ dryRun, force: force || dryRun });
|
|---|
| 71 | if (uit.overgeslagen) {
|
|---|
| 72 | console.log('\novergeslagen: de versievlag staat al. Gebruik --force om toch te draaien.');
|
|---|
| 73 | process.exit(0);
|
|---|
| 74 | }
|
|---|
| 75 | if (dryRun) {
|
|---|
| 76 | console.log(`\n--dry-run: zou ${uit.hersleuteld} rij(en) hersleutelen, ${uit.aangevuld} aanvullen`
|
|---|
| 77 | + ` en ${uit.reacties} uit reacties overnemen. Niets geschreven.`);
|
|---|
| 78 | process.exit(0);
|
|---|
| 79 | }
|
|---|
| 80 |
|
|---|
| 81 | const na = meet();
|
|---|
| 82 | console.log('hersleuteld:', uit.hersleuteld, ' aangevuld:', uit.aangevuld, ' uit reacties:', uit.reacties);
|
|---|
| 83 | console.log('achteraf :', JSON.stringify(na));
|
|---|
| 84 |
|
|---|
| 85 | // De twee controles die tellen. Blijft er een vlag zonder tegenhanger, dan is de
|
|---|
| 86 | // tussentabel niet compleet en tonen reacties als niet-gegeven. Blijft er een
|
|---|
| 87 | // tussentabel-rij zonder tijdlijnrij, dan is die op iets buiten je tijdlijn
|
|---|
| 88 | // gericht (legitiem) OF nog op een permalink (niet legitiem) -- vandaar de
|
|---|
| 89 | // waarschuwing in plaats van een fout.
|
|---|
| 90 | if (na.scheef !== 0) {
|
|---|
| 91 | console.error(`\nFOUT: nog ${na.scheef} rij(en) met een vlag zonder tegenhanger.`);
|
|---|
| 92 | process.exit(1);
|
|---|
| 93 | }
|
|---|
| 94 | if (na.scheefActed !== 0) {
|
|---|
| 95 | console.error(`\nFOUT: nog ${na.scheefActed} reactie(s) onder je eigen posts met acted_* zonder tegenhanger.`);
|
|---|
| 96 | process.exit(1);
|
|---|
| 97 | }
|
|---|
| 98 | if (na.wees > voor.wees) {
|
|---|
| 99 | console.error('\nFOUT: er zijn tussentabel-rijen bijgekomen die nergens op slaan.');
|
|---|
| 100 | process.exit(1);
|
|---|
| 101 | }
|
|---|
| 102 | if (na.wees) {
|
|---|
| 103 | console.warn(`\nLET OP: ${na.wees} tussentabel-rij(en) zonder tijdlijnrij. Dat mag (een reactie op iets\n`
|
|---|
| 104 | + 'buiten je tijdlijn), maar controleer of er geen permalinks tussen zitten van een post die je\n'
|
|---|
| 105 | + 'wel kent -- die zouden hersleuteld moeten zijn.');
|
|---|
| 106 | }
|
|---|
| 107 | console.log('\nOK: elke vlag heeft een tegenhanger in de tussentabel.');
|
|---|