source: Klonkt/src/services/guardianship/gatereq.js@ 2bfe26c

main
Last change on this file since 2bfe26c was 2bfe26c, checked in by roboburr <roboburr@…>, 5 weeks ago

Voorstellen vanuit de app, en een kind dat zelf kan vragen (shaer-8ru)

Barts opdracht: bouw shaer-8ru zodat de apps ook kunnen voorstellen, en maak
daarnaast het pad voor de ward om zelf een voorstel aan te zwengelen als hij
tegen een gated feature aanloopt.

DEEL 1 -- DE APPS KUNNEN VOORSTELLEN. De outbox kent nu een Offer van een
shaer:GatedSetting, precies de vorm die 5.6 al beschrijft en die de inbox al las.
De afweging zelf is verhuisd naar AP.proposeGate, waar de PWA-route nu ook
doorheen loopt. Twee implementaties naast elkaar zou een tweede weg naar
hetzelfde besluit zijn -- exact de fout die we vanmiddag bij de antwoordpoort
rechtzetten, toen de innamepoort alleen in C2S bleek te zitten.

DEEL 2 -- HET KIND KRIJGT WOORDEN. Tot nu toe liep alles over de guardians: zij
zien de catalogus, zij stellen voor, zij tellen. Het kind liep tegen een dichte
deur en kon niets. Nu stuurt het een shaer:gateRequest, en die landt bij zijn
guardians BIJ DE POORT waar hij over gaat -- niet in een aparte lijst die je
apart moet openen en dus vergeet.

EEN VRAAG IS GEEN STEM, en dat is de hele grens. Het verzoek is geen voorstel en
telt nergens mee; pas als een guardian het oppakt wordt het een voorstel dat
langs de gewone tally gaat. Anders opent een kind zijn eigen poort door hard
genoeg te vragen. Er staat een toets op die kijkt of er echt geen voorstel en
geen open poort uit ontstaat.

NIET DE REDDINGSBOEI. Een hulpvraag is een noodgeval en gaat door elke dichte
deur; dit is een wens. Ze door elkaar laten lopen zou de boei devalueren tot "het
kind wil iets", en dan kijkt er op een dag niemand meer op als hij afgaat.

GEEN VRIJE TEKST, en dat is geen gierigheid maar de reden dat het verzoek langs
de messages-poort MAG. Een kind met berichten dicht kan nog steeds om iets
vragen, zonder dat er een kanaal ontstaat om omheen die poort te praten. Wil het
uitleggen waarom, dan is dat een gesprek, en gesprekken hebben hun eigen poort.

Alleen van een eigen ward: een verzoek van een vreemde is geen vraag maar een
onbekende die iets over jouw instellingen wil zeggen.

