source: Klonkt/src/services/guardianship/queues.js@ 1a2d8ac

main
Last change on this file since 1a2d8ac was 1a2d8ac, checked in by Robin Genis <roboburr@…>, 7 weeks ago

Offers-queue draagt de daemon-hulpvelden (accept-knop in de apps)

De Shaer-clients renderen hun accepteer-knop uit de shaer:-hulpvelden die
de test-daemon op elk offer-item zet (shaer:ward, candidate, needsMyAccept,
iAmCandidate, ...). Klonkt's offers-queue gaf een kale AS2-Offer, waardoor
de parser lege velden zag en de knop nooit verscheen. Nu draagt elk item
beide vormen: de AS2 Relationship én de hulpvelden. Klonkts flow is
één-fase (de Accept van de ward maakt het meteen echt), dus needsMyAccept
geldt de ward-kant en readyToCommit blijft false.

Changed files:
src/services/guardianship/queues.js

  • offersCollection: shaer:ward/candidate/existingGuardians/acceptedBy/ needsMyAccept/readyToCommit/iAmCandidate per item

test/guardianship.test.js

  • pint de hulpvelden op de kid-queue

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

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/**
2 * Guardianship (FEP-633c) — the owner-only dashboard queues.
3 *
4 * Three OrderedCollections on the actor (shaer:queues), same contract as the
5 * Shaer test daemon so the iOS/Android guardian dashboards read them as-is:
6 * - offers: pending guardianship offers where I am a party (§3)
7 * - follows: pending follows for my wards (§5.3) — Klonkt has no gated
8 * follows yet, so this collection is empty for now
9 * - wards: my wards, for the dashboard's wards list
10 */
11import { GUARDIAN_RELATIONSHIP_COMPACT } from './context.js';
12import * as relations from './relations.js';
13
14const collection = (id, items) => ({
15 id, type: 'OrderedCollection', totalItems: items.length, orderedItems: items,
16});
17
18/** Pending offers, reconstructed as Offer activities (either side). Each item
19 * also carries the daemon-contract helper fields (shaer:ward, candidate,
20 * needsMyAccept, iAmCandidate, …): the Shaer clients render their accept
21 * button from those, so the shapes must match the test daemon exactly. */
22export function offersCollection(id, slug, me) {
23 const items = relations.listOffers(slug).map((r) => {
24 const ward = r.role === 'guardian' ? r.other_uri : me;
25 const candidate = r.role === 'guardian' ? me : r.other_uri;
26 return {
27 id: r.offer_id || `${me}/offers/pending-${r.id}`,
28 type: 'Offer',
29 actor: candidate,
30 object: {
31 type: 'Relationship',
32 subject: ward,
33 relationship: GUARDIAN_RELATIONSHIP_COMPACT,
34 object: candidate,
35 },
36 'shaer:ward': ward,
37 'shaer:candidate': candidate,
38 'shaer:existingGuardians': relations.listGuardians(slug).map((g) => g.other_uri),
39 'shaer:acceptedBy': [],
40 // Klonkt's flow is single-phase: the ward's Accept commits at once, so
41 // only the ward-side owner has an action here.
42 'shaer:needsMyAccept': r.role === 'ward',
43 'shaer:readyToCommit': false,
44 'shaer:iAmCandidate': r.role === 'guardian',
45 'shaer:handle': r.other_handle || undefined,
46 published: r.created_at,
47 };
48 });
49 return collection(id, items);
50}
51
52/** Gated follows awaiting guardian approval — not built in Klonkt yet. */
53export function followsCollection(id) {
54 return collection(id, []);
55}
56
57/** The guardian's wards (accepted), with cached handle for display. */
58export function wardsCollection(id, slug) {
59 const items = relations.listWards(slug)
60 .filter((r) => r.status === 'accepted')
61 .map((r) => ({ id: r.other_uri, 'shaer:handle': r.other_handle || undefined, since: r.created_at }));
62 return collection(id, items);
63}
64
65export default { offersCollection, followsCollection, wardsCollection };
Note: See TracBrowser for help on using the repository browser.