Changeset a9ede28 in Klonkt


Ignore:
Timestamp:
08/08/2026 07:56:50 AM (5 weeks ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
66d97b8
Parents:
86e6a45
git-author:
Robin <roboburr@…> (08/08/2026 07:56:48 AM)
git-committer:
roboburr <roboburr@…> (08/08/2026 07:56:50 AM)
Message:

Open hulpvragen worden nooit afgekapt (shaer-6wt)

Ik vond dit zelf en zette het op P3: "vergt tientallen hulpvragen bij een
guardian". Bart: "precies de jeugdzorgmedewerker."

DAT IS GEEN RANDGEVAL MAAR EEN CASELOAD. Een professionele voogd heeft geen
handvol wards; voor hem zijn tientallen open hulpvragen een gewone dinsdag. De
gebruiker die deze machinerie het hardst nodig heeft was precies degene voor wie
hij brak, en ik had hem als uitzondering weggeschreven.

Wat er misging: de queue kapte op 50. Een oudere vraag zat er niet in, de app
vond geen staat, en toonde hem -- terecht, want bij twijfel OPEN -- alsof er nog
iemand op moest. Een allang afgehandelde hulpvraag die weer om aandacht vraagt.

De regel bij-twijfel-open blijft; die is goed. Wat verandert is dat de twijfel
verdwijnt: OPEN vragen worden nooit afgekapt, dus mag een app concluderen dat wat
er niet in staat ook niet open is. De geschiedenis mag wel afgekapt -- die vraagt
niets, en staat nog gewoon op de server.

shaer:openComplete op de collectie zegt dat die gevolgtrekking is toegestaan.
Ontbreekt de vlag (een oudere server), dan valt de app terug op bij-twijfel-open,
en dat is de veilige kant.

Toets met 120 open vragen. Suite 720/720; met de afkap terug valt er een om.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/services/guardianship/queues.js

    r86e6a45 ra9ede28  
    191191// hetzelfde kind.
    192192
    193 /** De hulpvragen van deze guardian, met wie erop af is en of het dicht is. */
    194 export function helpItemsFor(slug, limit = 50) {
     193/**
     194 * De hulpvragen van deze guardian, met wie erop af is en of het dicht is.
     195 *
     196 * OPEN VRAGEN WORDEN NOOIT AFGEKAPT, en dat is geen ruimhartigheid maar de reden
     197 * dat de app iets mag CONCLUDEREN uit afwezigheid (Barts punt, 8-8).
     198 *
     199 * Dit stond op 50, en ik noemde 'tientallen hulpvragen bij een guardian' een
     200 * randgeval. Bart wees op de jeugdzorgmedewerker: die heeft geen handvol wards
     201 * maar een caseload, en voor hem is dat een gewone dinsdag. De gebruiker die dit
     202 * het hardst nodig heeft was precies degene voor wie het brak.
     203 *
     204 * Met een afkap op alles zag een app een oudere vraag niet in de queue, vond geen
     205 * staat, en toonde hem -- terecht, want bij twijfel OPEN -- als openstaand. Een
     206 * allang afgehandelde hulpvraag die weer om aandacht vraagt. Nu geldt: staat hij
     207 * niet in de queue, dan is hij NIET open. Die gevolgtrekking klopt alleen zolang
     208 * we open vragen volledig leveren.
     209 *
     210 * De geschiedenis mag wel afgekapt: die vraagt niets, en wat eraf valt is nog
     211 * steeds op de server te vinden.
     212 */
     213export function helpItemsFor(slug, historyLimit = 50) {
    195214  let rijen = [];
    196215  try {
    197216    rijen = db.prepare(
    198217      `SELECT object_uri, actor_uri, actor_name, actor_handle, actor_icon, content, published, created_at
    199        FROM ap_mentions WHERE slug = ? AND help_request = 1 ORDER BY created_at DESC LIMIT ?`,
    200     ).all(slug, limit);
     218       FROM ap_mentions WHERE slug = ? AND help_request = 1 ORDER BY created_at DESC`,
     219    ).all(slug);
    201220  } catch { return []; }
    202221  const staat = help.statusFor(rijen.map((r) => r.object_uri));
    203222  const mijn = new Set(relations.listWards(slug).map((w) => w.other_uri));
    204   return rijen.map((r) => ({
     223  const alles = rijen.map((r) => ({
    205224    ...r,
    206225    // Bij twijfel OPEN. Een hulpvraag die er afgehandeld uitziet terwijl hij dat
     
    211230    ),
    212231  }));
     232  const open = alles.filter((h) => h.state.open);
     233  const rest = alles.filter((h) => !h.state.open).slice(0, historyLimit);
     234  return [...open, ...rest];
    213235}
    214236
     
    231253    'shaer:formerWard': h.state.formerWard || undefined,
    232254  }));
    233   return collection(id, items);
    234 }
     255  const coll = collection(id, items);
     256  // Het teken dat de app mag concluderen uit afwezigheid: elke OPEN vraag zit
     257  // hierin. Ontbreekt deze vlag (een oudere server), dan valt de app terug op
     258  // bij-twijfel-open, en dat is de veilige kant.
     259  coll['shaer:openComplete'] = true;
     260  return coll;
     261}
  • test/activitypub-as2.test.js

    r86e6a45 ra9ede28  
    4343  // de feed en wisten niet of er al iemand op af was.
    4444  'shaer:queues', 'offers', 'follows', 'outgoingFollows', 'wards', 'guardians', 'help',
     45  // Elke OPEN hulpvraag zit in de collectie; daarom mag een app uit afwezigheid
     46  // concluderen dat iets niet open is (shaer-6wt).
     47  'shaer:openComplete',
    4548  // ActivityPub §4.1 `endpoints` vocabulary (same category as sharedInbox), used for C2S.
    4649  'oauthAuthorizationEndpoint', 'oauthTokenEndpoint', 'uploadMedia',
  • test/help-c2s.test.js

    r86e6a45 ra9ede28  
    8383  assert.notEqual(uit.status, 400);
    8484});
     85
     86test('OPEN vragen worden nooit afgekapt, hoeveel het er ook zijn', () => {
     87  // Barts punt (8-8): ik noemde tientallen hulpvragen bij een guardian een
     88  // randgeval, maar voor een jeugdzorgmedewerker is dat een caseload en dus een
     89  // gewone dinsdag. De gebruiker die dit het hardst nodig heeft was precies
     90  // degene voor wie het brak.
     91  //
     92  // Zonder deze regel viel een oudere vraag buiten de queue, vond de app geen
     93  // staat, en toonde hem -- terecht, want bij twijfel OPEN -- alsof er nog
     94  // iemand op moest.
     95  for (let i = 0; i < 120; i++) {
     96    db.prepare(`INSERT INTO ap_mentions (slug, object_uri, actor_uri, actor_handle, content, help_request)
     97                VALUES (?,?,?,?,?,1)`).run('oma', `https://elders.test/ap/notes/veel-${i}`, KIND, '@kind', '<p>help</p>');
     98  }
     99  const open = queues.helpItemsFor('oma').filter((h) => h.state.open);
     100  assert.equal(open.length, 120, 'alle 120 open vragen komen mee');
     101});
     102
     103test('de collectie zegt dat je uit afwezigheid mag concluderen', () => {
     104  // Zonder die vlag mag een app niets afleiden uit een ontbrekende staat, en
     105  // valt hij terug op bij-twijfel-open. Dat is de veilige kant, maar dan komt
     106  // een afgehandelde vraag terug in het zicht.
     107  const coll = queues.helpCollection('https://x/queues/help', 'oma');
     108  assert.equal(coll['shaer:openComplete'], true);
     109});
Note: See TracChangeset for help on using the changeset viewer.