Twaalf toetsen. Twee mutaties gecontroleerd (1 en 6 rood). Suite 712/712.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * Een kind dat zelf om een poort vraagt (shaer-8ru, Barts opdracht 8-8).
3 *
4 * Tot nu toe liep alles over de guardians: zij zien de catalogus, zij stellen
5 * voor, zij tellen. Het kind liep tegen een dichte deur en had geen woorden.
6 * Dit is die woorden -- niet meer dan dat.
7 *
8 * EEN VRAAG IS GEEN STEM, en dat is de hele grens. De ward stelt niet voor en
9 * stemt niet mee; het verzoek landt bij zijn guardians als iets om over te
10 * beslissen, en pas als EEN GUARDIAN het oppakt wordt het een voorstel dat
11 * langs de gewone tally gaat. Zou een verzoek zelf een voorstel zijn, dan kon
12 * een kind zijn eigen poort openen door hard genoeg te vragen.
13 *
14 * NIET DE REDDINGSBOEI, en dat verschil moet scherp blijven. Een hulpvraag is
15 * een noodgeval en gaat door elke dichte deur heen. Dit is een wens. Ze door
16 * elkaar laten lopen zou de boei devalueren tot "het kind wil iets", en dan
17 * kijkt er op een dag niemand meer op als hij afgaat.
18 *
19 * GEEN VRIJE TEKST. Een verzoek draagt alleen de naam van de feature. Dat is
20 * niet gierig maar precies de reden dat hij langs de messages-poort MAG: een
21 * kind met berichten dicht kan nog steeds om iets vragen, zonder dat daarmee
22 * een kanaal ontstaat om omheen die poort te praten. Wil het kind uitleggen
23 * waarom, dan is dat een gesprek, en gesprekken hebben hun eigen poort.
24 */
25
26import db from '../../config/database.js';
27
28let _s = null;
29function stmts() {
30 if (!_s) {
31 _s = {
32 ins: db.prepare(`INSERT OR IGNORE INTO ap_gate_requests (slug, ward_uri, feature, note_uri)
33 VALUES (?,?,?,?)`),
34 bySlug: db.prepare(`SELECT * FROM ap_gate_requests WHERE slug = ? AND handled_at IS NULL
35 ORDER BY created_at DESC`),
36 handle: db.prepare(`UPDATE ap_gate_requests SET handled_at = CURRENT_TIMESTAMP
37 WHERE slug = ? AND ward_uri = ? AND feature = ? AND handled_at IS NULL`),
38 };
39 }
40 return _s;
41}
42
43/** Leg vast dat dit kind om deze poort vroeg. Nooit dragend: een verzoek dat
44 * niet opgeslagen kan worden mag geen inkomend bericht laten stranden. */
45export function record(slug, wardUri, feature, noteUri = null) {
46 if (!slug || !wardUri || !feature) return;
47 try { stmts().ins.run(slug, wardUri, feature, noteUri); } catch { /* nooit dragend */ }
48}
49
50/** De openstaande verzoeken van de kinderen van deze guardian. */
51export function listOpen(slug) {
52 try { return stmts().bySlug.all(slug); } catch { return []; }
53}
54
55/**
56 * Afgehandeld: er is een voorstel van gemaakt, of een guardian legde hem weg.
57 *
58 * Verdwijnt niet uit de tabel. Er wordt niets herschreven, er wordt toegevoegd
59 * -- zelfde regel als bij de hulpvraag, en om dezelfde reden: wat een kind
60 * gevraagd heeft hoort terug te vinden te zijn, ook als het antwoord nee was.
61 */
62export function markHandled(slug, wardUri, feature) {
63 try { stmts().handle.run(slug, wardUri, feature); } catch { /* nooit dragend */ }
64}
65
66/**
67 * Hoeveel verzoeken er per feature openstaan voor dit kind, voor de
68 * waiting-kolom van het paneel. Zo staat de vraag bij de poort waar hij over
69 * gaat, en niet in een aparte lijst die je apart moet openen.
70 */
71export function waitingFor(slug, wardUri) {
72 const uit = {};
73 for (const r of listOpen(slug)) {
74 if (r.ward_uri !== wardUri) continue;
75 uit[r.feature] = (uit[r.feature] || 0) + 1;
76 }
77 return uit;
78}
79
80/** Het verzoek als bericht. Bewust dezelfde vorm als de zwaai en de
81 * hulpmarkering: een gewone directe note met een shaer:-markering, zodat hij
82 * over de bestaande bezorging reist en niet over een eigen kanaal. */
83export function requestNote({ id, me, feature, to }) {
84 return {
85 id, type: 'Note', attributedTo: me, to,
86 'shaer:gateRequest': feature,
87 // Vaste tekst, geen invoer van het kind: zie de kop over vrije tekst.
88 content: '<p>Mag dit aan?</p>',
89 };
90}
91
92/** Leest een binnengekomen note als poortverzoek, of null als hij er geen is. */
93export function parseRequest(object) {
94 if (!object || typeof object !== 'object') return null;
95 const f = object['shaer:gateRequest'] || object.gateRequest;
96 return (typeof f === 'string' && f) ? { feature: f } : null;
97}
98
99export default { record, listOpen, markHandled, waitingFor, requestNote, parseRequest };
Note: See TracBrowser for help on using the repository browser.