plan: intake to plan by a model; doors, labelled groups, the whole card

Work from another session, committed as found (tests green):

- `plan` reads an intake into a plan.yaml (a model decides needs,
  stages, forms and budgets; a person reads the result before build).
- Plans gain `doors` (a first question before the forms, when a front
  door would carry more than five needs), `groups` with labels that a
  select may draw its options from (`options_from: groups`), `private`
  fields kept off public pages, `multiple` selects, and `max_fields`
  as what the intake said the person will tolerate.
- `card.rs`: an alternative as the visitor meets it, in text, so the
  answering visitor and `rate` read the served card, not the heading.
- `rate` reads followup pages from the repo and reports "what happens
  next" as not measured rather than zero when it cannot.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
This commit is contained in:
Bendik Aagaard Lynghaug
2026-09-23 12:31:51 +02:00
co-authored by Claude Fable 5.1
parent baf36319b7
commit 255aeb4f4b
570 changed files with 40795 additions and 181 deletions
+28 -1
View File
@@ -1,6 +1,6 @@
# A contractor's whole operation, to stress the builder and the
# harness: 13 needs, 6 roles, 9 buckets, needs sharing a bucket,
# skippable stages, and a front door carrying more than a page should.
# skippable stages, and a front door that had to be tiered.
business: Nordvik Bygg
language: en
contact: { name: Ingrid Nordvik, email: ingrid@nordvikbygg.example }
@@ -12,9 +12,19 @@ about: >
each building site day to day, and one safety officer owns everything
reported from site.
# Six public needs is one over what a front door carries, so the
# public comes through three doors: a building of theirs, work with
# us, and a site of ours next to them (that one is a need on its own).
doors:
- id: your-building
who: an owner, a housing board or a past customer with a building
- id: work-with-us
who: a trade firm, a carpenter or an apprentice who wants work from us
needs:
# --- the public ---------------------------------------------------
- id: survey-enquiry
door: your-building
who: a housing board or private owner with a problem in a building
wants: someone qualified to come and look at it and say what it takes
lands_in: enquiries
@@ -26,6 +36,7 @@ needs:
# see what is coming their way.
moves_by: { surveyed: [project_managers, site_managers] }
watched_by: [site_managers]
max_fields: 4
collects:
- { name: name }
- { name: phone, type: tel }
@@ -34,6 +45,7 @@ needs:
- { name: access, optional: true }
- id: build-enquiry
door: your-building
who: an owner who already knows what they want built or changed
wants: drawings, a permit application and a price
lands_in: enquiries
@@ -45,6 +57,7 @@ needs:
# see what is coming their way.
moves_by: { surveyed: [project_managers, site_managers] }
watched_by: [site_managers]
max_fields: 5
collects:
- { name: name }
- { name: phone, type: tel }
@@ -53,6 +66,7 @@ needs:
- { name: timeframe, type: select, options: [This year, Next year, No fixed date] }
- id: warranty-claim
door: your-building
who: a past customer who has found a fault in work we handed over
wants: us to come back, look at it, and put it right
lands_in: claims
@@ -63,6 +77,7 @@ needs:
# The site manager inspects and puts it right; whether it is ours
# to fix is the project manager's call.
moves_by: { inspected: [site_managers], fixed: [site_managers] }
max_fields: 4
collects:
- { name: name }
- { name: phone, type: tel }
@@ -79,12 +94,14 @@ needs:
done_when: [answered]
success: [answered]
watched_by: [project_managers]
max_fields: 3
collects:
- { name: site_address }
- { name: what_is_wrong, type: textarea }
- { name: reach_me_on }
- id: subcontractor-application
door: work-with-us
who: a trade firm doing electrical, plumbing or scaffolding work
wants: to be approved once, and then be called when a job needs them
lands_in: subcontractors
@@ -94,6 +111,7 @@ needs:
success: [approved]
watched_by: [site_managers]
skippable: [awaiting_papers]
max_fields: 5
collects:
- { name: company }
- { name: registration_number }
@@ -103,6 +121,7 @@ needs:
- { name: trade_approval, optional: true }
- id: job-application
door: work-with-us
who: a carpenter, bricklayer or apprentice looking for work
wants: to be considered, without writing a letter
lands_in: applicants
@@ -110,6 +129,7 @@ needs:
stages: [open, interviewing, offered, hired, declined]
done_when: [hired, declined]
success: [hired]
max_fields: 3
collects:
- { name: name }
- { name: phone, type: tel }
@@ -130,6 +150,7 @@ needs:
# their own link, the site manager does the work.
moves_by: { approved: [submitter], declined: [submitter, project_managers], completed: [site_managers] }
watched_by: [site_managers]
max_fields: 3
collects:
- { name: email, type: email }
- { name: job_address }
@@ -150,6 +171,7 @@ needs:
# see what is coming their way.
moves_by: { surveyed: [project_managers, site_managers] }
watched_by: [site_managers]
max_fields: 4
collects:
- { name: caller }
- { name: phone, type: tel }
@@ -167,6 +189,7 @@ needs:
success: [awarded]
# This is how subcontractors see what there is to bid on.
watched_by: [subcontractors, site_managers]
max_fields: 4
collects:
- { name: site_address }
- { name: trade, type: select, options: [Electrical, Plumbing, Scaffolding, Sheet metal, Other] }
@@ -185,6 +208,7 @@ needs:
success: [accepted]
watched_by: [site_managers]
skippable: [shortlisted]
max_fields: 3
collects:
- { name: job }
- { name: price }
@@ -204,6 +228,7 @@ needs:
# safety officer closes it.
moves_by: { in_hand: [safety_officer, site_managers] }
watched_by: [project_managers]
max_fields: 3
collects:
- { name: kind, type: select, options: [Hazard, Near miss, Wrong materials, Other] }
- { name: where }
@@ -220,6 +245,7 @@ needs:
success: [delivered]
# The crew confirms it arrived.
moves_by: { delivered: [crew, site_managers] }
max_fields: 3
collects:
- { name: site_address }
- { name: what, type: textarea }
@@ -238,6 +264,7 @@ needs:
# safety officer closes it.
moves_by: { in_hand: [safety_officer, site_managers] }
watched_by: [project_managers]
max_fields: 3
collects:
- { name: kind, type: select, options: [Hazard, Near miss, Wrong materials, Other] }
- { name: where }
+6
View File
@@ -19,6 +19,7 @@ needs:
stages: [open, surveyed, quoted, won, lost]
done_when: [won, lost]
success: [won]
max_fields: 4
collects:
- { name: name }
- { name: phone, type: tel }
@@ -34,6 +35,7 @@ needs:
stages: [open, surveyed, quoted, won, lost]
done_when: [won, lost]
success: [won]
max_fields: 5
collects:
- { name: name }
- { name: phone, type: tel }
@@ -50,6 +52,7 @@ needs:
stages: [open, surveyed, quoted, won, lost]
done_when: [won, lost]
success: [won]
max_fields: 4
collects:
- { name: caller }
- { name: phone, type: tel }
@@ -65,6 +68,7 @@ needs:
done_when: [approved, declined]
success: [approved]
skippable: [awaiting_papers]
max_fields: 5
collects:
- { name: company }
- { name: registration_number }
@@ -81,6 +85,7 @@ needs:
stages: [open, interviewing, hired, declined]
done_when: [hired, declined]
success: [hired]
max_fields: 3
collects:
- { name: name }
- { name: phone, type: tel }
@@ -96,6 +101,7 @@ needs:
stages: [open, in_hand, closed]
done_when: [closed]
success: [closed]
max_fields: 3
collects:
- { name: kind, type: select, options: [Hazard, Near miss, Wrong materials, Other] }
- { name: where }
+112
View File
@@ -0,0 +1,112 @@
# Fotballgruppa i et idrettslag, på norsk: to dører på forsiden
# (foresatte, og de som vil bidra), roller som overlapper på én
# innmelding (treneren godkjenner, kassereren ser betalingen), og en
# intern melding fra trenerne til styret.
business: Lia IL Fotball
language: no
contact: { name: Kari Lien, email: kari@liail.example }
about: >
Fotballgruppa i et idrettslag på bygda. Rundt hundre og tjue unger
fra seks til seksten år, fordelt på lag etter årskull, drevet av
foreldre på fritida.
doors:
- id: foresatte
who: en forelder eller foresatt til et barn som vil spille, eller allerede spiller
- id: bidra
who: noen som vil hjelpe til i klubben, eller en bedrift som vil støtte den
needs:
- id: innmelding
who: en forelder som vil ha ungen med på et lag
wants: at barnet får plass på laget for sitt årskull
door: foresatte
lands_in: innmeldinger
handled_by: trenere
stages: [open, godkjent, betalt, trukket]
done_when: [betalt, trukket]
success: [betalt]
# Treneren godkjenner plassen, kassereren ser at det er betalt.
moves_by: { betalt: [kasserer] }
watched_by: [kasserer]
max_fields: 5
collects:
- { name: barnets_navn }
- { name: fodselsar, type: select, options: ["2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020"] }
- { name: foresatt }
- { name: telefon, type: tel }
- { name: epost, type: email }
- { name: spilt_for, optional: true }
- id: avgiftssak
who: en forelder som sliter med treningsavgiften
wants: å dele den opp, eller slippe den
door: foresatte
lands_in: avgiftssaker
handled_by: styret
stages: [open, vurdert, innvilget, avslatt]
done_when: [innvilget, avslatt]
success: [innvilget]
max_fields: 3
collects:
- { name: barnets_navn }
- { name: foresatt }
- { name: hva_gjelder_det, type: textarea }
- { name: telefon, type: tel, optional: true }
- id: frivillig
who: en som vil hjelpe til, som trener, lagleder, sjåfør eller på dugnad
wants: å bli brukt der det trengs
door: bidra
lands_in: frivillige
handled_by: styret
stages: [open, kontaktet, plassert, avslatt]
done_when: [plassert, avslatt]
success: [plassert]
max_fields: 3
collects:
- { name: navn }
- { name: telefon, type: tel }
- { name: hva_kan_du, type: select, options: [Trene et lag, Være lagleder, Kjøre til kamper, Dugnad, Annet] }
- id: sponsor
who: en bedrift i bygda som vil støtte klubben
wants: en prat om hva de kan bidra med, og en avtale
door: bidra
lands_in: sponsorer
handled_by: styret
stages: [open, i_dialog, avtalt, avslatt]
done_when: [avtalt, avslatt]
success: [avtalt]
max_fields: 3
collects:
- { name: bedrift }
- { name: kontaktperson }
- { name: telefon, type: tel }
- { name: hva_tenker_dere, type: textarea, optional: true }
- id: baneproblem
who: en trener som ser at noe på anlegget ikke er i orden
wants: at styret får vite det og ordner det
enters_as: trenere
lands_in: baneproblemer
handled_by: styret
stages: [open, tatt_tak_i, ordnet]
done_when: [ordnet]
success: [ordnet]
max_fields: 2
collects:
- { name: hvor }
- { name: hva, type: textarea }
# Holdt unna alle modeller som skriver ord.
personas:
- { id: ny-i-bygda, need: innmelding, text: "Vi flyttet hit i sommer og sønnen vår på ni har spilt fotball før. Hvordan får vi ham med på et lag her?" }
- { id: tvillinger, need: innmelding, text: "Jeg har tvillingjenter på sju som maser om å begynne. Er det plass, og hva koster det?" }
- { id: alenefar, need: avgiftssak, text: "Jeg er alene med tre unger og treningsavgiften for alle tre blir for mye på en gang. Går det an å dele den opp?" }
- { id: permittert, need: avgiftssak, text: "Jeg ble permittert i vinter. Kan dattera mi fortsette å spille selv om vi ikke klarer avgiften akkurat nå?" }
- { id: pensjonist, need: frivillig, text: "Jeg er pensjonert og spilte selv i mange år. Har dere bruk for en som kan ta de minste et par kvelder i uka?" }
- { id: stor-bil, need: frivillig, text: "Jeg kan ikke trene noen, men jeg har stor bil og kan kjøre til bortekamper." }
- { id: rorlegger, need: sponsor, text: "Jeg driver rørleggerfirma her i bygda og vil gjerne ha logoen vår på draktene til et lag. Hvem snakker jeg med?" }
- { id: kafeen, need: sponsor, text: "Vi har kafé i sentrum og kan bidra med noe til cupen i mai, kanskje vafler eller litt penger." }
- { id: lyset-slukker, need: baneproblem, text: "Lyset på kunstgresset slår seg av halv åtte og vi trener til åtte. Ungene løper i mørket." }
+94
View File
@@ -0,0 +1,94 @@
# A machine hire yard: two doors (hiring, and an account for firms),
# one aggregate walked by two roles (the counter reserves, the yard
# hands out and takes back), and the yard's own damage report.
business: Fjellstad Hire
language: en
contact: { name: Ola Fjellstad, email: ola@fjellstadhire.example }
about: >
Machine hire: mini diggers, lifts, compactors, generators. A counter,
a yard that delivers, collects and fixes, and an office.
doors:
- id: hiring
who: someone who needs a machine, or has one of ours that has stopped
- id: firms
who: a firm that hires often and wants an account with us
needs:
- id: hire-request
who: a private person or a firm who needs a machine for a while
wants: the right machine, from a date, for as long as they need it
door: hiring
lands_in: hires
handled_by: counter
stages: [open, reserved, out, returned, cancelled]
done_when: [returned, cancelled]
success: [returned]
# The counter reserves; the yard hands it out and takes it back.
moves_by: { out: [yard], returned: [yard] }
max_fields: 5
collects:
- { name: name }
- { name: phone, type: tel }
- { name: what, type: textarea }
- { name: from, type: date }
- { name: until, type: date }
- { name: deliver_to, optional: true }
- id: breakdown
who: someone whose hired machine has stopped working
wants: it running again, or swapped, today
door: hiring
lands_in: breakdowns
handled_by: yard
stages: [open, in_hand, resolved]
done_when: [resolved]
success: [resolved]
max_fields: 3
collects:
- { name: phone, type: tel }
- { name: machine }
- { name: what_happened, type: textarea }
- { name: where, optional: true }
- id: account-request
who: a firm that hires often
wants: to send anyone to collect, and get one invoice a month
door: firms
lands_in: accounts
handled_by: office
stages: [open, checked, approved, declined]
done_when: [approved, declined]
success: [approved]
max_fields: 4
collects:
- { name: company }
- { name: registration_number }
- { name: contact }
- { name: phone, type: tel }
- { name: invoice_email, type: email, optional: true }
- id: damage-on-return
who: someone in the yard who finds damage when a machine comes back
wants: it written down before the customer has left
enters_as: yard
lands_in: damage_reports
handled_by: office
stages: [open, invoiced, written_off]
done_when: [invoiced, written_off]
success: [invoiced]
max_fields: 3
collects:
- { name: machine }
- { name: hire_or_customer }
- { name: damage, type: textarea }
# Held out from every model that writes words.
personas:
- { id: garden-wall, need: hire-request, text: "I'm building a stone wall in the garden and need a small digger for a weekend. I've never driven one." }
- { id: roofer-lift, need: hire-request, text: "We're a roofing crew and need a scissor lift on site in Dalen from Monday for about two weeks." }
- { id: stuck-compactor, need: breakdown, text: "The plate compactor I picked up this morning won't start. I've got a crew standing around." }
- { id: lift-error, need: breakdown, text: "The lift you delivered keeps showing an error and stops halfway up. It's on our site at the school." }
- { id: landscaper-account, need: account-request, text: "We're a landscaping firm hiring from you almost every month and I'm tired of paying by card each time. Can we get invoiced monthly?" }
- { id: builder-account, need: account-request, text: "Small building firm, six people. We'd like to be able to send whoever is nearest to pick things up and have it on our account." }
- { id: yard-window, need: damage-on-return, text: "The mini digger from the Berg job came back with a smashed rear window and hydraulic oil everywhere." }
+113
View File
@@ -0,0 +1,113 @@
# A physiotherapy clinic: two doors on the front, patients and the
# people who send them; the reception handles everything, therapists
# write the report back and notice who did not turn up.
business: Bakken Fysioterapi
language: en
contact: { name: Marit Bakken, email: marit@bakkenfysio.example }
about: >
Six physiotherapists and a receptionist. People come with pain,
injuries and after operations, on their own or sent by a doctor,
and we treat them over a course of sessions.
doors:
- id: patients
who: someone with pain or an injury, or a patient who already has a time here
- id: referrers
who: a doctor, a hospital ward or an insurer sending someone to us
needs:
- id: new-patient
who: someone with something that hurts
wants: a first appointment with a therapist who suits them
door: patients
lands_in: requests
handled_by: reception
stages: [open, offered, booked, declined]
done_when: [booked, declined]
success: [booked]
max_fields: 4
collects:
- { name: name }
- { name: phone, type: tel }
- { name: what_hurts, type: textarea }
- { name: when, type: select, options: [Mornings, Afternoons, Any time] }
- { name: sent_by_doctor, type: select, options: ["Yes", "No"], optional: true }
- id: move-or-cancel
who: a patient who already has a time and cannot come
wants: the time moved, or the slot freed
door: patients
lands_in: cancellations
handled_by: reception
stages: [open, rebooked, released]
done_when: [rebooked, released]
success: [rebooked]
max_fields: 3
collects:
- { name: name }
- { name: phone, type: tel }
- { name: appointment_day, type: date }
- { name: new_time_wish, optional: true }
- id: referral
who: a GP or a hospital ward sending a patient
wants: the patient seen, and a report back when the course ends
door: referrers
lands_in: referrals
handled_by: reception
stages: [open, accepted, booked, reported, returned]
done_when: [reported, returned]
success: [reported]
# The therapist who treated them writes the report; they see the
# referral from the start.
moves_by: { reported: [therapists] }
watched_by: [therapists]
max_fields: 5
collects:
- { name: patient_name }
- { name: patient_phone, type: tel }
- { name: referrer }
- { name: what_for, type: textarea }
- { name: urgency, type: select, options: [This week, Within a month, Routine] }
- id: insurance-approval
who: the receptionist, before a course that an insurer has to approve
wants: the request sent and its answer kept where the patient's case is
enters_as: reception
lands_in: approvals
handled_by: reception
stages: [open, sent, approved, refused]
done_when: [approved, refused]
success: [approved]
max_fields: 3
collects:
- { name: patient_name }
- { name: insurer }
- { name: sessions }
- { name: case_number, optional: true }
- id: no-show
who: a therapist whose patient did not turn up and did not call
wants: the reception to ring them and get them back in
enters_as: therapists
lands_in: no_shows
handled_by: reception
stages: [open, contacted, rebooked, closed]
done_when: [rebooked, closed]
success: [rebooked]
max_fields: 2
collects:
- { name: patient_name }
- { name: appointment_day, type: date }
- { name: note, optional: true }
# Held out from every model that writes words.
personas:
- { id: runner-knee, need: new-patient, text: "I've been running for years and the outside of my right knee has started hurting after about five kilometres. I'd like someone to have a look, preferably in the mornings." }
- { id: post-surgery-mother, need: new-patient, text: "My mother had a hip replacement three weeks ago and the hospital said she needs training. She can't do much on her own and I'll drive her." }
- { id: sick-child, need: move-or-cancel, text: "I have a session on Thursday at ten but my daughter has a fever and I can't come. Can I move it?" }
- { id: sent-abroad, need: move-or-cancel, text: "Work is sending me abroad next week so my appointment on the 3rd is off. Just free the slot, I'll be in touch when I'm back." }
- { id: gp-shoulder, need: referral, text: "I'm a GP. A patient of mine has a frozen shoulder that isn't improving with what I can offer. I'd like her to start with you and hear how it goes." }
- { id: hospital-discharge, need: referral, text: "Orthopaedic ward here. We're discharging a man after an ankle fracture on Friday and need follow-up rehab arranged near where he lives. He'll need a report for his sick leave." }
- { id: reception-approval, need: insurance-approval, text: "The patient in room two has a policy that covers twelve sessions if the insurer signs off first. I need to send that off and keep track of the answer." }
- { id: therapist-no-show, need: no-show, text: "My two o'clock didn't turn up and didn't call. Second time. Someone needs to ring him." }
+243
View File
@@ -0,0 +1,243 @@
# Tomter Vel, en velforening: fire dører på forsiden (medlemskap,
# melde fra, bidra, naboer imellom) og høringsinnspill rett på
# forsiden, siden den som har en mening om en sak ikke ser seg selv
# som frivillig. Komiteene er gruppene: en søknad om plass i en
# komité velger blant de samme sju som har hver sin pult. Trafikk,
# anlegg og oppslagstavla kan alle lese; kontaktopplysninger vises
# ikke der. Nabohjelp begge veier, og oppslagstavla for deling av
# utstyr holdes lite: én melding, styret legger den ut og tar den ned.
business: Tomter Vel
language: no
contact: { name: Styret i Tomter Vel, email: post@tomtervel.no }
about: >
Velforeningen for Tomter, stiftet i 1947. Sju komiteer drevet på
fritida: arrangementer, elvestien, lekeplassene, høringssvar,
miljøgata, pendlerforhold og trafikk. 157 husstander er medlemmer.
# Komiteene, som gruppene heter, med navnet folk kjenner dem under.
groups:
- { id: arrangementer, label: Arrangementer }
- { id: elvesti, label: Elvesti }
- { id: horingsinstans, label: Høringsinstans }
- { id: lekeplasser, label: Leke- og møteplasser }
- { id: miljogate, label: Miljøgate }
- { id: pendlerforhold, label: Pendlerforhold }
- { id: trafikk, label: Trafikkforhold }
doors:
- id: medlem
who: en husstand i Tomter som vil bli medlem, betale kontingent, eller melde flytting, ny e-post eller utmelding
- id: melde-fra
who: noen som har sett noe farlig i trafikken, eller noe ødelagt på lekeplassen eller stien
- id: bidra
who: noen som vil stille opp på 17. mai, dugnad eller et arrangement, eller sitte i en komité
- id: naboer
who: en nabo som trenger en hånd med snømåking, handling eller skyss, kan gi en, eller har noe å låne ut
needs:
- id: bli-medlem
who: en husstand i Tomter
wants: å bli medlem og få betalt kontingenten
door: medlem
lands_in: husstander
handled_by: kasserer
stages: [open, betalt, utmeldt]
done_when: [betalt, utmeldt]
success: [betalt]
max_fields: 3
collects:
- { name: navn }
- { name: adresse }
- { name: epost, type: email }
- { name: telefon, type: tel, optional: true }
- id: endre-medlemskap
who: et medlem som har flyttet, byttet e-post eller vil melde seg ut
wants: at velet har riktige opplysninger om dem
door: medlem
lands_in: medlemsendringer
handled_by: kasserer
stages: [open, oppdatert]
done_when: [oppdatert]
success: [oppdatert]
max_fields: 3
collects:
- { name: navn }
- { name: adresse }
- { name: hva_er_nytt, type: textarea }
- id: trafikkfare
who: en som har sett et farlig sted i trafikken
wants: at velet tar det opp med kommunen eller den som eier veien
door: melde-fra
lands_in: trafikkmeldinger
handled_by: trafikk
stages: [open, tatt_opp, ordnet, avvist]
done_when: [ordnet, avvist]
success: [ordnet]
# Alle kan se hva som er meldt og hvor det står; e-posten vises ikke.
watched_by: [styret, public]
max_fields: 2
collects:
- { name: hvor }
- { name: hva, type: textarea }
- { name: epost, type: email, optional: true }
- id: anleggsfeil
who: en som ser at noe på lekeplassen eller stien er ødelagt
wants: at det blir fikset før noen skader seg
door: melde-fra
lands_in: anleggsfeil
handled_by: lekeplasser
stages: [open, tatt_tak_i, utbedret]
done_when: [utbedret]
success: [utbedret]
watched_by: [public]
max_fields: 2
collects:
- { name: hvor, type: select, options: [Lekeplassen, Elvestien, Skøytebanen, Et annet sted] }
- { name: hva, type: textarea }
# Rett på forsiden: den som har en mening om en sak er ikke frivillig.
- id: horingsinnspill
who: en beboer som har en mening om en sak kommunen har på høring
wants: at velet tar det med i sitt svar
lands_in: innspill
handled_by: horingsinstans
watched_by: [styret]
stages: [open, tatt_med, ikke_tatt_med]
done_when: [tatt_med, ikke_tatt_med]
success: [tatt_med]
max_fields: 3
collects:
- { name: navn }
- { name: sak }
- { name: innspill, type: textarea }
- id: hjelpe-til
who: en som vil hjelpe til på et arrangement eller en dugnad
wants: å bli satt opp på noe som passer dem
door: bidra
lands_in: frivillige
handled_by: arrangementer
stages: [open, kontaktet, satt_opp, takket_nei]
done_when: [satt_opp, takket_nei]
success: [satt_opp]
max_fields: 3
collects:
- { name: navn }
- { name: telefon, type: tel }
- { name: hva, type: select, multiple: true, options: [17. mai, Juletregranstenning, Skøytedag, Dugnad på elvestien, Det som trengs] }
- id: komite
who: en som vil sitte i en komité
wants: en plass i den komiteen som driver med det de bryr seg om
door: bidra
lands_in: komitesoknader
handled_by: styret
stages: [open, plassert, avslatt]
done_when: [plassert, avslatt]
success: [plassert]
max_fields: 3
collects:
- { name: navn }
- { name: epost, type: email }
- { name: komite, type: select, multiple: true, options_from: groups }
# Nabohjelp: den som trenger en hånd, og den som kan gi en. En
# nabohjelpsgruppe kobler dem; den som fikk hjelp sier fra selv at
# det er ordnet.
- id: trenger-hjelp
who: en beboer som ikke får til noe selv for tiden, som snømåking, handling eller en skyss
wants: at en nabo stiller opp
door: naboer
lands_in: hjelpebehov
handled_by: nabohjelp
stages: [open, formidlet, ordnet, ikke_lost]
done_when: [ordnet, ikke_lost]
success: [ordnet]
moves_by: { ordnet: [submitter, nabohjelp] }
max_fields: 4
collects:
- { name: navn }
- { name: email, type: email }
- { name: adresse }
- { name: hva, type: textarea }
- { name: telefon, type: tel, optional: true }
- id: kan-hjelpe
who: en nabo som kan stille opp når noen trenger det
wants: å bli spurt når det passer
door: naboer
lands_in: hjelpere
handled_by: nabohjelp
stages: [open, registrert, trukket]
done_when: [registrert, trukket]
success: [registrert]
moves_by: { trukket: [submitter, nabohjelp] }
max_fields: 4
collects:
- { name: navn }
- { name: email, type: email }
- { name: telefon, type: tel }
- { name: kan, type: select, multiple: true, options: [Snømåking, Handling, Kjøring, Småfiks i huset, En prat og litt selskap, Det som trengs] }
# Oppslagstavla, holdt lite: én melding.
- id: dele-utstyr
who: en nabo som har noe å låne ut, eller trenger å låne noe
wants: et oppslag som naboene ser
door: naboer
lands_in: oppslag
handled_by: styret
stages: [open, lagt_ut, tatt_ned]
done_when: [lagt_ut, tatt_ned]
success: [lagt_ut]
# Den som la det ut kan ta det ned selv. Tavla er offentlig: det er
# den naboene leser; navn og e-post vises ikke der.
moves_by: { tatt_ned: [submitter, styret] }
watched_by: [public]
max_fields: 4
collects:
- { name: navn, private: true }
- { name: email, type: email }
- { name: har_eller_trenger, type: select, options: [Jeg har noe å låne ut, Jeg trenger å låne noe] }
- { name: hva, type: textarea }
- id: utlegg
who: en i en komité som har lagt ut for noe
wants: pengene tilbake
enters_as: komiteer
lands_in: utlegg
handled_by: kasserer
stages: [open, godkjent, utbetalt, avvist]
done_when: [utbetalt, avvist]
success: [utbetalt]
max_fields: 3
collects:
- { name: navn }
- { name: belop }
- { name: hva, type: textarea }
# Holdt unna alle modeller som skriver ord.
personas:
- { id: nyinnflyttet, need: bli-medlem, text: "Vi flyttet til Tomter i mars og har hørt at det finnes et vel. Hvordan blir vi med, og hva koster det?" }
- { id: glemte-a-betale, need: bli-medlem, text: "Jeg har vært medlem før men fikk ikke betalt i fjor. Kan jeg bare vippse, og til hvem?" }
- { id: ny-epost, need: endre-medlemskap, text: "Vi har byttet e-postadresse og får ikke lenger noe fra dere." }
- { id: flytter, need: endre-medlemskap, text: "Vi selger huset og flytter til Ski i august, så vi må ut av medlemslista." }
- { id: skolevei, need: trafikkfare, text: "Bilene kjører altfor fort i svingen ved skolen om morgenen, og det er ikke fortau der ungene går." }
- { id: busslomme, need: trafikkfare, text: "Det er umulig å se om det kommer noen når man skal ut fra busslomma ved butikken, hekken har blitt kjempehøy." }
- { id: huske, need: anleggsfeil, text: "Huska på lekeplassen henger i én kjetting. Sønnen min dro i den i går og den holdt så vidt." }
- { id: bru, need: anleggsfeil, text: "Planken på den lille brua på stien langs elva er råtten, jeg gikk nesten gjennom." }
- { id: blokker, need: horingsinnspill, text: "Kommunen skal bygge blokker på jordet bak stasjonen, og jeg synes det er alt for høyt. Kan velet si ifra?" }
- { id: togtider, need: horingsinnspill, text: "Ruter vil kutte det tidlige toget. Jeg pendler til Oslo hver dag og vil at velet skriver til dem om det." }
- { id: vafler, need: hjelpe-til, text: "Jeg kan steke vafler på 17. mai-frokosten hvis dere trenger folk." }
- { id: motorsag, need: hjelpe-til, text: "Har motorsag og ledig helg, kan ta trær langs elvestien hvis det er en dugnad." }
- { id: pendler, need: komite, text: "Jeg pendler og er lei av at ingen snakker med Ruter. Jeg vil gjerne være med i gjengen som jobber med det." }
- { id: planlegger, need: komite, text: "Jeg er arealplanlegger av yrke og kunne bidratt når kommunen sender saker på høring." }
- { id: tilhenger, need: dele-utstyr, text: "Jeg har en tilhenger som står ubrukt mesteparten av året, naboer kan gjerne låne den for en hundrelapp." }
- { id: stige, need: dele-utstyr, text: "Trenger en lang stige en dag i helga for å rense takrenna, er det noen i nærheten som har?" }
- { id: snomaking, need: trenger-hjelp, text: "Jeg er 84 og klarer ikke å måke innkjørselen lenger. Er det noen som kan hjelpe meg når det snør?" }
- { id: nyoperert, need: trenger-hjelp, text: "Jeg er nyoperert i hofta og kommer meg ikke til butikken på noen uker. Kunne noen handlet for meg?" }
- { id: hjemmekontor, need: kan-hjelpe, text: "Jeg jobber hjemmefra og kan godt måke eller handle for noen som ikke får det til selv." }
- { id: pensjonert-elektriker, need: kan-hjelpe, text: "Pensjonert elektriker, har bil og god tid. Si fra om noen trenger skyss eller en hånd med småting." }
- { id: kvittering, need: utlegg, text: "Jeg kjøpte pølser og kakao til skøytedagen for 1 840 kroner, her er kvitteringa, vil ha det igjen." }