Bring the trainer in (uhhm/portal-trainer main, history kept)
git-subtree-dir: vendor/trainer git-subtree-mainline:c7c2956e15git-subtree-split:a2a9f4edcf
This commit is contained in:
+44
@@ -0,0 +1,44 @@
|
||||
name: Test
|
||||
|
||||
# Every push: the tests, then every plan under plans/ built and linted
|
||||
# with the iris release the live sites run, and the onboarding site
|
||||
# linted too. A plan that stops building, or a builder change that
|
||||
# renders a site the lint rejects, fails here and nowhere later.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: bare
|
||||
env:
|
||||
# The bare runner's shared toolchain and caches (see uhhm/portal).
|
||||
CARGO_HOME: /var/local/cargo
|
||||
RUSTUP_HOME: /var/local/rustup
|
||||
PATH: /var/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/bin
|
||||
SCCACHE_DIR: /var/local/sccache
|
||||
SCCACHE_SERVER_PORT: "4228"
|
||||
CARGO_TARGET_DIR: /var/local/cargo-target
|
||||
# The lint, pinned to the portal release the sites run.
|
||||
IRIS_RELEASE: v0.3.47
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Test
|
||||
run: cargo test --release
|
||||
|
||||
- name: Build and lint every plan
|
||||
run: |
|
||||
set -euo pipefail
|
||||
bin="$CARGO_TARGET_DIR/iris-$IRIS_RELEASE"
|
||||
[ -x "$bin" ] || { curl -sfL "${{ github.server_url }}/uhhm/iris/releases/download/$IRIS_RELEASE/iris" -o "$bin" && chmod +x "$bin"; }
|
||||
cargo build --release
|
||||
for plan in plans/*.yaml; do
|
||||
name=$(basename "$plan" .yaml)
|
||||
echo "== $plan"
|
||||
"$CARGO_TARGET_DIR/release/portal-trainer" build --plan "$plan" --out "/tmp/ci-$name" --lint "$bin"
|
||||
done
|
||||
echo "== portal-portal"
|
||||
"$bin" check --path portal-portal/questions
|
||||
@@ -0,0 +1,2 @@
|
||||
target/
|
||||
out/
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||
|
||||
[[package]]
|
||||
name = "portal-trainer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.229"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.151"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.34+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "3.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "portal-trainer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Generates a portal content repo from a business intake, held to portal's question_lint"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
# preserve_order: a page is read by the people who own it, so the keys
|
||||
# come out in the order they were written (name, then description, then
|
||||
# the rest), not sorted with `name` at the bottom.
|
||||
serde_json = { version = "1", features = ["preserve_order"] }
|
||||
serde_yaml = "0.9"
|
||||
Vendored
+485
@@ -0,0 +1,485 @@
|
||||
# portal-trainer
|
||||
|
||||
A business describes itself in plain words: what it does, who comes to
|
||||
it, what it keeps track of and through which stages, and who handles
|
||||
what. `portal-trainer` turns that into a working
|
||||
[portal](https://project.uhhm.no/uhhm/portal) content repo: a question
|
||||
series for every role, the state machines behind them, and a desk per
|
||||
handling role. No software is written for the business; the only thing
|
||||
produced is content, and every line of it is held to a verifier.
|
||||
|
||||
## Build: structure from the plan, words from the model
|
||||
|
||||
```
|
||||
portal-trainer build --plan plans/contractor.yaml --out out/nordvik \
|
||||
--lint iris --llm "MODEL=sonnet engines/claude.sh"
|
||||
```
|
||||
|
||||
A `plan.yaml` is a needs spec that also says what each form collects
|
||||
and, per need, `max_fields`: how many required fields that person
|
||||
will tolerate, taken from what the business said about them, never
|
||||
from the form. `build` refuses a form over its budget, and hands the
|
||||
budget to the verifier, so the check still means something after
|
||||
handover. Everything structural is derived from the plan with no
|
||||
model involved: the state machines (read off `stages`: walk the line,
|
||||
be turned down at any point, succeed only from the end, pass over
|
||||
`skippable` stages), the front door, a followup page per need, a gated
|
||||
directory per group with its desk and the pages only that group may
|
||||
open, and every button the machine allows. The verifier accepts the
|
||||
result by construction; what it still checks is the budget.
|
||||
|
||||
The model writes words only, one page at a time, into a JSON object
|
||||
whose shape is fixed. Its strings are merged over built-in fallbacks
|
||||
key by key, so a bad reply costs wording, never a working site. `--llm-for <path prefix>` points the model at some pages only
|
||||
(`aggregates.yaml` for the mails alone); a reply in the wrong language
|
||||
for the plan is refused, and a mail that lost the submitter's link
|
||||
gets it back.
|
||||
|
||||
### Onboarding from the plan
|
||||
|
||||
`invites_by: [styret]` on a plan, or `invited_by: [...]` on a group,
|
||||
puts an invite form on the inviting group's desk for each group it may
|
||||
fill, and a list of the invites sent. Portal does the rest (an account
|
||||
in Kanidm, the group, a one-time credential link) through `invite:` on
|
||||
the alternative. Every group with a desk invites into itself by
|
||||
default.
|
||||
|
||||
### Rebuilding a live site
|
||||
|
||||
`--words-from <repo>` lifts the words a repo already has back into the
|
||||
words map by what each card is (its bucket, the page it leads to, the
|
||||
group it invites into), across the whole repo, so a rebuild keeps
|
||||
hand-edited wording even when a card moves page (a door taken away, a
|
||||
need brought onto the front door) and
|
||||
adds only the new slots. Cards are matched by what they are (the
|
||||
bucket they record into, the page they lead to, a field's name, the
|
||||
group they invite into), not by position, so a rebuild that reorders
|
||||
or reshapes a page still hands each card its own words; on uhhm.no
|
||||
the live front door's three headings follow their buckets onto the
|
||||
new page. `--words
|
||||
<json>` overrides slots by page and may repeat, each file layered over
|
||||
the last (the words a build used, then a round of hand changes);
|
||||
`words.json` in the output is the words as used. See
|
||||
`runs/tomtervel-invites-2026-09-23` and `runs/uhhm-2026-09-23`.
|
||||
|
||||
| Same contractor, same local model (nemotron 30B-A3B on ergo) | Free-form `generate` | `build` |
|
||||
|---|---|---|
|
||||
| A site the verifier accepts | never, in 6 rounds and 16 min | first try, 130 s |
|
||||
| Held-out personas, with descriptions | - | 8 of 8 |
|
||||
| Held-out personas, headings only | - | 7 of 8 |
|
||||
|
||||
The wording numbers are from the re-score of 2026-09-22, one task per
|
||||
call (`runs/contractor-build-2026-09-21/rescore-2026-09-22/`). The
|
||||
first score, all tasks in one prompt, said 8 of 8 on headings only;
|
||||
the apprentice picking the building survey over "Join our carpentry
|
||||
team" only showed once no other visitor was in the prompt.
|
||||
|
||||
For comparison, a Sonnet-class model writing everything free-form
|
||||
scored 8 of 10 on headings only and silently dropped a stage the owner
|
||||
had described. `build` cannot drop a stage: it never decides one. The
|
||||
denominators differ: the `build` site gives the two crew personas a
|
||||
one-option page, so they generate no task, and 8 of 8 is eight public
|
||||
personas where the `generate` number is ten. Held out means held out
|
||||
from the model: the plan's `who` and `wants` lines and the personas
|
||||
were written by the same person about the same needs, and the fallback
|
||||
heading is the need's `wants`, so the two are cousins.
|
||||
|
||||
### The front door opens modestly
|
||||
|
||||
A front door with more buttons than text leaves a visitor paralysed.
|
||||
So the built front door opens with what the business does, in one or
|
||||
two features and no button at all (`does:` on the plan, at most two,
|
||||
each `for:` a need so it speaks to one role and is headed by what
|
||||
that role gets); then a look-around card, things a visitor may
|
||||
inspect before asking for anything (`shows:`, each a portal resource
|
||||
block passed through verbatim, plus every public view the plan
|
||||
opens); and only then the offers, as more alternatives on the same
|
||||
page. Nothing is layered: doors still exist for a plan that wants
|
||||
them, but a second tier is what this shape is there to avoid, and on
|
||||
uhhm.no a flat front door with an opener routed better than the
|
||||
doored one.
|
||||
|
||||
The house and its players: a role the opener invites in has to see
|
||||
its win, and the machine has to give it something to do after it
|
||||
sits down. `build` warns when a featured need gives the submitter
|
||||
neither a move (`moves_by: {<stage>: [submitter, ...]}`) nor a public
|
||||
view; a player with no move is a spectator.
|
||||
### Doors: a first question before the forms
|
||||
|
||||
Five or six needs on one page is more than a visitor sorts through
|
||||
(the full contractor plan had six). A plan can put public needs
|
||||
behind `doors`: each door is one alternative on the front door
|
||||
leading to a page of its own, where the needs that name it sit.
|
||||
|
||||
```yaml
|
||||
doors:
|
||||
- id: patients
|
||||
who: someone with pain or an injury, or a patient who already has a time here
|
||||
needs:
|
||||
- id: new-patient
|
||||
door: patients
|
||||
...
|
||||
```
|
||||
|
||||
The door's page is a nav page, public, holding the forms. The spec
|
||||
gives such a need `max_steps: 2` and pins `via` to the door's heading,
|
||||
so the verifier walks both pages. A door nobody is behind, a door on
|
||||
an internal need, or a door named like a group is refused, and a
|
||||
front door over five alternatives is warned about. The visitor is
|
||||
scored on both pages: a persona who picks the wrong door is a
|
||||
misroute on `/`, one who picks the wrong form is a misroute on the
|
||||
door's page.
|
||||
|
||||
Cases with doors: `plans/physio.yaml` (a physiotherapy clinic,
|
||||
patients and referrers), `plans/fotballklubb.yaml` (a football club,
|
||||
in Norwegian, parents and helpers), `plans/hire.yaml` (a machine hire
|
||||
yard, hiring and firms), and `plans/contractor-full.yaml` (three
|
||||
doors over six public needs). Each has an intake under `intakes/` in
|
||||
the business's own words and held-out personas.
|
||||
|
||||
### What a plan can say about a form and its readers
|
||||
|
||||
- `multiple: true` on a `select`: pick any number (portal renders
|
||||
toggles). What a volunteer can do, which events, which committees.
|
||||
- `groups:` at the top, a list of `{ id, label }`: the groups with a
|
||||
name the public knows, such as a vel's committees. A select with
|
||||
`options_from: groups` offers exactly those labels, so the
|
||||
application form and the desks cannot drift apart.
|
||||
- `watched_by: [public]`: an ungated read-only page of the bucket at
|
||||
`/status/<bucket>`, linked from the followup page. Everyone sees
|
||||
what was sent in and where it stands. `email` and `tel` fields, and
|
||||
any field marked `private: true`, are projected away before it is
|
||||
shown.
|
||||
- `events: { open: applied, active: onboarded }` on a need: the event
|
||||
name a stage is entered by, where the builder's default (the stage's
|
||||
own name, `received` for the first) is not what a live site already
|
||||
has. Portal replays every record by event name, so a rebuild of a
|
||||
site that holds records keeps the names its aggregates.yaml has, or
|
||||
every record vanishes from its desk. `plans/uhhm.yaml` rebuilds
|
||||
uhhm.no this way.
|
||||
- `mails: { <stage>: submitter | <address> }` on a need: who hears
|
||||
when a case enters that stage, sent by portal the moment it moves
|
||||
(portal 0.3.43, delivered by uhhm/gdo on the host). `submitter` goes
|
||||
to the email the form collected, so the form must collect a required
|
||||
`email`; an address is the treasurer, the board. The plan then needs
|
||||
`mail: { from, reply_to }` at the top, the sender every mail carries
|
||||
into `site.yaml`. The words model writes each mail's subject and
|
||||
body (`aggregates.yaml` in the words map); the fallback says what
|
||||
happened and, where the submitter has a move from that stage, the
|
||||
link to make it.
|
||||
- `stages_text: { <stage>: <words> }` on a need: each stage in the
|
||||
plan's language, where the ASCII id will not do (`ikke_lost` reads
|
||||
as English). Used by the fallback mails, the "what happens next"
|
||||
line, the desk buttons' fallback labels, and written into needs.yaml
|
||||
as `stage_words` so the desk score describes an outcome in the
|
||||
site's own words. With them, the vel's desks score 26 of 26.
|
||||
- `turned_down_from: [<stage>, ...]` on a need: the unfinished stages
|
||||
a case can still be turned down from; omitted, every one. An
|
||||
applicant is declined before they start and departs after, which
|
||||
is what uhhm.no's live machine says and what two near-synonymous
|
||||
desk buttons had been standing in for.
|
||||
- `reached_from: { <stage>: [<stage>, ...] }` on a need: where a stage
|
||||
is entered from, when the line a case walks does not say it. Two
|
||||
shapes need it and nothing else does - a case SENT BACK to a stage it
|
||||
was already past (a building application returned for the drawing it
|
||||
was missing, after the hearing turned something up), and a GOOD ENDING
|
||||
PARTWAY ALONG (an authority that changes its own decision while it is
|
||||
looking at the appeal, rather than passing it up to the board). A
|
||||
stage named there is entered from exactly those stages and nowhere
|
||||
else, so saying where a refusal may come from also says where it may
|
||||
not: an applicant may withdraw from anywhere, and be refused only once
|
||||
the papers are in, which `turned_down_from` could not express because
|
||||
it was one list for every bad ending at once. Found by replaying a
|
||||
building authority's real cases through portal's engine, which
|
||||
refused three legal paths and accepted two illegal ones until the
|
||||
plan could say this; see runs/permits-2026-09-25/README.md.
|
||||
- `attended_by:` on a need: who moves cases that no desk button moves,
|
||||
an automation listening on the bucket's events, written into
|
||||
aggregates.yaml as portal's own annotation for the reader.
|
||||
|
||||
## Plan: the intake, read by a model, checked by a person
|
||||
|
||||
```
|
||||
portal-trainer plan --intake intakes/contractor.yaml --out out/nordvik \
|
||||
--personas sectors/construction/needs.yaml \
|
||||
--llm "MODEL=nemotron-3.5-lightning:30b-a3b engines/ollama.sh"
|
||||
```
|
||||
|
||||
This is the one step where a model decides structure: which needs the
|
||||
intake implies, the stages, who handles what, the form, the budget.
|
||||
Its YAML is parsed and validated exactly as `build` will, the errors go
|
||||
back to it, and what passes is written verbatim for a person to read
|
||||
before building from it. Personas are never asked of this model; they
|
||||
are attached from a file, and where their `need:` names an id the plan
|
||||
does not have, `plan` says so and leaves the mapping to the reader.
|
||||
|
||||
`generate` (below) is the older path, a model writing pages free-form
|
||||
against the lint. It is kept for the record of what it measured.
|
||||
|
||||
## How it works
|
||||
|
||||
```
|
||||
intake (plain words)
|
||||
│
|
||||
▼ phase 1 frozen after this phase: the generator
|
||||
needs.yaml ─────────────────────── may not weaken the spec to pass
|
||||
│
|
||||
▼ phase 2 ◄── iris findings, until it exits 0
|
||||
aggregates.yaml + questions/** + desks
|
||||
│
|
||||
▼ phase 3 ◄── misroutes from a blind visitor model
|
||||
wording
|
||||
```
|
||||
|
||||
1. **Needs.** The intake becomes `needs.yaml`: one need per kind of
|
||||
person and thing they want, including the roles inside the
|
||||
business. Each names the bucket the answer lands in, the group that
|
||||
handles it, the states that count as finished, and the effort the
|
||||
visitor will tolerate.
|
||||
2. **Structure.** Pages, state machines and desks are generated, then
|
||||
revised against the lint, `iris check`, until every need is met:
|
||||
a path within budget, a desk held by the right group, every
|
||||
finished state reachable, no record stranding. The page-writing
|
||||
model sees the needs and never the personas.
|
||||
3. **Wording.** A separate model plays each persona, blind, first with
|
||||
headings only and then with descriptions. A misroute is a wording
|
||||
defect and goes back to the generator. A rewrite that breaks
|
||||
structure is reverted.
|
||||
|
||||
Model output is only ever written to `aggregates.yaml`, `site.yaml`
|
||||
and `questions/**.yaml` inside the output directory.
|
||||
|
||||
```
|
||||
portal-trainer generate --intake intakes/contractor.yaml --out out/nordvik \
|
||||
--lint iris --llm engines/ollama.sh
|
||||
portal-trainer answer --tasks tasks.jsonl --llm engines/ollama.sh > answers.jsonl
|
||||
```
|
||||
|
||||
`answer` puts one task per call to the visitor model, with the options
|
||||
shuffled per task and the call seeded from the task id: no visitor
|
||||
sees another visitor's situation, a heading's place on the page cannot
|
||||
carry the answer, and a rerun on the same site is the same experiment.
|
||||
The earlier runs under `runs/` answered all tasks in one prompt.
|
||||
|
||||
The verifier is uhhm/iris, not code in this repo: it
|
||||
reads portal's own content types and ships in every portal release, so
|
||||
a generated repo's CI keeps enforcing its needs after handover.
|
||||
|
||||
## LLM backends
|
||||
|
||||
A backend is any command that takes a prompt on stdin and prints text.
|
||||
|
||||
| Backend | Use |
|
||||
|---|---|
|
||||
| `engines/ollama.sh` | Local Ollama. `MODEL=qwen3:8b` answers a task in about two seconds on ergo's GPU and is the default visitor. Generation wants a larger model (`MODEL=qwen3.6:27b`), which runs mostly on CPU there. |
|
||||
| `engines/claude.sh` | Claude through Claude Code's own login (a Max or Pro subscription), no API key. `MODEL=sonnet` or `opus`, `EFFORT=low` by default. It drops any `ANTHROPIC_API_KEY` from the environment, because a key outranks the login and a stale one fails every call. Log in once with `claude auth login`. |
|
||||
| `engines/anthropic.sh` | The Anthropic API, given a working `ANTHROPIC_API_KEY` from the Console. That is separate, prepaid billing; a subscription does not cover it. |
|
||||
| `engines/mailbox.sh` | Writes each prompt to a directory and waits for a reply file: drive the generator from an agent session, or by hand. |
|
||||
|
||||
The visitor and the generator should be different models. A model
|
||||
grading its own wording agrees with itself.
|
||||
|
||||
## The onboarding site
|
||||
|
||||
`portal-portal/` is the front end of this: a portal content repo whose
|
||||
front door is the intake interview. A submission lands in
|
||||
`onboardings` (`open → drafted ⇄ revising → live | declined`) and is
|
||||
worked from an owners' desk. Today the desk step is a person running
|
||||
`generate` and sending the link; the intake record already carries
|
||||
every field the generator reads, so the step that remains is a
|
||||
listener on `portal.answers.submitted` that runs it and pushes the
|
||||
draft to a new repo. It passes its own `needs.yaml`.
|
||||
|
||||
## The whole card, not the heading
|
||||
|
||||
A visitor never sees a bare heading and description. Portal renders a
|
||||
card: a button, an encouragement, one or more sections each with an
|
||||
icon, a title and a line of guidance, and the fields with their
|
||||
labels and placeholders. Since 2026-09-23 the builder fills all of it
|
||||
and the scorers read all of it.
|
||||
|
||||
- **Slots.** Beside the heading and description, each form alternative
|
||||
gets a button, an encouragement, an icon, a form title and guidance
|
||||
line, and a placeholder per field. A door gets an icon and a "for
|
||||
whom" line. Icons are picked from a fixed list of Iconify lucide
|
||||
names; anything else is dropped.
|
||||
- **Context from the plan.** Every form alternative also carries two
|
||||
sections built from what the plan already knows, before the form:
|
||||
what happens next (the stages, in order, as one sentence) and who
|
||||
reads it (the handling group and the contact). Their fallbacks are
|
||||
true before a model has written a word; the model rewords them.
|
||||
- **Scoring.** `answer --repo <content dir>` shows the visitor each
|
||||
option as its whole card (headings-only tasks stay headings only).
|
||||
`rate --repo` does the same and asks a fourth question, "where": do
|
||||
you know where you are, who this is for, and what the button does.
|
||||
All four are controlled against the gutted twin.
|
||||
|
||||
## Scoring a built site
|
||||
|
||||
```
|
||||
portal-trainer score --site out/nordvik --out out/scored \
|
||||
--iris /var/local/cargo-target/release/iris \
|
||||
--llm "MODEL=qwen3:8b engines/ollama.sh"
|
||||
```
|
||||
|
||||
One command for the whole grading, which every run under `runs/`
|
||||
before 2026-09-23 carried as its own `score.sh`: iris writes the
|
||||
visitor tasks and the simulation model, the blind visitor answers
|
||||
them with descriptions and with headings only, iris scores the
|
||||
answers (the misroutes are printed), and `rate` reads the cards. The
|
||||
two routing numbers land in `summary.json`, the rating in
|
||||
`rated/rate.json`. The pieces still run alone: `answer --tasks` for
|
||||
one visitor model against tasks iris wrote, and:
|
||||
|
||||
```
|
||||
iris check --path out/nordvik/questions --needs-sim model.json
|
||||
portal-trainer rate --model model.json --out out/rated --repo out/nordvik \
|
||||
--llm "MODEL=qwen3:8b engines/ollama.sh"
|
||||
```
|
||||
|
||||
Four yes-or-no questions per persona (which option is mine, where am
|
||||
I and what does the button do, what will I be asked, what happens
|
||||
after I send it), each also put to a gutted
|
||||
twin of the page with headings, descriptions, the form and the
|
||||
followup removed. A question the twin still gets a yes on is not
|
||||
measuring the page, and `rate` says which. The followup page is read
|
||||
from the repo (`--repo`); without it "what happens next" is reported
|
||||
as not measured rather than as zero. LIX is over the prose only
|
||||
(question, descriptions, followup): headings and labels are not
|
||||
sentences and would pull every page down to "very easy". The
|
||||
`rate.json` in `runs/contractor-build-2026-09-21/` predates this and
|
||||
its `asked` and `next` columns are the old, pinned ones.
|
||||
|
||||
`rate --repo` also scores the **desks**, the inside of the business,
|
||||
which reads button labels and nothing else: for every desk and bucket
|
||||
with two or more buttons, a worker is told what has just happened to
|
||||
a case (in the state's own words, never the label's) and picks the
|
||||
button among the ones a row in that state shows, in a rotated order.
|
||||
Scored per desk as right of total, with what each miss was mistaken
|
||||
for. Measured on 2026-09-24 on the live vel: 24 of 26, the misses
|
||||
one button each on the neighbour-help desk and the notice board. Two
|
||||
limits: the outcome is put from the state id, and a Norwegian id with
|
||||
its accents stripped (`ikke_lost`) reads as English even to a strong
|
||||
model; and a first version that offered every button of the bucket,
|
||||
not the row's, scored the same desks 17 of 26 and sent a rewrite
|
||||
chasing an instrument fault. A desk that scores full marks has labels
|
||||
a stranger to the business could press right.
|
||||
`prefer` has a positive control on record
|
||||
(`runs/tomtervel-opener-2026-09-23`, "The friendliness judge"): the
|
||||
live vel front door against a bureaucratic twin, friendlier 9 of 10
|
||||
to the live page and 0 to the twin. A pair that comes back "no
|
||||
preference" throughout is alike in tone, not an instrument that
|
||||
cannot see; and the rejected door rewrite that was judged clearer on
|
||||
5 of 10 needs routed worse across three seeds, so clarity as judged
|
||||
and routing as measured are different things, and routing decides.
|
||||
## Measured so far
|
||||
|
||||
**Generated: a building contractor** (`runs/contractor-2026-09-21/`),
|
||||
from `intakes/contractor.yaml`, a Sonnet-class model generating.
|
||||
|
||||
- Phase 1 derived six needs from the owner's prose, including one
|
||||
nobody asked for: a project manager logging a phone enquiry, taken
|
||||
from "enquiries arrive by phone, email and text and get lost".
|
||||
- Phase 2 was green on the first round: 14 files, four state machines
|
||||
(`enquiries: open → quoted → won | lost`, `subcontractors` with an
|
||||
`awaiting_papers` loop, `applicants`, `site_issues`), two desks.
|
||||
- Phase 3, its own personas: 10 of 10 in both modes. That number is
|
||||
flattering, because in that run the pages were written with the
|
||||
personas in view. Against ten **held-out** personas, with qwen3:8b
|
||||
as the visitor:
|
||||
|
||||
| Visitor could read | Routed right |
|
||||
|---|---|
|
||||
| Headings and descriptions | 10 of 10 |
|
||||
| Headings only | 8 of 10 |
|
||||
|
||||
A scaffolding firm asking "how do I get to do jobs for you?" chose
|
||||
"Ask about working with us" (the hiring door). An attic conversion
|
||||
chose "Get someone to look at a building". The generator has since
|
||||
been changed to hide personas from the page-writing phase.
|
||||
|
||||
**Built: the same contractor from a plan** (`runs/contractor-build-2026-09-21/`),
|
||||
nemotron writing words only, and re-scored one task per call the day
|
||||
after (`rescore-2026-09-22/` in it): 8 of 8 with descriptions, 7 of 8
|
||||
on headings alone, the miss being an apprentice bricklayer reading
|
||||
"Join our carpentry team" as not for them. `rate` on the same site,
|
||||
with the followup shown and every question controlled, passes its
|
||||
controls and puts the pages at LIX 18 to 35.
|
||||
|
||||
**Built behind doors, 2026-09-22.** Five plans with a first question
|
||||
before the forms, each built and then scored by qwen3:8b one task per
|
||||
call, against held-out personas. Behind a door a persona is asked
|
||||
twice, on the front door and on the door's page.
|
||||
|
||||
| Case | Words by | With descriptions | Headings only | Notes |
|
||||
|---|---|---|---|---|
|
||||
| Machine hire (`hire`) | nemotron | 10 of 10 | 10 of 10 | doors that ask a question the visitor already knows the answer to |
|
||||
| Physio clinic (`physio`) | nemotron | 8 of 10 | 9 of 10 | "Book your first appointment" fails a daughter booking for her mother |
|
||||
| Football club, Norwegian (`fotballklubb`) | nemotron | 14 of 16 | 11 of 16 | three parents walk past "Er det på tide å melde inn?" |
|
||||
| Football club, Norwegian | Claude Sonnet | 13 of 16 | 12 of 16 | better sentences, same driver/sponsor blur |
|
||||
| Whole contractor (`contractor-full`) | nemotron | 18 of 22 | 15 of 22 | "Apply to work with us" and "Find a job with us" cross over for all four |
|
||||
| Tomter Vel, Norwegian (`tomtervel`), first plan | Claude Sonnet | 25 of 30 | 22 of 30 | "utstyr" for a swing, hearing input behind the wrong door |
|
||||
| Tomter Vel, plan revised 2026-09-23, whole card | Claude Sonnet | 31 of 38 | 30 of 38 | committees as groups, public lists, hearing input on the front door |
|
||||
|
||||
Each run's README names the misroutes and what in the plan or the
|
||||
heading caused them. A stronger word model did not route better on
|
||||
the one plan built with both: routing is decided by which distinctions
|
||||
sit on one page, and the visitor grades that the same whoever wrote
|
||||
the words.
|
||||
|
||||
**Planned: the contractor intake read by a local model**
|
||||
(`runs/contractor-plan-2026-09-22/`), nemotron, one round, 41 s. The
|
||||
plan passed every check `build` makes and a reader finds three
|
||||
structural misses in it the checks cannot: the crew's report made
|
||||
public, the "papers missing" stage dropped, and no need for the
|
||||
project manager logging a call. The person reading the plan is not
|
||||
optional.
|
||||
|
||||
**Existing site: uhhm.no** (`runs/uhhm-2026-09-21/`), eight tasks.
|
||||
|
||||
| Visitor model | With descriptions | Headings only |
|
||||
|---|---|---|
|
||||
| small LLM, blind | 7 of 8 | 5 of 8 |
|
||||
| qwen3:8b (Ollama) | 7 of 8 | 7 of 8 |
|
||||
| granite4.1:8b (Ollama) | 7 of 8 | 6 of 8 |
|
||||
|
||||
All three send a paying client through **"Work happens through
|
||||
dialogue, not tickets"**, the collaborator door. Different models,
|
||||
same defect: that is what a wording problem looks like.
|
||||
|
||||
**The noise floor, 2026-09-23** (`runs/spread.sh`, `answer --seed`).
|
||||
The same tasks answered by qwen3:8b with four seeds (0 is the run
|
||||
every score above used):
|
||||
|
||||
| Run | With descriptions | Headings only |
|
||||
|---|---|---|
|
||||
| uhhm.no round 6, 15 tasks | 11, 10, 10, 10 | 12, 12, 7, 7 |
|
||||
| Tomter Vel with the opener, 38 tasks | 30, 29, 29, 31 | 26, 24, 26, 23 |
|
||||
|
||||
With descriptions the visitor is steady: one task in fifteen, two in
|
||||
thirty-eight. On headings alone it is not: five of fifteen on uhhm.no
|
||||
between seeds, three of thirty-eight on the vel. A headings-only
|
||||
difference smaller than that is the visitor's mood. Compare
|
||||
descriptions-mode scores; read headings-only as a sanity check, and
|
||||
run several seeds before believing it.
|
||||
Small numbers, one run each. Leads, not measurements.
|
||||
|
||||
## What else is here
|
||||
|
||||
- `skill/SKILL.md` - the same procedure for an agent or a person
|
||||
working by hand.
|
||||
- `sectors/` - needs specs to start from. `construction/` doubles as
|
||||
the held-out persona set above.
|
||||
- `generator/reference.md` - everything the generating model is told
|
||||
about portal content. When the lint rejects something the reference
|
||||
did not warn about, the fix belongs there.
|
||||
|
||||
## Toward a trained model
|
||||
|
||||
Nothing here trains weights yet. What would make it possible is
|
||||
accumulating: every run leaves the intake, the needs, the pages at
|
||||
each revision and the scores. With a fast local visitor as the scorer,
|
||||
generating many variants per need and keeping the winners is cheap,
|
||||
and those winners are the fine-tuning set for a small generator. The
|
||||
verifier has to be trusted before any of that: a generator trained
|
||||
against a judge that is often wrong learns the judge.
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
# LLM backend for portal-trainer: prompt on stdin, text on stdout.
|
||||
# Needs ANTHROPIC_API_KEY, curl and jq. MODEL and MAX_TOKENS override.
|
||||
set -eu
|
||||
: "${ANTHROPIC_API_KEY:?set ANTHROPIC_API_KEY}"
|
||||
jq -Rs --arg model "${MODEL:-claude-sonnet-5}" --argjson max "${MAX_TOKENS:-16000}" \
|
||||
'{model: $model, max_tokens: $max, messages: [{role: "user", content: .}]}' |
|
||||
curl -sS --fail-with-body --max-time "${TIMEOUT:-600}" https://api.anthropic.com/v1/messages \
|
||||
-H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" \
|
||||
-H "content-type: application/json" --data-binary @- |
|
||||
jq -er '[.content[] | select(.type == "text") | .text] | join("")'
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
# LLM backend for portal-trainer on Claude Code's own login (a Max or
|
||||
# Pro subscription): prompt on stdin, text on stdout. No API key
|
||||
# needed: an ANTHROPIC_API_KEY in the environment would outrank the
|
||||
# login, so it is dropped here. Log the CLI in once with
|
||||
# `claude auth login`; `claude auth status` shows what it uses.
|
||||
# MODEL is an alias or id (sonnet, opus, claude-sonnet-5); EFFORT is
|
||||
# low, medium or high. Not --bare: that mode skips the stored login.
|
||||
#
|
||||
# The generator's SEED and TEMPERATURE hints cannot be honoured;
|
||||
# FORMAT=json is turned into an instruction.
|
||||
set -eu
|
||||
unset ANTHROPIC_API_KEY ANTHROPIC_AUTH_TOKEN CLAUDECODE CLAUDE_CODE_ENTRYPOINT
|
||||
prompt=$(cat)
|
||||
if [ "${FORMAT:-}" = json ]; then
|
||||
prompt="$prompt
|
||||
|
||||
Reply with the JSON object only, no prose, no code fences."
|
||||
fi
|
||||
printf '%s' "$prompt" | claude -p --model "${MODEL:-sonnet}" --effort "${EFFORT:-low}" \
|
||||
--output-format text --permission-mode dontAsk --no-session-persistence \
|
||||
--tools ""
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
# LLM backend that hands each prompt to whoever watches $MAILBOX:
|
||||
# prompt-N.md goes out, the reply is read from reply-N.md. For driving
|
||||
# the generator from an agent session, or by hand.
|
||||
set -eu
|
||||
: "${MAILBOX:?set MAILBOX to a directory}"
|
||||
mkdir -p "$MAILBOX"
|
||||
n=$(( $(ls "$MAILBOX" | grep -c '^prompt-' || true) + 1 ))
|
||||
cat > "$MAILBOX/prompt-$n.md"
|
||||
until [ -s "$MAILBOX/reply-$n.md" ]; do sleep 2; done
|
||||
sleep 1
|
||||
cat "$MAILBOX/reply-$n.md"
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
# LLM backend for portal-trainer on a local Ollama: prompt on stdin,
|
||||
# text on stdout. MODEL, OLLAMA_HOST, NUM_CTX and TIMEOUT override.
|
||||
# Thinking is off: the generator wants files, the answerer wants JSONL.
|
||||
# The simulator sets SEED (so the same case replays the same way
|
||||
# against two versions of a site), FORMAT=json and TEMPERATURE.
|
||||
set -eu
|
||||
jq -Rs --arg model "${MODEL:-qwen3:8b}" --argjson ctx "${NUM_CTX:-32768}" \
|
||||
--argjson temp "${TEMPERATURE:-0.2}" --arg seed "${SEED:-}" --arg format "${FORMAT:-}" \
|
||||
'{model: $model, stream: false, think: false,
|
||||
options: ({num_ctx: $ctx, temperature: $temp}
|
||||
+ (if $seed == "" then {} else {seed: ($seed | tonumber)} end)),
|
||||
messages: [{role: "user", content: .}]}
|
||||
+ (if $format == "json" then {format: "json"} else {} end)' |
|
||||
curl -sS --fail-with-body --max-time "${TIMEOUT:-1800}" \
|
||||
"${OLLAMA_HOST:-http://127.0.0.1:11434}/api/chat" \
|
||||
-H "content-type: application/json" --data-binary @- |
|
||||
jq -er '.message.content'
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
# Portal content reference (for the generator)
|
||||
|
||||
Portal serves a site that is one question per page. Each page offers a
|
||||
few alternatives. An alternative may carry a form; submitting it
|
||||
records the answer into a *bucket* whose records move through a state
|
||||
machine, worked from a *desk*: a page gated to a group, listing the
|
||||
bucket with one button per allowed move. There is no other mechanism.
|
||||
Everything a business needs is expressed as: who answers which
|
||||
question, where the answer lands, who moves it, through which states.
|
||||
|
||||
A content repo is these files and nothing else:
|
||||
|
||||
```
|
||||
needs.yaml what the business needs (the spec you are held to)
|
||||
aggregates.yaml one state machine per bucket
|
||||
site.yaml title and language
|
||||
questions/index.yaml the front door, "/"
|
||||
questions/<name>.yaml "/<name>"
|
||||
questions/<dir>/index.yaml "/<dir>"
|
||||
questions/<dir>/_section.yaml applies `qualifies` to the whole directory
|
||||
questions/<dir>/<name>.yaml "/<dir>/<name>" - a followup page by default
|
||||
```
|
||||
|
||||
## needs.yaml
|
||||
|
||||
```yaml
|
||||
needs:
|
||||
- id: kebab-case
|
||||
who: the kind of person, in plain words
|
||||
wants: what they want from the business
|
||||
enters: / # page they arrive on; default /
|
||||
enters_as: <group> # only when they are logged-in members of a group; omit for the public
|
||||
via: <alternative name> # only when several alternatives on the entry page record into the same bucket
|
||||
lands_in: <bucket>
|
||||
handled_by: <group> # the role inside the business that must see and move the record
|
||||
done_when: [<state>, <state>] # every state that counts as finished, good or bad
|
||||
max_steps: 1 # submissions before the record exists (1 or 2)
|
||||
max_fields: 4 # required fields the visitor will tolerate across the path
|
||||
success: [<state>] # the done_when states that are a good outcome for the business
|
||||
stages: [open, <stage>, <stage>, <end>, <end>]
|
||||
# EVERY stage the business said a case goes through, first to last,
|
||||
# read off their own sentences one verb at a time ("they come in, we
|
||||
# go and look, we send a quote, we win or lose it" is five stages).
|
||||
# The state machine must have a state for each, or the verifier fails.
|
||||
personas:
|
||||
- id: kebab-case
|
||||
need: <need id>
|
||||
text: >
|
||||
Two or three sentences in the visitor's own voice and vocabulary.
|
||||
```
|
||||
|
||||
Rules:
|
||||
- One need per (kind of person, thing they want). Internal work counts:
|
||||
a role inside the business recording or posting something is a need
|
||||
with `enters_as`.
|
||||
- States come from the business's own description of how a thing
|
||||
progresses. A pipeline is not an inbox: "answered" is rarely the real
|
||||
outcome.
|
||||
- `max_fields` is small on purpose. Reporting something from a phone
|
||||
gets 3. A first enquiry gets 4 to 6.
|
||||
- Two or three personas per public need. At least one must avoid the
|
||||
trade's own vocabulary. A persona must never quote a page heading.
|
||||
|
||||
## aggregates.yaml
|
||||
|
||||
```yaml
|
||||
aggregates:
|
||||
- bucket: leads
|
||||
initial: open
|
||||
states: # state: { event: past-tense verb }
|
||||
open: { event: received }
|
||||
quoted: { event: quoted }
|
||||
won: { event: won }
|
||||
lost: { event: lost }
|
||||
transitions: # only moves the business described
|
||||
open: [quoted, lost]
|
||||
quoted: [won, lost]
|
||||
```
|
||||
|
||||
The initial state should be `open` (a desk transition with no `from`
|
||||
means from `open`).
|
||||
|
||||
## A page
|
||||
|
||||
```yaml
|
||||
name: What brings you here? # always a question the visitor could ask themselves
|
||||
description: >
|
||||
One or two sentences.
|
||||
responsible: { name: <person or team>, contact: <email> } # required on every entry page
|
||||
alternatives:
|
||||
- name: <heading> # what the visitor picks. Must work WITHOUT the description.
|
||||
description: >
|
||||
One or two sentences.
|
||||
action: /received # absolute path of an existing page
|
||||
consequence: [Send] # the button label
|
||||
record_as: leads # omit for a pure navigation alternative
|
||||
features:
|
||||
- name: About the building
|
||||
description: Optional line of guidance.
|
||||
requirements:
|
||||
- { name: email, label: Email, type: email }
|
||||
- { name: problem, label: What is wrong, type: textarea }
|
||||
- { name: urgency, label: How soon, type: select, options: [This week, This month, No rush] }
|
||||
- { name: address, label: Address, optional: true }
|
||||
```
|
||||
|
||||
- Field types: `text` (default), `email`, `tel`, `textarea`, `date`,
|
||||
`select` (must list `options`). Use no other types.
|
||||
- Every `action` must name a page that exists. After a recording
|
||||
alternative, send the visitor to a followup page that says who reads
|
||||
it, when they answer, and what happens next. A followup page is a
|
||||
top-level file with `followup: true`, or any non-index file in a
|
||||
subdirectory. Give it one alternative with `action: /` to go back.
|
||||
- A page for members of a group sets `qualifies: <group>` (or sits in a
|
||||
directory whose `_section.yaml` does). Only `enters_as: <group>`
|
||||
needs can use it.
|
||||
- Every bucket that is recorded into must be read by a desk.
|
||||
|
||||
## A desk
|
||||
|
||||
```yaml
|
||||
# questions/desk/_section.yaml
|
||||
qualifies: project_managers
|
||||
```
|
||||
```yaml
|
||||
# questions/desk/index.yaml
|
||||
name: What came in?
|
||||
responsible: { name: ..., contact: ... }
|
||||
alternatives:
|
||||
- name: Leads
|
||||
description: One line on what to do with them.
|
||||
action: /desk
|
||||
consequence: [Confirm]
|
||||
features:
|
||||
- name: ""
|
||||
description: ""
|
||||
resource:
|
||||
source: { kind: kv, bucket: leads }
|
||||
requires_group: project_managers
|
||||
transitions:
|
||||
- { to: quoted, label: Quote sent }
|
||||
- { to: lost, label: Not for us }
|
||||
- { from: quoted, to: won, label: Won }
|
||||
- { from: quoted, to: lost, label: Lost }
|
||||
```
|
||||
|
||||
- One desk directory per handling group; one alternative per bucket
|
||||
that group handles.
|
||||
- Offer every move the state machine allows and no other. A state with
|
||||
no move out of it, on the way to a finished state, strands records.
|
||||
- A group may read a bucket it does not handle: the same `resource`
|
||||
block with its own `requires_group` and no `transitions`.
|
||||
|
||||
## site.yaml
|
||||
|
||||
```yaml
|
||||
title: <business name>
|
||||
lang: en
|
||||
```
|
||||
|
||||
## Language
|
||||
|
||||
Everything a person reads is written in the intake's `language`: page
|
||||
names, headings, descriptions, field labels, button labels, the
|
||||
`who`/`wants` of each need, and the personas. Write it the way people
|
||||
in that trade and country actually speak, not as a translation.
|
||||
Everything a machine reads stays plain ASCII snake_case or kebab-case:
|
||||
need ids, persona ids, bucket names, state names, field `name`s, file
|
||||
names and paths. Letters such as æ, ø and å belong in the copy and
|
||||
never in an identifier. Set `lang` in site.yaml to the intake's code.
|
||||
|
||||
## Copy rules
|
||||
|
||||
- Headings say what the visitor gets, in the visitor's words.
|
||||
- Lead with what a thing enables. Never define something by what it
|
||||
is not. No negations in headings.
|
||||
- Two alternatives must never be separable only by a distinction the
|
||||
business makes and the visitor does not.
|
||||
- Every required field is one the business will use to answer.
|
||||
|
||||
## The verifier
|
||||
|
||||
`question_lint` runs after every attempt. Non-zero exit means you are
|
||||
not done. Its messages are exact:
|
||||
|
||||
- `no path from ... records into ...`: no chain of alternatives from
|
||||
the entry page reaches an alternative with that `record_as`.
|
||||
- `the path asks for N required field(s), over the budget`: mark fields
|
||||
`optional: true` or drop them.
|
||||
- `no desk gated on "g" reads "b"`: add the desk.
|
||||
- `"g" cannot move a record to "s"` / `records strand in "s"`: the desk
|
||||
is missing a transition the state machine allows, or the state
|
||||
machine is missing the edge.
|
||||
- `action ... does not match any declared question id`: the page does
|
||||
not exist.
|
||||
- `entry page ... names no one responsible`: add `responsible`.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Held out from every model that writes words. Each is one real person
|
||||
# arriving with one real thing, in their own register: a homeowner who
|
||||
# has never read a regulation, a firm that files for a living, an
|
||||
# inspector on a roof in the wind, a politician reading a bundle.
|
||||
personas:
|
||||
- { id: garage-owner, need: pre-application-meeting, text: "We want to put a double garage where the old shed is. Before I pay an architect I'd like to know whether you'll even allow it, because the neighbour says it's too close to the road." }
|
||||
- { id: shop-to-flats, need: pre-application-meeting, text: "I own the old grocery on Torget and want to make four flats out of it. There are a lot of questions - parking, fire, the facade is listed. Can we sit down with someone?" }
|
||||
- { id: firm-files-extension, need: permit-application, text: "We are the responsible applicant for an extension at Bjorkeveien 14. Drawings, site plan and the neighbour notices are all ready. We file maybe forty of these a year." }
|
||||
- { id: owner-small-window, need: permit-application, text: "I want to put a dormer window in my roof. The man at the counter said I have to apply even though it's small." }
|
||||
- { id: missing-drawings, need: permit-application, text: "You wrote that our section drawing is missing and the case is on hold. I've got it here now, where do I send it so the clock starts again?" }
|
||||
- { id: too-close-to-boundary, need: exemption-request, text: "The garage ends up one and a half metres from the boundary and the plan says four. We are asking you to allow it anyway - the ground falls away steeply everywhere else on the plot." }
|
||||
- { id: neighbour-view, need: objection, text: "I got a notice about the extension at number 14. It takes the afternoon sun off my entire terrace and I want that on the record before you decide anything." }
|
||||
- { id: neighbour-parking, need: objection, text: "The flats they want to build in the old grocery have four parking places for four flats and everyone here already parks on the street. I object." }
|
||||
- { id: road-authority, need: hearing-answer, text: "Regarding your case 2026/418: the access onto the county road is within the sight line and we cannot accept it as drawn. Our formal reply is attached." }
|
||||
- { id: fire-service, need: hearing-answer, text: "We have looked at the conversion on Torget. We have no objection provided the stairwell is upgraded. Reference your case 2026/501." }
|
||||
- { id: refused-applicant, need: appeal, text: "You refused our exemption on the ninth. We don't accept the reasoning - you've allowed the same thing twice in the same street. We're appealing." }
|
||||
- { id: neighbour-appeals, need: appeal, text: "You approved the extension next door even though I objected. I'm appealing the decision. What do I need to send?" }
|
||||
- { id: board-member, need: appeal, text: "I sit on the appeals board. I need the case, our own decision, and what the neighbours wrote, before Tuesday." }
|
||||
- { id: inspector-on-roof, need: inspection-finding, text: "I'm up on the scaffold at Bjorkeveien. The fire wall isn't built to the drawing at all. I've got gloves on and it's blowing. I want this logged before I climb down." }
|
||||
- { id: inspector-all-good, need: inspection-finding, text: "Been out at Torget. Everything is as approved. Nothing to report but I have to record that I was there." }
|
||||
- { id: firm-wants-certificate, need: completion-request, text: "The work at Bjorkeveien 14 is finished and inspected. We're asking for the completion certificate so the owners can get their mortgage released." }
|
||||
- { id: wants-to-move-in, need: completion-request, text: "The house is done apart from the outside steps, which we can't pour until spring. The family has sold their flat. Can we get a temporary permission to move in?" }
|
||||
- { id: something-behind-fence, need: illegal-building-report, text: "There's a large structure going up behind the fence at Solbakken 7. Nobody has had a notice about it and it's been going on for two weeks." }
|
||||
- { id: owner-explains, need: illegal-building-report, text: "I got your letter about the terrace. I genuinely did not know it needed an application, it's been there since we moved in. What happens now?" }
|
||||
- { id: new-firm, need: firm-approval, text: "We are a three-person architecture firm that has just started. We want to be approved so we can file applications for our clients in your municipality." }
|
||||
- { id: firm-insurance-lapsed, need: firm-approval, text: "You wrote that our liability insurance certificate has expired. We have renewed it, here it is." }
|
||||
- { id: counter-phone-call, need: log-counter-enquiry, text: "A woman rang about the case behind her house. Wants to know where it stands. I'm at the counter and there's a queue - I need to write it down and send it to whoever has that case." }
|
||||
- { id: where-is-my-case, need: case-status-enquiry, text: "I sent in my application five weeks ago and I've heard nothing. Is anyone looking at it? Is it in the six weeks with the neighbours or is it waiting on me?" }
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
# A building authority's intake: the hardest sector the trainer has
|
||||
# been given. Cases that pause and resume, cases that belong to other
|
||||
# cases, a decision two roles sign, a deadline nobody in the building
|
||||
# controls, and an appeal that reopens something already finished.
|
||||
# Written the way the department head would write it, in plain words.
|
||||
business: Vestmark kommune - Building and Planning
|
||||
contact: { name: Solveig Hauge, email: byggesak@vestmark.example }
|
||||
language: en
|
||||
|
||||
what_we_do: >
|
||||
We are the building authority for a municipality of twenty-one
|
||||
thousand people. Anyone who wants to build, demolish, divide a
|
||||
property or change what a building is used for has to come to us
|
||||
first. We check the drawings against the zoning map and the building
|
||||
regulations, we let the neighbours and the other authorities have
|
||||
their say, and then we approve or refuse. We also decide exemptions
|
||||
from the zoning rules, we inspect what is actually built, we sign off
|
||||
finished work, and we deal with building that was never applied for.
|
||||
|
||||
who_comes_to_us: >
|
||||
Homeowners who want a garage, an extension or a new window, and who
|
||||
have never read a regulation in their life. Architects and
|
||||
engineering firms who file on behalf of owners; they have to be
|
||||
approved by us before they may file anything. Neighbours who got a
|
||||
notice in the post and do not agree with what is planned next door.
|
||||
The other authorities we are obliged to ask: the road authority, the
|
||||
fire service, the heritage office, the county. People who ring to say
|
||||
something is going up behind their fence without permission. And
|
||||
anyone who wants to sit down with us before they spend eighty
|
||||
thousand on drawings.
|
||||
|
||||
what_we_keep_track_of: >
|
||||
Pre-application meetings: someone asks for one, we find a time, we
|
||||
meet, and we write down what we told them so they can hold us to it.
|
||||
Applications: they arrive, someone checks whether the papers are all
|
||||
there, and if something is missing we write and ask for it, and the
|
||||
twelve-week clock stops until they answer. Often we have to ask
|
||||
twice. When it is complete we send it out to the neighbours and to
|
||||
the agencies and wait six weeks. Then a case officer writes a
|
||||
recommendation, and the head of section signs the decision: approved,
|
||||
approved with conditions, or refused. People can withdraw at any
|
||||
point, and quite a few do once they hear from the neighbours.
|
||||
Exemptions: if what someone wants breaks the zoning rules they can
|
||||
ask for an exemption. It rides along with the application but it is a
|
||||
decision of its own, and we are not allowed to grant one before the
|
||||
county has been asked.
|
||||
Objections: a neighbour who got a notice writes to us within the
|
||||
hearing period. Each objection belongs to an application. We register
|
||||
it, the applicant gets to answer it, and the case officer has to
|
||||
address every single one in the decision, by name.
|
||||
Hearing answers: we ask an agency, they answer, or they do not, and
|
||||
when the deadline has passed we go on without them.
|
||||
Appeals: for three weeks after a decision anyone with an interest can
|
||||
appeal it. We go through it ourselves first, and if we change our own
|
||||
mind that is the end of it. If we do not, it goes to the appeals
|
||||
board, who meet once a month and either uphold us or overturn us.
|
||||
Inspections: we pick cases and go and look, on site. Either it is as
|
||||
approved, or we write up what is wrong and set a date for it to be
|
||||
put right, and then we go back.
|
||||
Finishing: when the work is done the firm asks for a completion
|
||||
certificate. If they want to move in before everything is done they
|
||||
can ask for a temporary permission instead. We check what was
|
||||
inspected and what is still outstanding before we sign anything.
|
||||
Illegal building: someone reports it, we go and look, we write to the
|
||||
owner and they have to explain themselves, and then they either apply
|
||||
for it properly, take it down, or we fine them weekly until they do.
|
||||
Approved firms: a firm sends us their registration, their insurance
|
||||
and what they are qualified for, we check it, and then they are on
|
||||
the list and may file applications.
|
||||
|
||||
who_is_involved: >
|
||||
The front desk logs what comes in over the counter and on the phone,
|
||||
and keeps the archive. Four case officers carry the cases. The head
|
||||
of section signs every decision and every exemption; a case officer
|
||||
may not sign their own. Two inspectors are out on site most of the
|
||||
week and write up what they find on a phone in a cold wind. The
|
||||
appeals board is seven elected politicians who meet on the third
|
||||
Tuesday of the month and read what we send them. The agencies are
|
||||
outside the building altogether and only ever answer hearings. The
|
||||
approved firms file applications and answer objections on behalf of
|
||||
their clients.
|
||||
|
||||
what_slows_us_down: >
|
||||
The twelve-week clock, and the fact that stopping it and starting it
|
||||
again is done by hand in a spreadsheet. Applications that arrive
|
||||
missing half the drawings. Objections that come in on paper and get
|
||||
stapled to the wrong case. Neighbours ringing to ask what is
|
||||
happening with the case behind their house, which we are obliged to
|
||||
tell them and which takes ten minutes every time. Agencies that never
|
||||
answer at all. And nobody outside this building can see a case
|
||||
without asking us for it.
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
# An intake as the owner of a small building contractor would fill it
|
||||
# in: plain words, no portal vocabulary. These are the fields the
|
||||
# onboarding site asks for.
|
||||
business: Nordvik Bygg
|
||||
contact: { name: Ingrid Nordvik, email: ingrid@nordvikbygg.example }
|
||||
language: en
|
||||
|
||||
what_we_do: >
|
||||
We are twelve people. We survey old buildings, draw up rehabilitation
|
||||
plans, handle the permit application, and do the building work with
|
||||
our own carpenters plus subcontractors for electrical, plumbing and
|
||||
scaffolding.
|
||||
|
||||
who_comes_to_us: >
|
||||
Housing boards and private owners who have a problem with a building
|
||||
and want someone to look at it. Owners who already know what they
|
||||
want built and need drawings, a permit and a price. Trade firms who
|
||||
want to be on our list of subcontractors. Carpenters and apprentices
|
||||
asking if we are hiring.
|
||||
|
||||
what_we_keep_track_of: >
|
||||
Enquiries: they come in, we go and look at the building, we send a
|
||||
quote, and then we either win it or lose it. Sometimes it is simply
|
||||
not for us and we say so straight away.
|
||||
Subcontractors: they apply, we check their company registration,
|
||||
trade approval and insurance. Often papers are missing and we have to
|
||||
ask again. Then they are approved or turned down.
|
||||
Job applications: we read them, invite some to an interview, and hire
|
||||
or decline.
|
||||
Things that go wrong on site: a hazard, a near miss, wrong materials
|
||||
delivered. Someone reports it, the safety officer decides what is
|
||||
done about it, and closes it when it is fixed.
|
||||
|
||||
who_is_involved: >
|
||||
Two project managers handle enquiries, subcontractors and hiring.
|
||||
One safety officer handles everything reported from site.
|
||||
The crew, ours and the subcontractors' people, are the ones on site
|
||||
who report things. They are on their phones, with gloves on, and
|
||||
will not fill in a long form.
|
||||
|
||||
what_slows_us_down: >
|
||||
Enquiries arrive by phone, email and text and get lost. We never know
|
||||
which subcontractors have valid papers. Site problems get mentioned
|
||||
at lunch and forgotten.
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
# Slik lederen i en fotballgruppe ville fylt det ut.
|
||||
business: Lia IL Fotball
|
||||
contact: { name: Kari Lien, email: kari@liail.example }
|
||||
language: no
|
||||
|
||||
what_we_do: >
|
||||
Fotballgruppa i et idrettslag på bygda. Rundt hundre og tjue unger
|
||||
fra seks til sekstenår, fordelt på lag etter årskull. Alt drives av
|
||||
foreldre på fritida: trenere, lagledere, en kasserer og et styre.
|
||||
|
||||
who_comes_to_us: >
|
||||
Foreldre som vil ha ungen med på et lag. Foreldre som sliter med
|
||||
treningsavgiften og vil dele den opp eller slippe. Folk som vil
|
||||
hjelpe til, som trener, lagleder, sjåfør eller på dugnad. Bedrifter
|
||||
i bygda som vil sponse.
|
||||
|
||||
what_we_keep_track_of: >
|
||||
Innmeldinger: en forelder melder inn, treneren på årskullet
|
||||
godkjenner at det er plass, kassereren ser at avgiften er betalt.
|
||||
Noen trekker seg underveis.
|
||||
Avgiftssaker: noen ber om å dele opp eller slippe avgiften; styret
|
||||
vurderer og sier ja eller nei.
|
||||
Frivillige: noen tilbyr seg, styret tar kontakt og plasserer dem der
|
||||
det trengs, eller takker nei.
|
||||
Sponsorer: en bedrift melder interesse, vi tar en prat, og det blir
|
||||
en avtale eller ikke.
|
||||
Ting på banen: lys som ikke virker, mål som er ødelagt, drakter som
|
||||
mangler. Trenerne melder fra, styret tar tak i det og ordner det.
|
||||
|
||||
who_is_involved: >
|
||||
Trenerne godkjenner innmeldinger på sitt årskull og melder fra om
|
||||
banen. Kassereren følger opp betaling. Styret tar frivillige,
|
||||
sponsorer, avgiftssaker og alt som gjelder anlegget.
|
||||
|
||||
what_slows_us_down: >
|
||||
Alt går i en gruppechat og et regneark. Trenerne vet ikke hvem som
|
||||
har betalt, kassereren vet ikke hvem som er godkjent, og en som
|
||||
tilbød seg å kjøre i høst fikk aldri svar.
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
# An intake as the owner of a machine hire yard would fill it in.
|
||||
business: Fjellstad Hire
|
||||
contact: { name: Ola Fjellstad, email: ola@fjellstadhire.example }
|
||||
language: en
|
||||
|
||||
what_we_do: >
|
||||
We hire out machines: mini diggers, lifts, compactors, generators,
|
||||
that kind of thing. A counter with two people, a yard with three who
|
||||
deliver, collect and fix, and me in the office doing accounts and
|
||||
the business customers.
|
||||
|
||||
who_comes_to_us: >
|
||||
Private people who need a machine for a weekend and have often never
|
||||
driven one. Building and landscaping firms who need something on a
|
||||
site from a date for a period. Anyone whose hired machine has
|
||||
stopped working while they have it. Firms who hire often and want
|
||||
an account so they can send anyone to collect and get one invoice a
|
||||
month.
|
||||
|
||||
what_we_keep_track_of: >
|
||||
Hires: someone asks, the counter reserves it, the yard hands it out
|
||||
or delivers it, and the yard takes it back. Some are cancelled
|
||||
before they go out.
|
||||
Breakdowns: a machine stops during a hire; the yard takes it on and
|
||||
either fixes it on site or swaps it.
|
||||
Account applications: a firm applies, I check the company and its
|
||||
credit, and it is approved or turned down.
|
||||
Damage on return: the yard finds damage when a machine comes back; I
|
||||
either invoice the customer or write it off.
|
||||
|
||||
who_is_involved: >
|
||||
The counter handles hires. The yard handles breakdowns and the
|
||||
handing out and taking back. The office does accounts and damage.
|
||||
|
||||
what_slows_us_down: >
|
||||
The yard finds out about breakdowns from whoever picks up the phone.
|
||||
Damage found on return is written on a whiteboard and half of it is
|
||||
never invoiced.
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
# An intake as the manager of a physiotherapy clinic would fill it in.
|
||||
business: Bakken Fysioterapi
|
||||
contact: { name: Marit Bakken, email: marit@bakkenfysio.example }
|
||||
language: en
|
||||
|
||||
what_we_do: >
|
||||
Six physiotherapists and a receptionist. People come to us with
|
||||
pain, injuries and after operations; we assess them and treat them
|
||||
over a course of sessions. Some come on their own, some are sent by
|
||||
a GP or a hospital, and some have insurance that pays if the insurer
|
||||
approves the course first.
|
||||
|
||||
who_comes_to_us: >
|
||||
People with something that hurts who want to see the right
|
||||
therapist. Patients who already have a time and need to move or
|
||||
drop it. GPs and hospital wards sending us someone, who want to
|
||||
hear how it went. Insurers, through us, when a course has to be
|
||||
approved before it starts.
|
||||
|
||||
what_we_keep_track_of: >
|
||||
Requests for a first appointment: they come in, we offer a time with
|
||||
a therapist who suits, and it is either booked or they go elsewhere.
|
||||
Cancellations: someone can't come; we either find them a new time or
|
||||
give the slot to someone waiting.
|
||||
Referrals: a doctor sends someone, we accept it, book them in, treat
|
||||
them, and send the doctor a report at the end. Sometimes we send it
|
||||
back because it isn't something we treat.
|
||||
Insurance approvals: for some patients we have to ask the insurer
|
||||
before we start; we send the request and it comes back approved or
|
||||
refused.
|
||||
No-shows: someone doesn't turn up and doesn't call. The receptionist
|
||||
rings them and either rebooks or, after a couple of times, closes it.
|
||||
|
||||
who_is_involved: >
|
||||
The receptionist handles every request, cancellation, referral and
|
||||
approval. The therapists treat and write the report back to the
|
||||
doctor, and they are the ones who notice a no-show.
|
||||
|
||||
what_slows_us_down: >
|
||||
Referrals, cancellations and insurance approvals all go through one
|
||||
inbox that only the receptionist understands. Therapists tell her
|
||||
about no-shows in the corridor and they get forgotten.
|
||||
@@ -0,0 +1,48 @@
|
||||
# En fiktiv norsk rehabiliteringsentreprenør, inspirert av hva
|
||||
# Klingenberg Bygg driver med: tilstandsrapporter, prosjektering,
|
||||
# byggesøknader og utførelse på eldre murgårder. Skrevet slik eieren
|
||||
# ville sagt det, uten portal-ord.
|
||||
business: Åsrud Bygg og Rehabilitering AS
|
||||
contact: { name: Marte Åsrud, email: marte@asrudbygg.example }
|
||||
language: "no"
|
||||
|
||||
what_we_do: >
|
||||
Vi er fjorten ansatte og jobber mest med eldre murgårder og
|
||||
trehus. Vi lager tilstandsrapporter, prosjekterer rehabilitering,
|
||||
sender byggesøknad med ansvarsrett, og utfører arbeidet med egne
|
||||
tømrere og murere. Elektriker, rørlegger, stillas og blikkenslager
|
||||
leier vi inn som underentreprenører.
|
||||
|
||||
who_comes_to_us: >
|
||||
Styreledere i borettslag og sameier, og private huseiere, som har
|
||||
et problem med bygget og vil at noen skal se på det. Eiere som
|
||||
allerede vet hva de vil bygge eller endre, og trenger tegninger,
|
||||
søknad til kommunen og en pris. Håndverksfirmaer som vil stå på
|
||||
lista vår over underentreprenører. Tømrere, murere og lærlinger som
|
||||
lurer på om vi trenger folk.
|
||||
|
||||
what_we_keep_track_of: >
|
||||
Henvendelser: de kommer inn, vi avtaler og drar på befaring, vi
|
||||
sender tilbud, og så vinner vi jobben eller taper den. Noen ganger
|
||||
er det rett og slett ikke noe for oss, og da sier vi det med en gang.
|
||||
Underentreprenører: de melder seg, vi sjekker organisasjonsnummer,
|
||||
sentral godkjenning, forsikring og at folka har HMS-kort. Ofte
|
||||
mangler det papirer og vi må etterlyse dem. Så blir de godkjent
|
||||
eller avslått.
|
||||
Jobbsøknader: vi leser dem, kaller inn noen til intervju, og
|
||||
ansetter eller takker nei.
|
||||
Avvik og uønskede hendelser på byggeplass: løse rekkverk,
|
||||
nestenulykker, feil materialer levert. Noen melder fra, HMS-ansvarlig
|
||||
bestemmer tiltak, og lukker saken når det er utbedret.
|
||||
|
||||
who_is_involved: >
|
||||
To prosjektledere tar seg av henvendelser, underentreprenører og
|
||||
ansettelser. En HMS-ansvarlig tar alt som meldes fra byggeplass.
|
||||
Mannskapet, både våre egne og underentreprenørenes folk, er de som
|
||||
står på plassen og melder fra. De sitter med telefonen, har hansker
|
||||
på, og fyller ikke ut lange skjemaer.
|
||||
|
||||
what_slows_us_down: >
|
||||
Henvendelser kommer på telefon, e-post og SMS og blir borte. Vi vet
|
||||
aldri sikkert hvilke underentreprenører som har papirene i orden.
|
||||
Avvik blir nevnt i lunsjen og glemt.
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
# Tomter Vel, slik en i styret ville fylt det ut. Det som står om
|
||||
# velet er hentet fra tomtervel.no (komiteer, kontingent, medlemstall,
|
||||
# arrangementer); det som står om deling av utstyr er et forslag til
|
||||
# en ny tjeneste.
|
||||
business: Tomter Vel
|
||||
contact: { name: Styret i Tomter Vel, email: post@tomtervel.no }
|
||||
language: no
|
||||
|
||||
what_we_do: >
|
||||
Velforeningen for Tomter, stiftet i 1947. Vi er et styre på sju og
|
||||
sju komiteer som alle drives av folk på fritida: arrangementer
|
||||
(17. mai-frokost, juletregranstenning, skøytedag), elvestien langs
|
||||
Hobølelva, to lekeplasser vi holder i stand og får kontrollert hvert
|
||||
år, høringssvar til kommunen, miljøgata i sentrum, pendlerforhold
|
||||
mot Ruter, og trafikkforhold. 157 husstander betaler kontingent på
|
||||
250 kroner i året.
|
||||
|
||||
who_comes_to_us: >
|
||||
Husstander som vil bli medlem, eller som har flyttet eller byttet
|
||||
e-post og vil at vi skal ha det riktig. Folk som har sett noe i
|
||||
nabolaget som ikke er som det skal: en farlig sving, en huske som
|
||||
henger i én kjetting, en råtten planke på stien. Beboere som vil
|
||||
si sin mening om en sak kommunen har på høring. Folk som vil hjelpe
|
||||
til på et arrangement eller en dugnad, eller sitte i en komité.
|
||||
Og naboer som har en tilhenger, en stige eller en hekksaks som står
|
||||
ubrukt, og naboer som trenger å låne en. Eldre og nyopererte som
|
||||
trenger en hånd med snømåking, handling eller en skyss, og naboer
|
||||
som gjerne stiller opp hvis noen spør.
|
||||
|
||||
what_we_keep_track_of: >
|
||||
Medlemskap: en husstand melder seg inn, kassereren ser at
|
||||
kontingenten er betalt, og noen melder seg ut når de flytter.
|
||||
Meldinger om trafikk: noen melder fra, trafikkomiteen tar det opp
|
||||
med kommunen eller veieier, og det blir ordnet eller avvist.
|
||||
Feil på lekeplass og sti: noen melder fra, komiteen tar tak i det
|
||||
og utbedrer det.
|
||||
Høringsinnspill: en beboer sender inn, styret tar det med i svaret
|
||||
eller lar være.
|
||||
Frivillige: noen tilbyr seg, arrangementskomiteen tar kontakt og
|
||||
setter dem opp, eller takker nei.
|
||||
Komitésøknader: noen vil være med, styret plasserer dem eller sier
|
||||
nei.
|
||||
Utlegg: en i en komité har lagt ut for noe, kassereren godkjenner og
|
||||
betaler ut, eller avviser.
|
||||
Nabohjelp: noen ber om en hånd, nabohjelpsgruppa finner en som kan,
|
||||
og den som fikk hjelp sier fra når det er ordnet. Naboer som vil
|
||||
hjelpe melder seg, og kan trekke seg igjen.
|
||||
Deling av utstyr: en nabo melder at de har noe å låne ut, eller
|
||||
trenger å låne noe; styret legger det ut på oppslagstavla og tar
|
||||
det ned når det er gjort.
|
||||
|
||||
who_is_involved: >
|
||||
Kassereren har medlemskap og utlegg. Trafikkomiteen har
|
||||
trafikkmeldinger, lekeplasskomiteen har feil på anlegg,
|
||||
arrangementskomiteen har frivillige. Styret har høringsinnspill,
|
||||
komitésøknader og oppslagstavla. Nabohjelpsgruppa kobler dem som
|
||||
trenger hjelp med dem som kan. Komiteene leverer utlegg.
|
||||
|
||||
what_slows_us_down: >
|
||||
Medlemslista er en bankutskrift og et regneark. Ting som meldes på
|
||||
Facebook eller i butikken blir husket av den som hørte det. Folk
|
||||
som tilbyr seg å hjelpe får svar sent eller aldri.
|
||||
+487
@@ -0,0 +1,487 @@
|
||||
# A building authority, written by hand to find where the plan language
|
||||
# stops. 14 needs, 7 roles, 12 buckets, two needs sharing a bucket in
|
||||
# each direction (public and internal), a decision no case officer may
|
||||
# sign, a group outside the building that moves records and nothing
|
||||
# else, a stage a deadline moves rather than a person, and four things
|
||||
# the plan language cannot say at all - each named in the run's README
|
||||
# rather than smuggled past.
|
||||
business: Vestmark kommune - Building and Planning
|
||||
language: en
|
||||
contact: { name: Solveig Hauge, email: byggesak@vestmark.example }
|
||||
mail: { from: "Vestmark Building and Planning <byggesak@vestmark.example>", reply_to: byggesak@vestmark.example }
|
||||
about: >
|
||||
The building authority for twenty-one thousand people. Anything built,
|
||||
demolished, divided or changed in use is decided here: the drawings are
|
||||
checked against the zoning map, the neighbours and the other
|
||||
authorities have their say, and then the head of section signs. The
|
||||
same office inspects what is actually built, signs off finished work,
|
||||
and deals with building nobody applied for.
|
||||
|
||||
# Two features, two roles, no button. The authority exists for the
|
||||
# person who wants to build; the next one it serves is the neighbour
|
||||
# who finds out what is planned next door. Both have a move of their
|
||||
# own after sending: the applicant withdraws, the objector withdraws,
|
||||
# and both buckets are open to read.
|
||||
does:
|
||||
- id: we-decide-what-may-be-built
|
||||
for: small-works-application
|
||||
text: >
|
||||
Everything built in Vestmark is decided here. You send the drawings,
|
||||
the neighbours and the road, fire and heritage authorities are heard,
|
||||
and you get a written decision you can hold us to.
|
||||
- id: your-neighbours-case-is-readable
|
||||
for: objection
|
||||
text: >
|
||||
If a notice landed in your postbox, the case behind it is open to
|
||||
read here, and what you write to us has to be answered by name in
|
||||
the decision.
|
||||
|
||||
doors:
|
||||
- id: want-to-build
|
||||
who: an owner or a firm with something to build, divide or change
|
||||
- id: building-near-me
|
||||
who: someone who lives next to what is being built
|
||||
|
||||
groups:
|
||||
- { id: front_desk, label: Front desk }
|
||||
- { id: case_officers, label: Case officers }
|
||||
- { id: section_head, label: Head of section }
|
||||
- { id: inspectors, label: Inspectors }
|
||||
- { id: appeals_board, label: Appeals board, invited_by: [section_head] }
|
||||
- { id: agencies, label: Hearing bodies, invited_by: [case_officers, section_head] }
|
||||
- { id: approved_firms, label: Approved firms, invited_by: [section_head] }
|
||||
invites_by: [section_head, case_officers]
|
||||
|
||||
needs:
|
||||
# --- the public: something they want to build ----------------------
|
||||
- id: pre-application-meeting
|
||||
door: want-to-build
|
||||
who: someone with an idea for a building and no drawings yet
|
||||
wants: to hear what we will allow before paying an architect
|
||||
lands_in: meetings
|
||||
handled_by: case_officers
|
||||
stages: [open, scheduled, met, advised, cancelled]
|
||||
done_when: [advised, cancelled]
|
||||
success: [advised]
|
||||
# They can call it off themselves; the front desk does it when they ring.
|
||||
moves_by: { cancelled: [submitter, front_desk] }
|
||||
watched_by: [front_desk]
|
||||
mails: { open: submitter, scheduled: submitter, advised: submitter }
|
||||
stages_text: { met: we have met, advised: written advice sent }
|
||||
max_fields: 5
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: email, type: email }
|
||||
- { name: property_address }
|
||||
- { name: what_you_want, type: textarea }
|
||||
- { name: phone, type: tel, optional: true }
|
||||
- { name: site, type: location, optional: true }
|
||||
|
||||
- id: small-works-application
|
||||
door: want-to-build
|
||||
who: an owner applying for something small enough to file themselves
|
||||
wants: permission to build it, and to know where the case stands
|
||||
lands_in: applications
|
||||
handled_by: case_officers
|
||||
stages: [open, incomplete, complete, on_hearing, recommended, approved, approved_with_conditions, refused, withdrawn]
|
||||
done_when: [approved, approved_with_conditions, refused, withdrawn]
|
||||
success: [approved, approved_with_conditions]
|
||||
skippable: [incomplete]
|
||||
# A case is sent back for the drawing it was missing, and the
|
||||
# hearing turns things up that send it back again. It may be
|
||||
# withdrawn from anywhere, and refused only once we have seen
|
||||
# everything: not on the day it arrives.
|
||||
reached_from:
|
||||
incomplete: [open, complete, on_hearing]
|
||||
refused: [complete, on_hearing, recommended]
|
||||
# No case officer signs their own case: only the head of section
|
||||
# moves one into a decision. The applicant answers a request for
|
||||
# missing papers, and may withdraw right up to the signature.
|
||||
moves_by:
|
||||
complete: [submitter, case_officers]
|
||||
approved: [section_head]
|
||||
approved_with_conditions: [section_head]
|
||||
refused: [section_head]
|
||||
withdrawn: [submitter]
|
||||
watched_by: [public, front_desk, inspectors, section_head]
|
||||
mails:
|
||||
open: submitter
|
||||
incomplete: submitter
|
||||
on_hearing: submitter
|
||||
approved: submitter
|
||||
approved_with_conditions: submitter
|
||||
refused: submitter
|
||||
stages_text:
|
||||
incomplete: papers missing
|
||||
complete: papers complete
|
||||
on_hearing: out to the neighbours and the agencies
|
||||
recommended: recommendation written
|
||||
approved_with_conditions: approved on conditions
|
||||
max_fields: 6
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: property_address }
|
||||
- { name: property_number }
|
||||
- { name: what_is_planned, type: textarea }
|
||||
- { name: neighbours_notified, type: select, options: ["Yes", Not yet] }
|
||||
- { name: site, type: location, optional: true }
|
||||
- { name: drawings_url, optional: true }
|
||||
|
||||
- id: exemption-request
|
||||
door: want-to-build
|
||||
who: someone whose plans break a rule in the zoning map
|
||||
wants: to be allowed it anyway, with reasons on the record
|
||||
requires: An application already with us, and the case number from its receipt.
|
||||
lands_in: exemptions
|
||||
handled_by: case_officers
|
||||
stages: [open, county_asked, county_answered, recommended, granted, denied, withdrawn]
|
||||
done_when: [granted, denied, withdrawn]
|
||||
success: [granted]
|
||||
# The county answers from outside the building; nothing may be
|
||||
# granted before it has. The head of section signs, as for a permit.
|
||||
moves_by:
|
||||
county_answered: [agencies]
|
||||
granted: [section_head]
|
||||
denied: [section_head]
|
||||
withdrawn: [submitter]
|
||||
watched_by: [public, section_head]
|
||||
mails: { open: submitter, county_asked: submitter, granted: submitter, denied: submitter }
|
||||
stages_text: { county_asked: with the county, county_answered: the county has answered }
|
||||
max_fields: 4
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: case_number }
|
||||
- { name: which_rule }
|
||||
- { name: why_it_should_be_allowed, type: textarea }
|
||||
- { name: site, type: location, optional: true }
|
||||
|
||||
- id: completion-request
|
||||
door: want-to-build
|
||||
who: an owner or firm whose building work is finished
|
||||
wants: the certificate that lets the building be used
|
||||
requires: A case number, and the work finished or close enough to move in.
|
||||
lands_in: completions
|
||||
handled_by: case_officers
|
||||
stages: [open, checked, temporary_permission, certificate_issued, refused]
|
||||
done_when: [certificate_issued, refused]
|
||||
success: [certificate_issued]
|
||||
# Most go straight through; the ones who want to move in before the
|
||||
# last of it is done detour past a temporary permission.
|
||||
skippable: [temporary_permission]
|
||||
moves_by:
|
||||
temporary_permission: [section_head]
|
||||
certificate_issued: [section_head]
|
||||
refused: [section_head]
|
||||
watched_by: [public, inspectors]
|
||||
turned_down_from: [open, checked]
|
||||
mails: { open: submitter, temporary_permission: submitter, certificate_issued: submitter, refused: submitter }
|
||||
stages_text: { checked: checked against the inspections, temporary_permission: temporary permission to use, certificate_issued: certificate issued }
|
||||
max_fields: 5
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: case_number }
|
||||
- { name: property_address }
|
||||
- { name: work_finished, type: date }
|
||||
- { name: asking_for, type: select, options: [Completion certificate, Temporary permission to move in] }
|
||||
- { name: what_is_outstanding, type: textarea, optional: true }
|
||||
|
||||
# --- the public: someone else is building ---------------------------
|
||||
- id: objection
|
||||
door: building-near-me
|
||||
who: a neighbour who got a notice about what is planned next door
|
||||
wants: what they think on the record, and answered in the decision
|
||||
requires: The notice that came in the post, which has the case number on it.
|
||||
lands_in: objections
|
||||
handled_by: case_officers
|
||||
stages: [open, registered, answered_by_applicant, addressed, withdrawn]
|
||||
done_when: [addressed, withdrawn]
|
||||
success: [addressed]
|
||||
# The firm that filed the case answers the objection; the neighbour
|
||||
# can take it back if they are satisfied.
|
||||
moves_by: { answered_by_applicant: [approved_firms, case_officers], withdrawn: [submitter] }
|
||||
watched_by: [public, section_head]
|
||||
mails: { open: submitter, answered_by_applicant: submitter, addressed: submitter }
|
||||
stages_text: { registered: on the case file, answered_by_applicant: the applicant has answered, addressed: answered in the decision }
|
||||
max_fields: 4
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: case_number }
|
||||
- { name: your_property }
|
||||
- { name: your_objection, type: textarea }
|
||||
|
||||
- id: case-status-enquiry
|
||||
door: building-near-me
|
||||
who: someone waiting on a case and getting nothing back
|
||||
wants: to be told where it actually stands
|
||||
lands_in: enquiries
|
||||
handled_by: front_desk
|
||||
stages: [open, in_hand, answered]
|
||||
done_when: [answered]
|
||||
success: [answered]
|
||||
moves_by: { in_hand: [front_desk, case_officers] }
|
||||
watched_by: [case_officers]
|
||||
mails: { open: submitter, answered: submitter }
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: case_number_or_address }
|
||||
- { name: what_you_want_to_know, type: textarea }
|
||||
|
||||
- id: illegal-building-report
|
||||
door: building-near-me
|
||||
who: someone who can see building going up that nobody was told about
|
||||
wants: us to go and look, and to hear that we did
|
||||
lands_in: illegal_building
|
||||
handled_by: inspectors
|
||||
stages: [open, inspected, owner_asked, explained, resolved, fined, dropped]
|
||||
done_when: [resolved, fined, dropped]
|
||||
success: [resolved, dropped]
|
||||
# An inspector goes and looks; the letter to the owner is a case
|
||||
# officer's, and so is the fine.
|
||||
moves_by: { owner_asked: [case_officers], explained: [case_officers], fined: [section_head] }
|
||||
watched_by: [case_officers, section_head]
|
||||
turned_down_from: [open, inspected]
|
||||
mails: { open: submitter, inspected: submitter, resolved: submitter, dropped: submitter }
|
||||
stages_text: { owner_asked: the owner has been written to, explained: the owner has answered, dropped: nothing to pursue }
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: address }
|
||||
- { name: what_you_saw, type: textarea }
|
||||
- { name: where, type: location, optional: true }
|
||||
|
||||
# --- the public: after a decision ------------------------------------
|
||||
- id: appeal
|
||||
who: anyone with an interest who will not accept a decision of ours
|
||||
wants: the decision looked at again, by us and then by the board
|
||||
requires: A decision from us less than three weeks old, and its case number.
|
||||
lands_in: appeals
|
||||
handled_by: case_officers
|
||||
stages: [open, reconsidered, changed_by_us, before_the_board, upheld, overturned, withdrawn]
|
||||
done_when: [changed_by_us, upheld, overturned, withdrawn]
|
||||
success: [changed_by_us, upheld]
|
||||
# If we change our own mind that is the end of it, and it happens
|
||||
# while we are looking - not after the board has the case. The
|
||||
# board can only decide what has reached it.
|
||||
reached_from:
|
||||
changed_by_us: [reconsidered]
|
||||
upheld: [before_the_board]
|
||||
overturned: [before_the_board]
|
||||
# We look at ourselves first and the head of section decides whether
|
||||
# we were wrong. What we will not change goes to seven elected
|
||||
# people who meet once a month and move nothing else in this office.
|
||||
moves_by:
|
||||
changed_by_us: [section_head]
|
||||
before_the_board: [section_head]
|
||||
upheld: [appeals_board]
|
||||
overturned: [appeals_board]
|
||||
withdrawn: [submitter]
|
||||
watched_by: [public, front_desk, section_head]
|
||||
mails:
|
||||
open: submitter
|
||||
reconsidered: submitter
|
||||
changed_by_us: submitter
|
||||
before_the_board: submitter
|
||||
upheld: submitter
|
||||
overturned: submitter
|
||||
stages_text:
|
||||
reconsidered: we are looking at it again
|
||||
changed_by_us: we changed our own decision
|
||||
before_the_board: with the appeals board
|
||||
upheld: the board kept our decision
|
||||
overturned: the board overturned us
|
||||
max_fields: 5
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: case_number }
|
||||
- { name: property }
|
||||
- { name: what_you_disagree_with, type: textarea }
|
||||
- { name: your_interest, type: select, options: [I applied, I am a neighbour, Other] }
|
||||
|
||||
# --- the public: a firm that wants to file here -----------------------
|
||||
- id: firm-approval
|
||||
who: an architect or engineering firm that files for its clients
|
||||
wants: to be on the list, and then to file without asking again
|
||||
lands_in: firms
|
||||
handled_by: case_officers
|
||||
stages: [open, papers_missing, checked, approved, declined]
|
||||
done_when: [approved, declined]
|
||||
success: [approved]
|
||||
skippable: [papers_missing]
|
||||
moves_by: { checked: [submitter, case_officers], approved: [section_head], declined: [section_head] }
|
||||
watched_by: [section_head, front_desk]
|
||||
turned_down_from: [open, papers_missing, checked]
|
||||
mails: { open: submitter, papers_missing: submitter, approved: submitter, declined: submitter }
|
||||
stages_text: { papers_missing: waiting on papers, checked: papers checked }
|
||||
max_fields: 6
|
||||
collects:
|
||||
- { name: firm_name }
|
||||
- { name: org_number }
|
||||
- { name: email, type: email }
|
||||
- { name: qualified_for, type: select, multiple: true, options: [Design, Execution, Independent control, Site management] }
|
||||
- { name: insurance_expires, type: date }
|
||||
- { name: insurance_document, optional: true }
|
||||
|
||||
# --- approved firms ----------------------------------------------------
|
||||
- id: permit-application
|
||||
who: an approved firm filing on behalf of an owner
|
||||
wants: a decision inside twelve weeks, and to know when the clock stops
|
||||
enters_as: approved_firms
|
||||
lands_in: applications
|
||||
handled_by: case_officers
|
||||
stages: [open, incomplete, complete, on_hearing, recommended, approved, approved_with_conditions, refused, withdrawn]
|
||||
done_when: [approved, approved_with_conditions, refused, withdrawn]
|
||||
success: [approved, approved_with_conditions]
|
||||
skippable: [incomplete]
|
||||
# A case is sent back for the drawing it was missing, and the
|
||||
# hearing turns things up that send it back again. It may be
|
||||
# withdrawn from anywhere, and refused only once we have seen
|
||||
# everything: not on the day it arrives.
|
||||
reached_from:
|
||||
incomplete: [open, complete, on_hearing]
|
||||
refused: [complete, on_hearing, recommended]
|
||||
moves_by:
|
||||
complete: [submitter, case_officers]
|
||||
approved: [section_head]
|
||||
approved_with_conditions: [section_head]
|
||||
refused: [section_head]
|
||||
withdrawn: [submitter]
|
||||
watched_by: [public, front_desk, inspectors, section_head]
|
||||
mails:
|
||||
open: submitter
|
||||
incomplete: submitter
|
||||
on_hearing: submitter
|
||||
approved: submitter
|
||||
approved_with_conditions: submitter
|
||||
refused: submitter
|
||||
stages_text:
|
||||
incomplete: papers missing
|
||||
complete: papers complete
|
||||
on_hearing: out to the neighbours and the agencies
|
||||
recommended: recommendation written
|
||||
approved_with_conditions: approved on conditions
|
||||
max_fields: 6
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: property_address }
|
||||
- { name: property_number }
|
||||
- { name: what_is_planned, type: textarea }
|
||||
- { name: neighbours_notified, type: select, options: ["Yes", Not yet] }
|
||||
- { name: site, type: location, optional: true }
|
||||
- { name: drawings_url, optional: true }
|
||||
|
||||
# --- the front desk -----------------------------------------------------
|
||||
- id: log-counter-enquiry
|
||||
who: whoever is on the counter with a queue and a caller on the line
|
||||
wants: the question written down and sent to whoever has the case
|
||||
enters_as: front_desk
|
||||
lands_in: enquiries
|
||||
handled_by: front_desk
|
||||
stages: [open, in_hand, answered]
|
||||
done_when: [answered]
|
||||
success: [answered]
|
||||
moves_by: { in_hand: [front_desk, case_officers] }
|
||||
watched_by: [case_officers]
|
||||
mails: { open: submitter, answered: submitter }
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: case_number_or_address }
|
||||
- { name: what_you_want_to_know, type: textarea }
|
||||
|
||||
# --- case officers ------------------------------------------------------
|
||||
- id: request-hearing
|
||||
who: a case officer sending a case out to the authority that must see it
|
||||
wants: an answer by the deadline, or a record that none came
|
||||
enters_as: case_officers
|
||||
lands_in: hearings
|
||||
handled_by: case_officers
|
||||
stages: [open, answered, no_answer, cancelled]
|
||||
done_when: [answered, no_answer, cancelled]
|
||||
success: [answered]
|
||||
# This is how an agency sees what it has been asked. Nobody presses
|
||||
# a button for the deadline passing.
|
||||
moves_by: { answered: [agencies] }
|
||||
watched_by: [agencies, section_head, front_desk]
|
||||
attended_by: >
|
||||
the six-week deadline: when it passes with nothing from the agency
|
||||
the case goes to no_answer and the application goes on without one
|
||||
stages_text: { no_answer: the deadline passed with no answer }
|
||||
max_fields: 4
|
||||
collects:
|
||||
- { name: case_number }
|
||||
- { name: which_authority, type: select, options: [Road authority, Fire service, Heritage office, The county] }
|
||||
- { name: what_we_ask, type: textarea }
|
||||
- { name: answer_by, type: date }
|
||||
- { name: site, type: location, optional: true }
|
||||
|
||||
# --- the authorities outside the building --------------------------------
|
||||
- id: hearing-answer
|
||||
who: a road, fire, heritage or county officer who has been asked about a case
|
||||
wants: their answer on the file, in their own words
|
||||
requires: The hearing letter we sent you, which has the case number on it.
|
||||
enters_as: agencies
|
||||
lands_in: hearing_answers
|
||||
handled_by: case_officers
|
||||
stages: [open, read, followed, set_aside]
|
||||
done_when: [followed, set_aside]
|
||||
success: [followed]
|
||||
watched_by: [section_head, front_desk]
|
||||
stages_text: { read: read by the case officer, followed: followed in the decision, set_aside: set aside with reasons }
|
||||
max_fields: 4
|
||||
collects:
|
||||
- { name: case_number }
|
||||
- { name: which_authority, type: select, options: [Road authority, Fire service, Heritage office, The county] }
|
||||
- { name: our_answer, type: select, options: [No objection, Objection, Conditions required] }
|
||||
- { name: what_we_say, type: textarea }
|
||||
|
||||
# --- inspectors -----------------------------------------------------------
|
||||
- id: inspection-finding
|
||||
who: an inspector on a scaffold with gloves on and the wind blowing
|
||||
wants: what they found logged before they climb down
|
||||
enters_as: inspectors
|
||||
lands_in: inspections
|
||||
handled_by: inspectors
|
||||
stages: [open, as_approved, deviation, put_right, escalated]
|
||||
done_when: [as_approved, put_right, escalated]
|
||||
success: [as_approved, put_right]
|
||||
# Anything that has to become a fine or a refusal leaves the
|
||||
# inspectors and becomes a case officer's problem.
|
||||
moves_by: { escalated: [case_officers, section_head] }
|
||||
watched_by: [case_officers, section_head]
|
||||
stages_text: { as_approved: built as approved, deviation: built differently, put_right: put right, escalated: handed to a case officer }
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: case_number }
|
||||
- { name: site_address }
|
||||
- { name: what_i_found, type: textarea }
|
||||
- { name: where, type: location, optional: true }
|
||||
|
||||
# Held out from every model that writes words.
|
||||
# arriving with one real thing, in their own register: a homeowner who
|
||||
# has never read a regulation, a firm that files for a living, an
|
||||
# inspector on a roof in the wind, a politician reading a bundle.
|
||||
personas:
|
||||
- { id: garage-owner, need: pre-application-meeting, text: "We want to put a double garage where the old shed is. Before I pay an architect I'd like to know whether you'll even allow it, because the neighbour says it's too close to the road." }
|
||||
- { id: shop-to-flats, need: pre-application-meeting, text: "I own the old grocery on Torget and want to make four flats out of it. There are a lot of questions - parking, fire, the facade is listed. Can we sit down with someone?" }
|
||||
- { id: firm-files-extension, need: permit-application, text: "We are the responsible applicant for an extension at Bjorkeveien 14. Drawings, site plan and the neighbour notices are all ready. We file maybe forty of these a year." }
|
||||
- { id: owner-small-window, need: permit-application, text: "I want to put a dormer window in my roof. The man at the counter said I have to apply even though it's small." }
|
||||
- { id: missing-drawings, need: permit-application, text: "You wrote that our section drawing is missing and the case is on hold. I've got it here now, where do I send it so the clock starts again?" }
|
||||
- { id: too-close-to-boundary, need: exemption-request, text: "The garage ends up one and a half metres from the boundary and the plan says four. We are asking you to allow it anyway - the ground falls away steeply everywhere else on the plot." }
|
||||
- { id: neighbour-view, need: objection, text: "I got a notice about the extension at number 14. It takes the afternoon sun off my entire terrace and I want that on the record before you decide anything." }
|
||||
- { id: neighbour-parking, need: objection, text: "The flats they want to build in the old grocery have four parking places for four flats and everyone here already parks on the street. I object." }
|
||||
- { id: road-authority, need: hearing-answer, text: "Regarding your case 2026/418: the access onto the county road is within the sight line and we cannot accept it as drawn. Our formal reply is attached." }
|
||||
- { id: fire-service, need: hearing-answer, text: "We have looked at the conversion on Torget. We have no objection provided the stairwell is upgraded. Reference your case 2026/501." }
|
||||
- { id: refused-applicant, need: appeal, text: "You refused our exemption on the ninth. We don't accept the reasoning - you've allowed the same thing twice in the same street. We're appealing." }
|
||||
- { id: neighbour-appeals, need: appeal, text: "You approved the extension next door even though I objected. I'm appealing the decision. What do I need to send?" }
|
||||
- { id: board-member, need: appeal, text: "I sit on the appeals board. I need the case, our own decision, and what the neighbours wrote, before Tuesday." }
|
||||
- { id: inspector-on-roof, need: inspection-finding, text: "I'm up on the scaffold at Bjorkeveien. The fire wall isn't built to the drawing at all. I've got gloves on and it's blowing. I want this logged before I climb down." }
|
||||
- { id: inspector-all-good, need: inspection-finding, text: "Been out at Torget. Everything is as approved. Nothing to report but I have to record that I was there." }
|
||||
- { id: firm-wants-certificate, need: completion-request, text: "The work at Bjorkeveien 14 is finished and inspected. We're asking for the completion certificate so the owners can get their mortgage released." }
|
||||
- { id: wants-to-move-in, need: completion-request, text: "The house is done apart from the outside steps, which we can't pour until spring. The family has sold their flat. Can we get a temporary permission to move in?" }
|
||||
- { id: something-behind-fence, need: illegal-building-report, text: "There's a large structure going up behind the fence at Solbakken 7. Nobody has had a notice about it and it's been going on for two weeks." }
|
||||
- { id: owner-explains, need: illegal-building-report, text: "I got your letter about the terrace. I genuinely did not know it needed an application, it's been there since we moved in. What happens now?" }
|
||||
- { id: new-firm, need: firm-approval, text: "We are a three-person architecture firm that has just started. We want to be approved so we can file applications for our clients in your municipality." }
|
||||
- { id: firm-insurance-lapsed, need: firm-approval, text: "You wrote that our liability insurance certificate has expired. We have renewed it, here it is." }
|
||||
- { id: counter-phone-call, need: log-counter-enquiry, text: "A woman rang about the case behind her house. Wants to know where it stands. I'm at the counter and there's a queue - I need to write it down and send it to whoever has that case." }
|
||||
- { id: where-is-my-case, need: case-status-enquiry, text: "I sent in my application five weeks ago and I've heard nothing. Is anyone looking at it? Is it in the six weeks with the neighbours or is it waiting on me?" }
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
# 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 that had to be tiered.
|
||||
business: Nordvik Bygg
|
||||
language: en
|
||||
contact: { name: Ingrid Nordvik, email: ingrid@nordvikbygg.example }
|
||||
about: >
|
||||
Twelve people who survey old buildings, draw up rehabilitation plans,
|
||||
handle the permit application, and do the building work with their
|
||||
own carpenters plus subcontractors for electrical, plumbing and
|
||||
scaffolding. Project managers win and run the jobs, site managers run
|
||||
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
|
||||
handled_by: project_managers
|
||||
stages: [open, surveyed, quoted, won, lost]
|
||||
done_when: [won, lost]
|
||||
success: [won]
|
||||
# Whoever went to the building marks it surveyed; site managers
|
||||
# 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 }
|
||||
- { name: address }
|
||||
- { name: problem, type: textarea }
|
||||
- { 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
|
||||
handled_by: project_managers
|
||||
stages: [open, surveyed, quoted, won, lost]
|
||||
done_when: [won, lost]
|
||||
success: [won]
|
||||
# Whoever went to the building marks it surveyed; site managers
|
||||
# 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 }
|
||||
- { name: address }
|
||||
- { name: project, type: textarea }
|
||||
- { 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
|
||||
handled_by: project_managers
|
||||
stages: [open, inspected, accepted, fixed, rejected]
|
||||
done_when: [fixed, rejected]
|
||||
success: [fixed]
|
||||
# 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 }
|
||||
- { name: address }
|
||||
- { name: fault, type: textarea }
|
||||
- { name: handed_over, type: date, optional: true }
|
||||
|
||||
- id: neighbour-complaint
|
||||
who: someone living or working next to one of our building sites
|
||||
wants: the noise, dust or blocked access dealt with, and an answer
|
||||
lands_in: complaints
|
||||
handled_by: site_managers
|
||||
stages: [open, answered]
|
||||
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
|
||||
handled_by: project_managers
|
||||
stages: [open, awaiting_papers, approved, declined]
|
||||
done_when: [approved, declined]
|
||||
success: [approved]
|
||||
watched_by: [site_managers]
|
||||
skippable: [awaiting_papers]
|
||||
max_fields: 5
|
||||
collects:
|
||||
- { name: company }
|
||||
- { name: registration_number }
|
||||
- { name: trade, type: select, options: [Electrical, Plumbing, Scaffolding, Sheet metal, Other] }
|
||||
- { name: contact_email, type: email }
|
||||
- { name: insurance_confirmed, type: select, options: ["Yes", Not yet] }
|
||||
- { 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
|
||||
handled_by: project_managers
|
||||
stages: [open, interviewing, offered, hired, declined]
|
||||
done_when: [hired, declined]
|
||||
success: [hired]
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: phone, type: tel }
|
||||
- { name: trade, type: select, options: [Carpenter, Bricklayer, Apprentice, Other] }
|
||||
- { name: experience, type: textarea, optional: true }
|
||||
|
||||
# --- clients with a job under way ---------------------------------
|
||||
- id: change-request
|
||||
who: a client whose job is under way and who wants something changed
|
||||
wants: a price for the change, and the change done if they accept it
|
||||
enters_as: clients
|
||||
lands_in: change_orders
|
||||
handled_by: project_managers
|
||||
stages: [open, priced, approved, completed, declined]
|
||||
done_when: [completed, declined]
|
||||
success: [completed]
|
||||
# The project manager prices it, the client says yes or no through
|
||||
# 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 }
|
||||
- { name: change, type: textarea }
|
||||
- { name: needed_by, type: date, optional: true }
|
||||
|
||||
# --- project managers ---------------------------------------------
|
||||
- id: log-phone-enquiry
|
||||
who: a project manager who just took a call or a text about a building
|
||||
wants: the enquiry written down before it gets lost
|
||||
enters_as: project_managers
|
||||
lands_in: enquiries
|
||||
handled_by: project_managers
|
||||
stages: [open, surveyed, quoted, won, lost]
|
||||
done_when: [won, lost]
|
||||
success: [won]
|
||||
# Whoever went to the building marks it surveyed; site managers
|
||||
# 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 }
|
||||
- { name: address }
|
||||
- { name: problem, type: textarea }
|
||||
|
||||
- id: post-job-request
|
||||
who: a project manager with work to hand to a subcontractor
|
||||
wants: approved subcontractors to see the job and answer with a price
|
||||
enters_as: project_managers
|
||||
lands_in: job_requests
|
||||
handled_by: project_managers
|
||||
stages: [open, awarded, withdrawn]
|
||||
done_when: [awarded, withdrawn]
|
||||
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] }
|
||||
- { name: work, type: textarea }
|
||||
- { name: start, type: date }
|
||||
|
||||
# --- approved subcontractors --------------------------------------
|
||||
- id: submit-bid
|
||||
who: an approved subcontractor who has seen a job they can take
|
||||
wants: to say yes with a price and a start date
|
||||
enters_as: subcontractors
|
||||
lands_in: bids
|
||||
handled_by: project_managers
|
||||
stages: [open, shortlisted, accepted, declined]
|
||||
done_when: [accepted, declined]
|
||||
success: [accepted]
|
||||
watched_by: [site_managers]
|
||||
skippable: [shortlisted]
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: job }
|
||||
- { name: price }
|
||||
- { name: can_start, type: date }
|
||||
|
||||
# --- on site --------------------------------------------------------
|
||||
- id: report-site-issue
|
||||
who: anyone on site, ours or a subcontractor's, on a phone with gloves on
|
||||
wants: to report a hazard, a near miss or wrong materials before they forget
|
||||
enters_as: crew
|
||||
lands_in: site_issues
|
||||
handled_by: safety_officer
|
||||
stages: [open, in_hand, closed]
|
||||
done_when: [closed]
|
||||
success: [closed]
|
||||
# A site manager can take an issue in hand on the spot; only the
|
||||
# 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 }
|
||||
- { name: what_happened, type: textarea }
|
||||
|
||||
- id: order-materials
|
||||
who: a carpenter or bricklayer who is about to run out of something
|
||||
wants: it ordered and on site before work stops
|
||||
enters_as: crew
|
||||
lands_in: material_orders
|
||||
handled_by: site_managers
|
||||
stages: [open, ordered, delivered, refused]
|
||||
done_when: [delivered, refused]
|
||||
success: [delivered]
|
||||
# The crew confirms it arrived.
|
||||
moves_by: { delivered: [crew, site_managers] }
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: site_address }
|
||||
- { name: what, type: textarea }
|
||||
- { name: needed_by, type: date }
|
||||
|
||||
- id: safety-round-finding
|
||||
who: the safety officer walking a site on the weekly round
|
||||
wants: each thing found written down where the reported issues already are
|
||||
enters_as: safety_officer
|
||||
lands_in: site_issues
|
||||
handled_by: safety_officer
|
||||
stages: [open, in_hand, closed]
|
||||
done_when: [closed]
|
||||
success: [closed]
|
||||
# A site manager can take an issue in hand on the spot; only the
|
||||
# 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 }
|
||||
- { name: what_happened, type: textarea }
|
||||
|
||||
# No model that writes words ever sees these.
|
||||
personas:
|
||||
- { id: housing-board-damp, need: survey-enquiry, text: "I chair the board of a housing cooperative from the seventies. Two ground-floor flats have damp in the walls and we don't know if it's drainage or the facade. We need someone to tell us." }
|
||||
- { id: buyer-before-purchase, need: survey-enquiry, text: "We are about to buy an old timber house. Before we sign we want a professional to go through it and tell us what is wrong with it." }
|
||||
- { id: attic-conversion, need: build-enquiry, text: "We want to turn our attic into two bedrooms and a bathroom. We need drawings and someone who handles the application to the municipality." }
|
||||
- { id: shop-to-flat, need: build-enquiry, text: "I own a former shop on the ground floor and want to make it a flat. I have no idea what is allowed. Can you sort that out and give me a price?" }
|
||||
- { id: leaking-bathroom, need: warranty-claim, text: "You redid our bathroom two years ago. Now water is coming through the ceiling of the flat below. I want you to come and fix it." }
|
||||
- { id: cracked-render, need: warranty-claim, text: "The render you put on our gable wall last summer has cracked right across. That can't be right after one winter." }
|
||||
- { id: noisy-mornings, need: neighbour-complaint, text: "I live next door to the block you are working on. You start drilling at half past six every morning and I have a baby. Who do I talk to?" }
|
||||
- { id: blocked-driveway, need: neighbour-complaint, text: "Your skip and a van have been parked across the entrance to our shop's loading bay for three days. We can't get deliveries." }
|
||||
- { id: electrician-firm, need: subcontractor-application, text: "We are a four-person electrical firm, fully certified. We would like to get on your list so you call us when you need electricians." }
|
||||
- { id: scaffolder, need: subcontractor-application, text: "I run a scaffolding company. How do I get to do jobs for you?" }
|
||||
- { id: carpenter-jobseeker, need: job-application, text: "I'm a certified carpenter with eight years on rehabilitation jobs. Are you hiring?" }
|
||||
- { id: apprentice, need: job-application, text: "I finish vocational school this spring and need an apprenticeship as a bricklayer." }
|
||||
- { id: extra-window, need: change-request, text: "You are in the middle of our attic conversion. We have decided we want a roof window over the stairs as well. What would that cost?" }
|
||||
- { id: pm-took-a-call, need: log-phone-enquiry, text: "A woman from a housing board in Storgata just rang about water in their basement. I'm in the van. I need to note it before I forget her number." }
|
||||
- { id: pm-needs-plumber, need: post-job-request, text: "The bathroom job in Kirkeveien needs a plumber for two weeks from the first of next month. I want prices from the ones we have approved." }
|
||||
- { id: plumber-bidding, need: submit-bid, text: "We are an approved plumbing firm. I saw you need someone in Kirkeveien next month. We can do it, I have a price." }
|
||||
- { id: loose-railing, need: report-site-issue, text: "The railing on the third level of the scaffold on the north side is loose. Nobody got hurt but someone will." }
|
||||
- { id: wrong-membrane, need: report-site-issue, text: "The bathroom membrane delivered today is not the one in the specification. We stopped work on it." }
|
||||
- { id: out-of-battens, need: order-materials, text: "We have enough roof battens for today and maybe half of tomorrow. Need another two hundred metres on site by Thursday." }
|
||||
- { id: weekly-round, need: safety-round-finding, text: "On my Friday round I found the first-aid box on level two empty and an extension lead run through a puddle." }
|
||||
Vendored
+122
@@ -0,0 +1,122 @@
|
||||
# The contractor from intakes/contractor.yaml as a plan: the needs spec
|
||||
# plus what each form collects. Everything structural in the generated
|
||||
# site comes from this file; a model only writes the words.
|
||||
business: Nordvik Bygg
|
||||
language: en
|
||||
contact: { name: Ingrid Nordvik, email: ingrid@nordvikbygg.example }
|
||||
about: >
|
||||
Twelve people who survey old buildings, draw up rehabilitation plans,
|
||||
handle the permit application, and do the building work with their
|
||||
own carpenters plus subcontractors for electrical, plumbing and
|
||||
scaffolding.
|
||||
|
||||
needs:
|
||||
- id: survey-enquiry
|
||||
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
|
||||
handled_by: project_managers
|
||||
stages: [open, surveyed, quoted, won, lost]
|
||||
done_when: [won, lost]
|
||||
success: [won]
|
||||
max_fields: 4
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: phone, type: tel }
|
||||
- { name: address }
|
||||
- { name: problem, type: textarea }
|
||||
- { name: access, optional: true }
|
||||
|
||||
- id: build-enquiry
|
||||
who: an owner who already knows what they want built or changed
|
||||
wants: drawings, a permit application and a price
|
||||
lands_in: enquiries
|
||||
handled_by: project_managers
|
||||
stages: [open, surveyed, quoted, won, lost]
|
||||
done_when: [won, lost]
|
||||
success: [won]
|
||||
max_fields: 5
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: phone, type: tel }
|
||||
- { name: address }
|
||||
- { name: project, type: textarea }
|
||||
- { name: timeframe, type: select, options: [This year, Next year, No fixed date] }
|
||||
|
||||
- id: log-phone-enquiry
|
||||
who: a project manager who just took a call or a text about a building
|
||||
wants: the enquiry written down before it gets lost
|
||||
enters_as: project_managers
|
||||
lands_in: enquiries
|
||||
handled_by: project_managers
|
||||
stages: [open, surveyed, quoted, won, lost]
|
||||
done_when: [won, lost]
|
||||
success: [won]
|
||||
max_fields: 4
|
||||
collects:
|
||||
- { name: caller }
|
||||
- { name: phone, type: tel }
|
||||
- { name: address }
|
||||
- { name: problem, type: textarea }
|
||||
|
||||
- id: subcontractor-application
|
||||
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
|
||||
handled_by: project_managers
|
||||
stages: [open, awaiting_papers, approved, declined]
|
||||
done_when: [approved, declined]
|
||||
success: [approved]
|
||||
skippable: [awaiting_papers]
|
||||
max_fields: 5
|
||||
collects:
|
||||
- { name: company }
|
||||
- { name: registration_number }
|
||||
- { name: trade, type: select, options: [Electrical, Plumbing, Scaffolding, Sheet metal, Other] }
|
||||
- { name: contact_email, type: email }
|
||||
- { name: insurance_confirmed, type: select, options: ["Yes", Not yet] }
|
||||
- { name: trade_approval, optional: true }
|
||||
|
||||
- id: job-application
|
||||
who: a carpenter, bricklayer or apprentice looking for work
|
||||
wants: to be considered, without writing a letter
|
||||
lands_in: applicants
|
||||
handled_by: project_managers
|
||||
stages: [open, interviewing, hired, declined]
|
||||
done_when: [hired, declined]
|
||||
success: [hired]
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: phone, type: tel }
|
||||
- { name: trade, type: select, options: [Carpenter, Bricklayer, Apprentice, Other] }
|
||||
- { name: experience, type: textarea, optional: true }
|
||||
|
||||
- id: report-site-issue
|
||||
who: anyone on site, ours or a subcontractor's, on a phone with gloves on
|
||||
wants: to report a hazard, a near miss or wrong materials before they forget
|
||||
enters_as: crew
|
||||
lands_in: site_issues
|
||||
handled_by: safety_officer
|
||||
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 }
|
||||
- { name: what_happened, type: textarea }
|
||||
|
||||
# Held out from every model that writes words: these are the personas
|
||||
# from sectors/construction, which no generator has seen.
|
||||
personas:
|
||||
- { id: housing-board-damp, need: survey-enquiry, text: "I chair the board of a housing cooperative from the seventies. Two ground-floor flats have damp in the walls and we don't know if it's drainage or the facade. We need someone to tell us." }
|
||||
- { id: buyer-before-purchase, need: survey-enquiry, text: "We are about to buy an old timber house. Before we sign we want a professional to go through it and tell us what is wrong with it." }
|
||||
- { id: attic-conversion, need: build-enquiry, text: "We want to turn our attic into two bedrooms and a bathroom. We need drawings and someone who handles the application to the municipality." }
|
||||
- { id: shop-to-flat, need: build-enquiry, text: "I own a former shop on the ground floor and want to make it a flat. I have no idea what is allowed. Can you sort that out and give me a price?" }
|
||||
- { id: electrician-firm, need: subcontractor-application, text: "We are a four-person electrical firm, fully certified. We would like to get on your list so you call us when you need electricians." }
|
||||
- { id: scaffolder, need: subcontractor-application, text: "I run a scaffolding company. How do I get to do jobs for you?" }
|
||||
- { id: carpenter-jobseeker, need: job-application, text: "I'm a certified carpenter with eight years on rehabilitation jobs. Are you hiring?" }
|
||||
- { id: apprentice, need: job-application, text: "I finish vocational school this spring and need an apprenticeship as a bricklayer." }
|
||||
- { id: loose-railing, need: report-site-issue, text: "The railing on the third level of the scaffold on the north side is loose. Nobody got hurt but someone will." }
|
||||
- { id: wrong-membrane, need: report-site-issue, text: "The bathroom membrane delivered today is not the one in the specification. We stopped work on it." }
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
# 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 }
|
||||
mail: { from: "Liail IL <post@liail.example>", reply_to: 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]
|
||||
stages_text: { open: "mottatt", godkjent: "godkjent av treneren", betalt: "betalt", trukket: "trukket" }
|
||||
mails: { open: submitter, godkjent: submitter, betalt: submitter }
|
||||
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: email, 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]
|
||||
stages_text: { open: "mottatt", vurdert: "vurdert", innvilget: "innvilget", avslatt: "avslått" }
|
||||
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]
|
||||
stages_text: { open: "mottatt", kontaktet: "kontaktet", plassert: "satt opp", avslatt: "takket nei" }
|
||||
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]
|
||||
stages_text: { open: "mottatt", i_dialog: "i dialog", avtalt: "avtalt", avslatt: "avslått" }
|
||||
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]
|
||||
stages_text: { open: "mottatt", tatt_tak_i: "tatt tak i", ordnet: "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." }
|
||||
Vendored
+94
@@ -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." }
|
||||
Vendored
+113
@@ -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." }
|
||||
Vendored
+331
@@ -0,0 +1,331 @@
|
||||
# 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. Oppslagstavla for deling av utstyr
|
||||
# står ute med en gang: en nabo som kan låne ut, eller vil låne, sier
|
||||
# fra rett fra oppslaget, og den som la det ut hører fra dem. Køen er
|
||||
# innboksen til den som la ut; siden holder ikke rede på hvem som ble
|
||||
# valgt. Redaktøren, de som står som ansvarlige, tar ned det som står
|
||||
# igjen.
|
||||
business: Tomter Vel
|
||||
language: no
|
||||
# Styret svarer for sidene som gruppe: ingen konto for innboksen, og
|
||||
# hvert styremedlem kan foreslå endringer på dem.
|
||||
contact: { name: Styret i Tomter Vel, email: post@tomtervel.no, group: styret }
|
||||
# Portal holder gruppene selv: en invitasjon er en plass som venter til
|
||||
# personen logger inn, og en person er telefonnummeret sitt først. Med
|
||||
# Vipps-innlogging kan alle logge inn med en gang; til da lager Kanidm
|
||||
# kontoen ved siden av.
|
||||
people: memberships
|
||||
# Avsenderen for all e-post fra siden (gdo på kasse leverer); det
|
||||
# kasses postfix kan sende for i dag.
|
||||
mail: { from: "Tomter Vel <tomtervel@klingenbergbygg.no>", reply_to: 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 }
|
||||
|
||||
# Styret kan invitere inn i alle grupper som har en pult; hver gruppe kan
|
||||
# invitere inn i seg selv. Portal oppretter kontoen og en engangslenke.
|
||||
invites_by: [styret]
|
||||
|
||||
# Forsiden åpner beskjedent: to trekk, én rolle hver, ingen knapp,
|
||||
# før tilbudene lenger ned på samme side. De to velet er til for: en
|
||||
# husstand som blir medlem, og en nabo som trenger en hånd. Begge har
|
||||
# noe å gjøre etterpå: medlemmet melder seg ut selv, den som fikk
|
||||
# hjelp sier selv fra at det er ordnet.
|
||||
does:
|
||||
- id: medlem
|
||||
for: bli-medlem
|
||||
text: >
|
||||
Velet taler for Tomter overfor kommunen, holder lekeplassene og
|
||||
stien i stand og samler naboene på 17. mai og dugnad. 157
|
||||
husstander er med. Du melder deg inn her, og ut igjen selv når
|
||||
du vil.
|
||||
- id: nabo
|
||||
for: trenger-hjelp
|
||||
text: >
|
||||
Trenger du en hånd med snømåking, handling eller skyss, kobler
|
||||
nabohjelpsgruppa deg med en nabo som kan. Du sier selv fra når
|
||||
det er ordnet.
|
||||
|
||||
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
|
||||
lands_in: husstander
|
||||
door: medlem
|
||||
handled_by: kasserer
|
||||
stages: [open, betalt, utmeldt]
|
||||
stages_text: { open: "mottatt", betalt: "betalt", utmeldt: "meldt ut" }
|
||||
done_when: [betalt, utmeldt]
|
||||
success: [betalt]
|
||||
# Medlemmet melder seg ut selv, gjennom sin egen lenke.
|
||||
moves_by: { utmeldt: [submitter, kasserer] }
|
||||
mails: { open: submitter, betalt: submitter }
|
||||
# Betalt kontingent er medlemskapet: husstanden får konto og plass
|
||||
# blant medlemmene i samme trekk, og det som er medlemmenes eget
|
||||
# (komitéplass) ligger bak innloggingen.
|
||||
grants: { betalt: medlemmer }
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: adresse }
|
||||
- { name: email, 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
|
||||
lands_in: medlemsendringer
|
||||
door: medlem
|
||||
handled_by: kasserer
|
||||
stages: [open, oppdatert]
|
||||
stages_text: { open: "mottatt", oppdatert: "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
|
||||
lands_in: trafikkmeldinger
|
||||
door: melde-fra
|
||||
handled_by: trafikk
|
||||
stages: [open, tatt_opp, ordnet, avvist]
|
||||
stages_text: { open: "mottatt", tatt_opp: "tatt opp med kommunen", ordnet: "ordnet", avvist: "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
|
||||
lands_in: anleggsfeil
|
||||
door: melde-fra
|
||||
handled_by: lekeplasser
|
||||
stages: [open, tatt_tak_i, utbedret]
|
||||
stages_text: { open: "mottatt", tatt_tak_i: "tatt tak i", utbedret: "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]
|
||||
stages_text: { open: "mottatt", tatt_med: "tatt med i høringssvaret", ikke_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
|
||||
lands_in: frivillige
|
||||
door: bidra
|
||||
handled_by: arrangementer
|
||||
stages: [open, kontaktet, satt_opp, takket_nei]
|
||||
stages_text: { open: "mottatt", kontaktet: "kontaktet", satt_opp: "satt opp", takket_nei: "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] }
|
||||
|
||||
# Komitéplass er for medlemmer: døra viser veien, skjemaet ligger på
|
||||
# medlemmenes side bak innloggingen.
|
||||
- id: komite
|
||||
who: et medlem som vil sitte i en komité
|
||||
wants: en plass i den komiteen som driver med det de bryr seg om
|
||||
lands_in: komitesoknader
|
||||
door: bidra
|
||||
enters_as: medlemmer
|
||||
handled_by: styret
|
||||
stages: [open, plassert, avslatt]
|
||||
stages_text: { open: "mottatt", plassert: "plassert i en komité", avslatt: "avslått" }
|
||||
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
|
||||
lands_in: hjelpebehov
|
||||
# Et behov ingen har tatt tak i på en uke går opp til styret: samme
|
||||
# sak, samme knapper, på styrets pult i tillegg.
|
||||
escalate: { open: { days: 7, to: styret } }
|
||||
door: naboer
|
||||
handled_by: nabohjelp
|
||||
stages: [open, formidlet, ordnet, ikke_lost]
|
||||
stages_text: { open: "mottatt", open_escalated: "hos styret, siden ingen tok den på en uke", formidlet: "formidlet til en nabo", ordnet: "ordnet", ikke_lost: "ikke løst" }
|
||||
done_when: [ordnet, ikke_lost]
|
||||
success: [ordnet]
|
||||
moves_by: { ordnet: [submitter, nabohjelp] }
|
||||
mails: { open: submitter, formidlet: submitter, ordnet: submitter }
|
||||
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
|
||||
lands_in: hjelpere
|
||||
door: naboer
|
||||
handled_by: nabohjelp
|
||||
stages: [open, registrert, trukket]
|
||||
stages_text: { open: "mottatt", registrert: "registrert som hjelper", trukket: "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: ut med en gang, styret hører om det. Svar går
|
||||
# rett til den som la ut; køen er innboksen deres. Tas ned av den
|
||||
# som la ut, av redaktøren, eller av klokka etter en måned.
|
||||
- id: dele-utstyr
|
||||
who: en nabo som har noe å låne ut, eller trenger å låne noe
|
||||
wants: et oppslag naboene ser med en gang
|
||||
lands_in: oppslag
|
||||
door: naboer
|
||||
handled_by: redaktor
|
||||
stages: [open, tatt_ned]
|
||||
stages_text: { open: "ute", tatt_ned: "tatt ned" }
|
||||
done_when: [tatt_ned]
|
||||
success: [tatt_ned]
|
||||
moves_by: { tatt_ned: [submitter, redaktor] }
|
||||
mails: { open: post@tomtervel.no }
|
||||
deadlines: { open: { days: 30, to: tatt_ned } }
|
||||
# Tavla er offentlig: det er den naboene leser; navn og e-post
|
||||
# vises ikke der.
|
||||
watched_by: [public]
|
||||
public_states: [open]
|
||||
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 }
|
||||
|
||||
# Svaret på et oppslag: fra oppslagets egen rad på tavla, med
|
||||
# e-post eller innlogget, rett til den som la ut. Redaktøren ser
|
||||
# svarene og merker dem lest.
|
||||
- id: melde-seg
|
||||
who: en nabo som kan låne ut, eller vil låne, det et oppslag gjelder
|
||||
wants: at den som la ut oppslaget får vite det
|
||||
about: dele-utstyr
|
||||
lands_in: svar
|
||||
handled_by: redaktor
|
||||
stages: [open, lest]
|
||||
stages_text: { open: "sendt", lest: "lest" }
|
||||
done_when: [lest]
|
||||
success: [lest]
|
||||
mails: { open: owner }
|
||||
max_fields: 2
|
||||
collects:
|
||||
- { name: email, type: email }
|
||||
- { name: hilsen, type: textarea, optional: true }
|
||||
|
||||
- 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]
|
||||
stages_text: { open: "mottatt", godkjent: "godkjent", utbetalt: "utbetalt", avvist: "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." }
|
||||
Vendored
+233
@@ -0,0 +1,233 @@
|
||||
# UHHM, uhhm.no: the studio that builds portal and carries redoal.
|
||||
# Rebuilt from the live site (uhhm/questions) on 2026-09-23. The five
|
||||
# buckets the site already holds keep their live state and event
|
||||
# names (`events:`), so every record on the owners' desk stays where
|
||||
# it is. Two are new: a business trying the trainer on its own
|
||||
# workflow (`trials`, approved by a person before anything is built),
|
||||
# and what reaches UHHM as the custodian of the redoal network
|
||||
# (`custody_requests`, a desk of its own).
|
||||
business: UHHM
|
||||
language: en
|
||||
contact: { name: Bendik Aagaard Lynghaug, email: bl@uhhm.no }
|
||||
# Every mail the site sends comes from here (gdo on ergo delivers).
|
||||
mail: { from: "UHHM <portal@uhhm.no>", reply_to: bl@uhhm.no }
|
||||
about: >
|
||||
UHHM builds software around a clear argument: infrastructure, tools
|
||||
and products for organizations that can say what problem they have.
|
||||
It also builds and carries the redoal network - the gesture math,
|
||||
the relay, the first node, and the portal this site runs on - and
|
||||
answers for what that network keeps.
|
||||
|
||||
groups:
|
||||
- { id: owners, label: Owners }
|
||||
# The people who answer for the redoal network: they host its first
|
||||
# node and relay, keep what is left there, and decide what stays.
|
||||
- { id: custodians, label: redoal custodians, invited_by: [owners] }
|
||||
# Owners onboard into every desk; a custodian can vouch for another.
|
||||
invites_by: [owners]
|
||||
|
||||
# The front door opens modestly: one or two features, one role each,
|
||||
# and no button, before the offers further down the same page. The
|
||||
# two roles UHHM exists for: an organization with a problem, and the
|
||||
# people on the redoal network it keeps.
|
||||
does:
|
||||
- id: software
|
||||
for: commission
|
||||
text: >
|
||||
Software built around a clear argument. Infrastructure, tools
|
||||
and products for organizations that can say what problem they
|
||||
have - and a working draft of your own workflow as a site,
|
||||
before you pay for anything.
|
||||
- id: redoal
|
||||
for: custody
|
||||
text: >
|
||||
The redoal network, built and carried here: the gesture math,
|
||||
the relay, the first node, and the portal this site runs on.
|
||||
UHHM answers for what that network keeps.
|
||||
|
||||
# Things to look at before asking for anything.
|
||||
shows:
|
||||
- id: built
|
||||
text: A few things already out in the world.
|
||||
resource:
|
||||
public: true
|
||||
source: { kind: gitea_starred, username: bl }
|
||||
jq: >
|
||||
.[] | {name: .name, description: .description,
|
||||
url: (if .website != null and .website != "" then .website
|
||||
elif .private then null
|
||||
else .html_url end)}
|
||||
- id: voices
|
||||
text: Live from the redoal relay - what has been left at places so far.
|
||||
resource:
|
||||
public: true
|
||||
source: { kind: url, url: https://relay.redoal.com/pulse }
|
||||
jq: >
|
||||
{ "name": (.voices_echoed | tostring),
|
||||
"description": "voices echoed so far" }
|
||||
empty: The first voice has not echoed yet.
|
||||
|
||||
needs:
|
||||
- id: commission
|
||||
who: an organization with a problem it wants software to solve
|
||||
wants: a considered reply to a brief, from people who read the whole thing
|
||||
lands_in: projects
|
||||
handled_by: owners
|
||||
stages: [open, accepted, declined]
|
||||
done_when: [accepted, declined]
|
||||
success: [accepted]
|
||||
events: { open: submitted }
|
||||
stages_text: { open: "received", accepted: "taken on", declined: "not a fit for us" }
|
||||
# The client plays too: they can withdraw the brief themselves.
|
||||
moves_by: { declined: [submitter, owners] }
|
||||
mails: { open: submitter, accepted: submitter, declined: submitter }
|
||||
max_fields: 4
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: email, type: email }
|
||||
- { name: project, type: textarea }
|
||||
- { name: organization }
|
||||
- { name: org_contact, optional: true }
|
||||
|
||||
# The client feature: the trainer tried on a real business. A person
|
||||
# approves each intake before anything is built from it.
|
||||
- id: trial
|
||||
who: someone who runs a business where requests, approvals and handovers get lost, and wants to see it as a site before committing to anything
|
||||
wants: a first draft of a site for their own roles, built from their own words and approved by a person first
|
||||
lands_in: trials
|
||||
handled_by: owners
|
||||
stages: [open, approved, previewed, declined]
|
||||
done_when: [previewed, declined]
|
||||
success: [previewed]
|
||||
stages_text: { open: "received", approved: "approved for a draft", previewed: "a preview is ready", declined: "not a fit for us" }
|
||||
mails: { open: submitter, approved: submitter, previewed: submitter, declined: submitter }
|
||||
attended_by: >
|
||||
approved -> previewed: the n8n workflow that builds the draft
|
||||
site from an approved intake (docker, rauthy, portal content)
|
||||
and sends the preview link. Until it exists, owners run
|
||||
portal-trainer by hand and press the button.
|
||||
max_fields: 6
|
||||
collects:
|
||||
- { name: business }
|
||||
- { name: email, type: email }
|
||||
- { name: what_we_do, type: textarea }
|
||||
- { name: who_comes_to_us, type: textarea }
|
||||
- { name: what_we_keep_track_of, type: textarea }
|
||||
- { name: who_is_involved, type: textarea }
|
||||
- { name: what_slows_us_down, type: textarea, optional: true }
|
||||
|
||||
- id: collaborate
|
||||
who: someone who wants to work with us on what we build
|
||||
wants: to be read as a person, and invited in if there is a fit
|
||||
lands_in: applicants
|
||||
handled_by: owners
|
||||
stages: [open, invited, active, departed, declined]
|
||||
done_when: [departed, declined]
|
||||
success: [departed]
|
||||
events: { open: applied, active: onboarded }
|
||||
# Declined before starting; after that a person departs.
|
||||
turned_down_from: [open, invited]
|
||||
stages_text: { open: "received", invited: "invited in", active: "working with us", departed: "moved on", declined: "not a fit for us" }
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: email, type: email }
|
||||
- { name: interest, type: textarea }
|
||||
- { name: note, type: textarea, optional: true }
|
||||
|
||||
- id: subscribe
|
||||
who: someone who wants to hear from us when there is something to say
|
||||
wants: a note now and then, and an easy way out
|
||||
lands_in: subscribers
|
||||
handled_by: owners
|
||||
stages: [open, unsubscribed]
|
||||
done_when: [unsubscribed]
|
||||
events: { open: subscribed }
|
||||
stages_text: { open: "on the list", unsubscribed: "off the list" }
|
||||
moves_by: { unsubscribed: [submitter, owners] }
|
||||
max_fields: 2
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: email, type: email }
|
||||
|
||||
# This site proposes its own changes through itself.
|
||||
- id: propose
|
||||
who: a visitor who sees how a page on this site should change
|
||||
wants: the change read by a person and, if approved, made
|
||||
lands_in: development_proposals
|
||||
handled_by: owners
|
||||
stages: [open, approved, rejected]
|
||||
done_when: [approved, rejected]
|
||||
success: [approved]
|
||||
events: { open: proposed }
|
||||
stages_text: { open: "received", approved: "approved", rejected: "turned down" }
|
||||
# The site changes in the open: anyone can read what was approved,
|
||||
# without who proposed it.
|
||||
watched_by: [public]
|
||||
public_states: [approved]
|
||||
max_fields: 3
|
||||
collects:
|
||||
- { name: submitted_by, private: true }
|
||||
- { name: email, type: email, optional: true }
|
||||
- { name: page, optional: true }
|
||||
- { name: rationale, type: textarea }
|
||||
- { name: proposed_yaml, type: textarea }
|
||||
|
||||
# The custodian role, on the front door: UHHM answers for the redoal
|
||||
# network it hosts. Owners see these too, and move nothing.
|
||||
- id: custody
|
||||
who: someone who runs, builds on, or is affected by the redoal network and needs the people who keep its first node
|
||||
wants: an answer from a custodian, and action where the network keeps something it should not
|
||||
lands_in: custody_requests
|
||||
handled_by: custodians
|
||||
watched_by: [owners]
|
||||
stages: [open, in_dialogue, resolved, declined]
|
||||
done_when: [resolved, declined]
|
||||
success: [resolved]
|
||||
stages_text: { open: "received", in_dialogue: "in dialogue with a custodian", resolved: "resolved", declined: "closed without action" }
|
||||
# The person affected says when it is resolved, not only the custodian.
|
||||
moves_by: { resolved: [submitter, custodians] }
|
||||
mails: { open: submitter, resolved: submitter, declined: submitter }
|
||||
max_fields: 4
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: email, type: email }
|
||||
- { name: about, type: select, options: [Running a node of my own, Building on the network, Something the network keeps about me, Something else] }
|
||||
- { name: what, type: textarea }
|
||||
|
||||
# Internal: a relationship worth tracking before it is a project.
|
||||
- id: prospect
|
||||
who: an owner who has met an organization worth following up
|
||||
wants: it written down and walked through its states from the desk
|
||||
enters_as: owners
|
||||
lands_in: organizations
|
||||
handled_by: owners
|
||||
stages: [prospect, client, past_client]
|
||||
done_when: [past_client]
|
||||
skippable: [client]
|
||||
stages_text: { prospect: "a prospect", client: "a client", past_client: "a past client" }
|
||||
events: { prospect: identified, client: became_client, past_client: churned }
|
||||
max_fields: 2
|
||||
collects:
|
||||
- { name: name }
|
||||
- { name: contact }
|
||||
- { name: note, type: textarea, optional: true }
|
||||
|
||||
# Held out from every model that writes words. The first eight are the
|
||||
# 2026-09-21 set (runs/uhhm-2026-09-21); the rest are for what is new.
|
||||
personas:
|
||||
- { id: architecture-firm, need: commission, text: "We run a small architecture firm and our project files are scattered across three cloud drives. We want to pay someone to set up proper storage and backups we control ourselves." }
|
||||
- { id: climbing-gym-founder, need: commission, text: "I have an idea for a booking app for climbing gyms and I'm looking for a team that can build the first version with me." }
|
||||
- { id: municipality-buyer, need: commission, text: "Our municipality needs an internal tool for tracking building permits. We are looking for a vendor who can scope it and deliver it." }
|
||||
- { id: exhibition-visitor, need: subscribe, text: "I saw your drawing network at an exhibition and liked it. I don't want to get involved, I'd just like to know when there is news." }
|
||||
- { id: tech-journalist, need: subscribe, text: "I write about Nordic technology. Keep me posted on what you release so I can cover it." }
|
||||
- { id: rust-developer, need: collaborate, text: "I'm a Rust developer between jobs and I like that you build in the open. I would love to contribute, and maybe join you." }
|
||||
- { id: interaction-designer, need: collaborate, text: "I'm an interaction designer. I want to work with you on the drawing interface." }
|
||||
- { id: student-intern, need: collaborate, text: "I'm a computer science student looking for a summer internship doing infrastructure work." }
|
||||
- { id: plumber-owner, need: trial, text: "I run a plumbing company with four vans. Jobs come in by phone and text and some get lost. I'd like to see how this would look for us before I spend any money." }
|
||||
- { id: dance-school, need: trial, text: "We are a dance school. Enrolments, cancellations and invoices all go through one email inbox that only I understand. Can you show me a version made for us?" }
|
||||
- { id: node-runner, need: custody, text: "I run a small server in Berlin and want to host a redoal node that peers with yours. Who do I talk to?" }
|
||||
- { id: recorded-name, need: custody, text: "Someone left a recording on redoal that says my full name and where I live. I want it gone, and I want to know who is responsible for that network." }
|
||||
- { id: app-builder, need: custody, text: "I'm building a music app and would like to use redoal's gesture addresses in it. Is that possible, and who decides?" }
|
||||
- { id: wording-fix, need: propose, text: "The subscribe page should say how often you actually write. I'd like to suggest that exact change to the page." }
|
||||
- { id: rewrite, need: propose, text: "One page on this site reads wrong to me and I know exactly how I'd rewrite it. Where do I send the new text?" }
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
# One onboarding per business. `open` is the intake as submitted; the
|
||||
# generator (portal-trainer generate) turns it into a draft content
|
||||
# repo; the business reviews the draft and either it goes live or it
|
||||
# comes back for another pass.
|
||||
aggregates:
|
||||
- bucket: onboardings
|
||||
initial: open
|
||||
states:
|
||||
open: { event: intake_received }
|
||||
drafted: { event: draft_generated }
|
||||
revising: { event: revision_requested }
|
||||
live: { event: went_live }
|
||||
declined: { event: declined }
|
||||
transitions:
|
||||
open: [drafted, declined]
|
||||
drafted: [live, revising, declined]
|
||||
revising: [drafted, declined]
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
# The onboarding site is a portal site, so it is held to a needs spec
|
||||
# like any other.
|
||||
needs:
|
||||
- id: onboard-business
|
||||
who: someone who runs a business where requests, approvals and handovers get lost
|
||||
wants: a working site for their own roles, without commissioning software
|
||||
via: Describe your business and get a first draft
|
||||
lands_in: onboardings
|
||||
handled_by: owners
|
||||
done_when: [live, declined]
|
||||
max_steps: 1
|
||||
# The intake is the interview: two to reach them, four about the work.
|
||||
max_fields: 6
|
||||
|
||||
personas:
|
||||
- id: contractor-owner
|
||||
need: onboard-business
|
||||
text: >
|
||||
I run a building firm. Enquiries come by phone, text and email
|
||||
and we lose track of who promised what. I want one place where
|
||||
they land and my project managers pick them up.
|
||||
|
||||
- id: clinic-manager
|
||||
need: onboard-business
|
||||
text: >
|
||||
We are a physiotherapy clinic with six therapists. Referrals,
|
||||
cancellations and insurance approvals all go through one inbox
|
||||
that only our receptionist understands. I'd like that sorted.
|
||||
|
||||
- id: sports-club
|
||||
need: onboard-business
|
||||
text: >
|
||||
I volunteer for a youth football club. Parents sign kids up,
|
||||
coaches need to approve them, and the treasurer chases fees.
|
||||
Right now it's a spreadsheet and a group chat.
|
||||
|
||||
- id: sceptical-founder
|
||||
need: onboard-business
|
||||
text: >
|
||||
I've been burned by agencies before. If I can explain my
|
||||
workflow and see something real before paying anyone, I'm in.
|
||||
@@ -0,0 +1 @@
|
||||
qualifies: owners
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Which businesses are waiting on us?
|
||||
responsible:
|
||||
name: Bendik Aagaard Lynghaug
|
||||
contact: bl@uhhm.no
|
||||
alternatives:
|
||||
- name: Onboardings
|
||||
description: >
|
||||
Run `portal-trainer generate` on an open intake, push the draft,
|
||||
send the link, then mark it drafted. Revisions come back here.
|
||||
action: /desk
|
||||
consequence: [Confirm]
|
||||
features:
|
||||
- name: ""
|
||||
description: ""
|
||||
resource:
|
||||
source: { kind: kv, bucket: onboardings }
|
||||
requires_group: owners
|
||||
transitions:
|
||||
- { to: drafted, label: Draft sent }
|
||||
- { to: declined, label: Decline }
|
||||
- { from: drafted, to: live, label: Went live }
|
||||
- { from: drafted, to: revising, label: Revision asked }
|
||||
- { from: drafted, to: declined, label: Decline }
|
||||
- { from: revising, to: drafted, label: Revised draft sent }
|
||||
- { from: revising, to: declined, label: Decline }
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
name: How does an answer become a finished job?
|
||||
description: >
|
||||
Every page asks one question. Every answer lands with the person
|
||||
whose job it is, and carries its own next steps.
|
||||
alternatives:
|
||||
- name: A visitor answers
|
||||
description: >
|
||||
They pick what they came for and fill in the few fields that
|
||||
person needs. They are told who reads it and when.
|
||||
- name: The right role sees it
|
||||
description: >
|
||||
Each role has a desk listing what is theirs, with one button per
|
||||
step your process allows - quoted, approved, closed.
|
||||
- name: Nothing waits unseen
|
||||
description: >
|
||||
Every case has a state and an owner, so what is open, and with
|
||||
whom, is always one page away.
|
||||
- name: Describe your business and get a first draft
|
||||
description: Five answers in your own words.
|
||||
action: /
|
||||
consequence: [Start]
|
||||
@@ -0,0 +1,49 @@
|
||||
name: What does your business keep doing by hand?
|
||||
description: >
|
||||
Tell us who comes to you, what you keep track of, and who handles
|
||||
what. You get a site that asks each of those people the right
|
||||
question and moves every answer to the person who acts on it.
|
||||
responsible:
|
||||
name: Bendik Aagaard Lynghaug
|
||||
contact: bl@uhhm.no
|
||||
alternatives:
|
||||
- name: Describe your business and get a first draft
|
||||
description: >
|
||||
Five answers in your own words. We turn them into pages, forms
|
||||
and a desk for each role, and send you a link to try it.
|
||||
action: /received
|
||||
consequence: [Send it]
|
||||
record_as: onboardings
|
||||
encouragements:
|
||||
- Write it the way you would explain it to a new colleague.
|
||||
features:
|
||||
- name: You
|
||||
requirements:
|
||||
- { name: business, label: Business name }
|
||||
- { name: email, label: Your email, type: email }
|
||||
- name: The work
|
||||
description: Plain words are best. Stages, handovers and waiting are what we listen for.
|
||||
requirements:
|
||||
- name: what_we_do
|
||||
label: What you do
|
||||
type: textarea
|
||||
- name: who_comes_to_us
|
||||
label: Who comes to you, and what each of them wants
|
||||
type: textarea
|
||||
- name: what_we_keep_track_of
|
||||
label: What you keep track of, and the stages it goes through
|
||||
type: textarea
|
||||
- name: who_is_involved
|
||||
label: Who on your side handles what
|
||||
type: textarea
|
||||
- name: what_slows_us_down
|
||||
label: Where things get lost or wait today
|
||||
type: textarea
|
||||
optional: true
|
||||
|
||||
- name: See how a question becomes a finished job
|
||||
description: >
|
||||
One enquiry followed from the visitor's answer to the desk that
|
||||
closes it.
|
||||
action: /how
|
||||
consequence: [Show me]
|
||||
@@ -0,0 +1,15 @@
|
||||
followup: true
|
||||
name: What happens with what you sent?
|
||||
description: >
|
||||
Bendik reads every intake. Within two working days you get a link to
|
||||
a working draft built from your answers.
|
||||
alternatives:
|
||||
- name: You try the draft as each of your roles
|
||||
description: >
|
||||
Click through it as a customer, then as the colleague who handles
|
||||
that customer. Tell us what reads wrong and the draft comes back
|
||||
revised.
|
||||
- name: Back to the start
|
||||
description: ""
|
||||
action: /
|
||||
consequence: [Back]
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
title: Portal
|
||||
lang: en
|
||||
@@ -0,0 +1,43 @@
|
||||
aggregates:
|
||||
- bucket: enquiries
|
||||
initial: open
|
||||
states:
|
||||
open: { event: received }
|
||||
quoted: { event: quoted }
|
||||
won: { event: won }
|
||||
lost: { event: lost }
|
||||
transitions:
|
||||
open: [quoted, lost]
|
||||
quoted: [won, lost]
|
||||
|
||||
- bucket: subcontractors
|
||||
initial: open
|
||||
states:
|
||||
open: { event: applied }
|
||||
awaiting_papers: { event: papers_requested }
|
||||
approved: { event: approved }
|
||||
declined: { event: declined }
|
||||
transitions:
|
||||
open: [awaiting_papers, approved, declined]
|
||||
awaiting_papers: [approved, declined]
|
||||
|
||||
- bucket: applicants
|
||||
initial: open
|
||||
states:
|
||||
open: { event: applied }
|
||||
interviewing: { event: invited }
|
||||
hired: { event: hired }
|
||||
declined: { event: declined }
|
||||
transitions:
|
||||
open: [interviewing, declined]
|
||||
interviewing: [hired, declined]
|
||||
|
||||
- bucket: site_issues
|
||||
initial: open
|
||||
states:
|
||||
open: { event: reported }
|
||||
in_hand: { event: assessed }
|
||||
closed: { event: closed }
|
||||
transitions:
|
||||
open: [in_hand]
|
||||
in_hand: [closed]
|
||||
@@ -0,0 +1,10 @@
|
||||
{"id":"housing-board-cracks@/","choice":"Get someone to look at a building","confidence":0.93}
|
||||
{"id":"homeowner-leaking-roof@/","choice":"Get someone to look at a building","confidence":0.92}
|
||||
{"id":"homeowner-extension@/","choice":"Get a price for a build","confidence":0.72}
|
||||
{"id":"owner-basement-conversion@/","choice":"Get a price for a build","confidence":0.72}
|
||||
{"id":"electrician-more-work@/","choice":"Join our subcontractor list","confidence":0.9}
|
||||
{"id":"scaffolding-firm@/","choice":"Join our subcontractor list","confidence":0.9}
|
||||
{"id":"apprentice-asking@/","choice":"Ask about working with us","confidence":0.62}
|
||||
{"id":"experienced-carpenter@/","choice":"Ask about working with us","confidence":0.62}
|
||||
{"id":"crew-loose-scaffold@/","choice":"Report something from site","confidence":0.92}
|
||||
{"id":"subcontractor-wrong-delivery@/","choice":"Report something from site","confidence":0.88}
|
||||
@@ -0,0 +1,10 @@
|
||||
{"id":"housing-board-cracks@/","choice":"Get someone to look at a building","confidence":0.97}
|
||||
{"id":"homeowner-leaking-roof@/","choice":"Get someone to look at a building","confidence":0.96}
|
||||
{"id":"homeowner-extension@/","choice":"Get a price for a build","confidence":0.95}
|
||||
{"id":"owner-basement-conversion@/","choice":"Get a price for a build","confidence":0.95}
|
||||
{"id":"electrician-more-work@/","choice":"Join our subcontractor list","confidence":0.97}
|
||||
{"id":"scaffolding-firm@/","choice":"Join our subcontractor list","confidence":0.97}
|
||||
{"id":"apprentice-asking@/","choice":"Ask about working with us","confidence":0.96}
|
||||
{"id":"experienced-carpenter@/","choice":"Ask about working with us","confidence":0.95}
|
||||
{"id":"crew-loose-scaffold@/","choice":"Report something from site","confidence":0.95}
|
||||
{"id":"subcontractor-wrong-delivery@/","choice":"Report something from site","confidence":0.93}
|
||||
@@ -0,0 +1,124 @@
|
||||
needs:
|
||||
- id: survey-enquiry
|
||||
who: a housing board member or private owner with a problem in a building
|
||||
wants: someone from Nordvik Bygg to come and look at the building and tell them what a fix would cost
|
||||
via: Get someone to look at a building
|
||||
lands_in: enquiries
|
||||
handled_by: project_managers
|
||||
done_when: [won, lost]
|
||||
max_steps: 1
|
||||
max_fields: 4
|
||||
|
||||
- id: build-price-enquiry
|
||||
who: an owner who already knows what they want built
|
||||
wants: drawings, a permit application and a price for the work
|
||||
via: Get a price for a build
|
||||
lands_in: enquiries
|
||||
handled_by: project_managers
|
||||
done_when: [won, lost]
|
||||
max_steps: 1
|
||||
max_fields: 5
|
||||
|
||||
- id: subcontractor-application
|
||||
who: a trade firm doing electrical, plumbing or scaffolding work
|
||||
wants: to get on Nordvik Bygg's list of subcontractors they call for work
|
||||
lands_in: subcontractors
|
||||
handled_by: project_managers
|
||||
done_when: [approved, declined]
|
||||
max_steps: 1
|
||||
max_fields: 5
|
||||
|
||||
- id: job-application
|
||||
who: a carpenter or apprentice looking for work
|
||||
wants: to find out if Nordvik Bygg is hiring and put themselves forward
|
||||
lands_in: applicants
|
||||
handled_by: project_managers
|
||||
done_when: [hired, declined]
|
||||
max_steps: 1
|
||||
max_fields: 4
|
||||
|
||||
- id: report-site-issue
|
||||
who: a crew member on site, ours or a subcontractor's
|
||||
wants: to flag a hazard, a near miss or wrong materials fast, from their phone
|
||||
lands_in: site_issues
|
||||
handled_by: safety_officer
|
||||
done_when: [closed]
|
||||
max_steps: 1
|
||||
max_fields: 3
|
||||
|
||||
- id: log-phone-enquiry
|
||||
who: a project manager who just took a call, email or text about a building
|
||||
wants: to get the enquiry into the system before it gets lost
|
||||
enters: /desk/phone-enquiry
|
||||
enters_as: project_managers
|
||||
lands_in: enquiries
|
||||
handled_by: project_managers
|
||||
done_when: [won, lost]
|
||||
max_steps: 1
|
||||
max_fields: 5
|
||||
|
||||
personas:
|
||||
- id: housing-board-cracks
|
||||
need: survey-enquiry
|
||||
text: >
|
||||
There are cracks running up the outside wall of our building and none
|
||||
of us know if it's serious. We just want someone qualified to come
|
||||
look at it and tell us what we're dealing with.
|
||||
|
||||
- id: homeowner-leaking-roof
|
||||
need: survey-enquiry
|
||||
text: >
|
||||
Water's coming through the ceiling every time it rains. I don't know
|
||||
if it's the roof or something else, I just want someone to come out
|
||||
and have a look before it gets worse.
|
||||
|
||||
- id: homeowner-extension
|
||||
need: build-price-enquiry
|
||||
text: >
|
||||
We want to add a room above the garage. We know roughly what we want,
|
||||
we just need someone to draw it up, sort the paperwork with the
|
||||
municipality, and tell us what it will cost.
|
||||
|
||||
- id: owner-basement-conversion
|
||||
need: build-price-enquiry
|
||||
text: >
|
||||
I'd like to turn the basement into a flat. Need drawings, the permit
|
||||
sorted, and a proper price before I commit to anything.
|
||||
|
||||
- id: electrician-more-work
|
||||
need: subcontractor-application
|
||||
text: >
|
||||
We're a small electrical firm and we'd like to pick up more building
|
||||
work. We're registered and insured, just need to know who to talk to
|
||||
about getting on your books.
|
||||
|
||||
- id: scaffolding-firm
|
||||
need: subcontractor-application
|
||||
text: >
|
||||
We put up and take down scaffolding for building sites. We'd like to
|
||||
be one of the firms you call when a job needs it.
|
||||
|
||||
- id: apprentice-asking
|
||||
need: job-application
|
||||
text: >
|
||||
I'm in my second year as an apprentice carpenter and looking for a
|
||||
firm that'll keep me on after. Are you taking anyone on right now?
|
||||
|
||||
- id: experienced-carpenter
|
||||
need: job-application
|
||||
text: >
|
||||
I've been doing carpentry for eight years, mostly older buildings.
|
||||
Wondered if you had any openings on site.
|
||||
|
||||
- id: crew-loose-scaffold
|
||||
need: report-site-issue
|
||||
text: >
|
||||
Noticed a scaffold board that's not sitting right, feels loose when
|
||||
you step on it. Wanted to flag it straight away before someone gets
|
||||
hurt, but I've got gloves on and no time for a long form.
|
||||
|
||||
- id: subcontractor-wrong-delivery
|
||||
need: report-site-issue
|
||||
text: >
|
||||
The delivery this morning was the wrong type of insulation, not what
|
||||
was on the drawings. Someone needs to know before it gets used.
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
name: What happens with your application now?
|
||||
description: >
|
||||
A project manager reads every application. If it looks like a good fit
|
||||
we'll be in touch to arrange an interview.
|
||||
alternatives:
|
||||
- name: Back to the start
|
||||
description: Return to the front page.
|
||||
action: /
|
||||
consequence: [Back]
|
||||
+1
@@ -0,0 +1 @@
|
||||
qualifies: project_managers
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
name: What came in?
|
||||
responsible: { name: Ingrid Nordvik, contact: ingrid@nordvikbygg.example }
|
||||
alternatives:
|
||||
- name: Enquiries
|
||||
description: Move each enquiry on as you work it.
|
||||
action: /desk
|
||||
consequence: [Update]
|
||||
features:
|
||||
- name: ""
|
||||
description: ""
|
||||
resource:
|
||||
source: { kind: kv, bucket: enquiries }
|
||||
requires_group: project_managers
|
||||
transitions:
|
||||
- { to: quoted, label: Quote sent }
|
||||
- { to: lost, label: Not for us }
|
||||
- { from: quoted, to: won, label: Won }
|
||||
- { from: quoted, to: lost, label: Lost }
|
||||
|
||||
- name: Subcontractors
|
||||
description: Check papers and approve or decline each application.
|
||||
action: /desk
|
||||
consequence: [Update]
|
||||
features:
|
||||
- name: ""
|
||||
description: ""
|
||||
resource:
|
||||
source: { kind: kv, bucket: subcontractors }
|
||||
requires_group: project_managers
|
||||
transitions:
|
||||
- { to: awaiting_papers, label: Ask for missing papers }
|
||||
- { to: approved, label: Approve }
|
||||
- { to: declined, label: Decline }
|
||||
- { from: awaiting_papers, to: approved, label: Approve }
|
||||
- { from: awaiting_papers, to: declined, label: Decline }
|
||||
|
||||
- name: Applicants
|
||||
description: Move each job application through interview to a decision.
|
||||
action: /desk
|
||||
consequence: [Update]
|
||||
features:
|
||||
- name: ""
|
||||
description: ""
|
||||
resource:
|
||||
source: { kind: kv, bucket: applicants }
|
||||
requires_group: project_managers
|
||||
transitions:
|
||||
- { to: interviewing, label: Invite to interview }
|
||||
- { to: declined, label: Decline }
|
||||
- { from: interviewing, to: hired, label: Hire }
|
||||
- { from: interviewing, to: declined, label: Decline }
|
||||
|
||||
- name: Log a call, email or text
|
||||
description: >
|
||||
Get an enquiry that came in by phone, email or text into the system
|
||||
before it's lost.
|
||||
action: /desk/phone-enquiry
|
||||
consequence: [Log it]
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
name: What happens with this enquiry now?
|
||||
description: >
|
||||
It's in with the rest of the enquiries on the desk, ready to work the
|
||||
same way as one that came in through the front page.
|
||||
alternatives:
|
||||
- name: Back to the start
|
||||
description: Return to the front page.
|
||||
action: /
|
||||
consequence: [Back]
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
name: What did they tell you?
|
||||
description: >
|
||||
Get it down before it gets lost. This creates the same kind of record
|
||||
as one submitted through the front page.
|
||||
responsible: { name: Ingrid Nordvik, contact: ingrid@nordvikbygg.example }
|
||||
alternatives:
|
||||
- name: Log this enquiry
|
||||
description: ""
|
||||
action: /desk/phone-enquiry-logged
|
||||
consequence: [Save]
|
||||
record_as: enquiries
|
||||
features:
|
||||
- name: About the caller and the building
|
||||
description: ""
|
||||
requirements:
|
||||
- { name: caller_name, label: Their name, type: text }
|
||||
- { name: contact, label: Phone or email, type: text }
|
||||
- { name: address, label: Address of the building, type: text }
|
||||
- { name: problem, label: What they told you, type: textarea }
|
||||
- { name: urgency, label: How soon, type: select, options: [This week, This month, No rush] }
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
name: What happens with your enquiry now?
|
||||
description: >
|
||||
One of our two project managers reads every enquiry as it comes in.
|
||||
We'll usually be in touch within a couple of working days to arrange a
|
||||
look at the building, or to say plainly if it's not something we take
|
||||
on.
|
||||
alternatives:
|
||||
- name: Back to the start
|
||||
description: Return to the front page.
|
||||
action: /
|
||||
consequence: [Back]
|
||||
@@ -0,0 +1,85 @@
|
||||
name: What brings you here?
|
||||
description: >
|
||||
Pick what best matches why you're here today.
|
||||
responsible: { name: Ingrid Nordvik, contact: ingrid@nordvikbygg.example }
|
||||
alternatives:
|
||||
- name: Get someone to look at a building
|
||||
description: >
|
||||
For housing boards and private owners with a problem in a building
|
||||
who want us to come and take a look.
|
||||
action: /enquiries/thanks
|
||||
consequence: [Send]
|
||||
record_as: enquiries
|
||||
features:
|
||||
- name: About you and the building
|
||||
description: ""
|
||||
requirements:
|
||||
- { name: name, label: Your name, type: text }
|
||||
- { name: email, label: Email, type: email }
|
||||
- { name: address, label: Address of the building, type: text }
|
||||
- { name: problem, label: What's wrong, type: textarea }
|
||||
|
||||
- name: Get a price for a build
|
||||
description: >
|
||||
For owners who already know what they want built and need drawings,
|
||||
a permit application and a price.
|
||||
action: /enquiries/thanks
|
||||
consequence: [Send]
|
||||
record_as: enquiries
|
||||
features:
|
||||
- name: About you and the build
|
||||
description: ""
|
||||
requirements:
|
||||
- { name: name, label: Your name, type: text }
|
||||
- { name: email, label: Email, type: email }
|
||||
- { name: address, label: Address of the site, type: text }
|
||||
- { name: project, label: What you want built, type: textarea }
|
||||
- { name: timeframe, label: When you'd like to start, type: select, options: [As soon as possible, Within a year, Just exploring] }
|
||||
|
||||
- name: Join our subcontractor list
|
||||
description: >
|
||||
For electrical, plumbing and scaffolding firms who want to be one of
|
||||
the firms we call when a job needs them.
|
||||
action: /subcontractors/thanks
|
||||
consequence: [Apply]
|
||||
record_as: subcontractors
|
||||
features:
|
||||
- name: About your firm
|
||||
description: ""
|
||||
requirements:
|
||||
- { name: company_name, label: Company name, type: text }
|
||||
- { name: contact_email, label: Email, type: email }
|
||||
- { name: trade, label: Trade, type: select, options: [Electrical, Plumbing, Scaffolding] }
|
||||
- { name: registration_number, label: Company registration number, type: text }
|
||||
- { name: insurance, label: Insurance policy details, type: text }
|
||||
- { name: trade_approval, label: Trade approval reference, optional: true }
|
||||
|
||||
- name: Ask about working with us
|
||||
description: >
|
||||
For carpenters and apprentices who want to know if we're hiring.
|
||||
action: /applicants/thanks
|
||||
consequence: [Send]
|
||||
record_as: applicants
|
||||
features:
|
||||
- name: About you
|
||||
description: ""
|
||||
requirements:
|
||||
- { name: name, label: Your name, type: text }
|
||||
- { name: email, label: Email, type: email }
|
||||
- { name: role, label: What you do, type: select, options: [Carpenter, Apprentice carpenter, Other] }
|
||||
- { name: message, label: Anything else we should know, type: textarea }
|
||||
|
||||
- name: Report something from site
|
||||
description: >
|
||||
For crew on site, ours or a subcontractor's, who've spotted a hazard,
|
||||
a near miss or the wrong materials.
|
||||
action: /site-issues/thanks
|
||||
consequence: [Report it]
|
||||
record_as: site_issues
|
||||
features:
|
||||
- name: What's happened
|
||||
description: ""
|
||||
requirements:
|
||||
- { name: issue_type, label: What kind of issue, type: select, options: [Hazard, Near miss, Wrong materials delivered] }
|
||||
- { name: location, label: Where on site, type: text }
|
||||
- { name: details, label: What happened, type: textarea }
|
||||
+1
@@ -0,0 +1 @@
|
||||
qualifies: safety_officer
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
name: What's been reported from site?
|
||||
responsible: { name: Ingrid Nordvik, contact: ingrid@nordvikbygg.example }
|
||||
alternatives:
|
||||
- name: Site issues
|
||||
description: Decide what needs doing, then close it out once it's fixed.
|
||||
action: /safety
|
||||
consequence: [Update]
|
||||
features:
|
||||
- name: ""
|
||||
description: ""
|
||||
resource:
|
||||
source: { kind: kv, bucket: site_issues }
|
||||
requires_group: safety_officer
|
||||
transitions:
|
||||
- { to: in_hand, label: Look into it }
|
||||
- { from: in_hand, to: closed, label: Mark fixed }
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
name: What happens with your report now?
|
||||
description: >
|
||||
Our safety officer sees every report as it comes in and decides what
|
||||
needs to be done. You'll see it marked fixed once it's sorted.
|
||||
alternatives:
|
||||
- name: Back to the start
|
||||
description: Return to the front page.
|
||||
action: /
|
||||
consequence: [Back]
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
name: What happens with your application now?
|
||||
description: >
|
||||
A project manager checks your company registration, trade approval and
|
||||
insurance. If anything's missing we'll come back to you for it before
|
||||
we can put you on the list.
|
||||
alternatives:
|
||||
- name: Back to the start
|
||||
description: Return to the front page.
|
||||
action: /
|
||||
consequence: [Back]
|
||||
@@ -0,0 +1,3 @@
|
||||
needs: parsed in round 1
|
||||
structure round 1: ok=true fails=0
|
||||
wording round 0: headings only: wording: 10/10 routed right (100%) | headings and descriptions: wording: 10/10 routed right (100%)
|
||||
@@ -0,0 +1,2 @@
|
||||
title: Nordvik Bygg
|
||||
lang: en
|
||||
@@ -0,0 +1,10 @@
|
||||
{"id":"housing-board-cracks@/","persona":"housing-board-cracks","need":"survey-enquiry","page":"/","state":{"body":"There are cracks running up the outside wall of our building and none of us know if it's serious. We just want someone qualified to come look at it and tell us what we're dealing with."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Get someone to look at a building"]}
|
||||
{"id":"homeowner-leaking-roof@/","persona":"homeowner-leaking-roof","need":"survey-enquiry","page":"/","state":{"body":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Get someone to look at a building"]}
|
||||
{"id":"homeowner-extension@/","persona":"homeowner-extension","need":"build-price-enquiry","page":"/","state":{"body":"We want to add a room above the garage. We know roughly what we want, we just need someone to draw it up, sort the paperwork with the municipality, and tell us what it will cost."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Get a price for a build"]}
|
||||
{"id":"owner-basement-conversion@/","persona":"owner-basement-conversion","need":"build-price-enquiry","page":"/","state":{"body":"I'd like to turn the basement into a flat. Need drawings, the permit sorted, and a proper price before I commit to anything."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Get a price for a build"]}
|
||||
{"id":"electrician-more-work@/","persona":"electrician-more-work","need":"subcontractor-application","page":"/","state":{"body":"We're a small electrical firm and we'd like to pick up more building work. We're registered and insured, just need to know who to talk to about getting on your books."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Join our subcontractor list"]}
|
||||
{"id":"scaffolding-firm@/","persona":"scaffolding-firm","need":"subcontractor-application","page":"/","state":{"body":"We put up and take down scaffolding for building sites. We'd like to be one of the firms you call when a job needs it."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Join our subcontractor list"]}
|
||||
{"id":"apprentice-asking@/","persona":"apprentice-asking","need":"job-application","page":"/","state":{"body":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after. Are you taking anyone on right now?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Ask about working with us"]}
|
||||
{"id":"experienced-carpenter@/","persona":"experienced-carpenter","need":"job-application","page":"/","state":{"body":"I've been doing carpentry for eight years, mostly older buildings. Wondered if you had any openings on site."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Ask about working with us"]}
|
||||
{"id":"crew-loose-scaffold@/","persona":"crew-loose-scaffold","need":"report-site-issue","page":"/","state":{"body":"Noticed a scaffold board that's not sitting right, feels loose when you step on it. Wanted to flag it straight away before someone gets hurt, but I've got gloves on and no time for a long form."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Report something from site"]}
|
||||
{"id":"subcontractor-wrong-delivery@/","persona":"subcontractor-wrong-delivery","need":"report-site-issue","page":"/","state":{"body":"The delivery this morning was the wrong type of insulation, not what was on the drawings. Someone needs to know before it gets used."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Report something from site"]}
|
||||
@@ -0,0 +1,10 @@
|
||||
{"id":"housing-board-cracks@/","persona":"housing-board-cracks","need":"survey-enquiry","page":"/","state":{"body":"There are cracks running up the outside wall of our building and none of us know if it's serious. We just want someone qualified to come look at it and tell us what we're dealing with."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Get someone to look at a building"]}
|
||||
{"id":"homeowner-leaking-roof@/","persona":"homeowner-leaking-roof","need":"survey-enquiry","page":"/","state":{"body":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Get someone to look at a building"]}
|
||||
{"id":"homeowner-extension@/","persona":"homeowner-extension","need":"build-price-enquiry","page":"/","state":{"body":"We want to add a room above the garage. We know roughly what we want, we just need someone to draw it up, sort the paperwork with the municipality, and tell us what it will cost."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Get a price for a build"]}
|
||||
{"id":"owner-basement-conversion@/","persona":"owner-basement-conversion","need":"build-price-enquiry","page":"/","state":{"body":"I'd like to turn the basement into a flat. Need drawings, the permit sorted, and a proper price before I commit to anything."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Get a price for a build"]}
|
||||
{"id":"electrician-more-work@/","persona":"electrician-more-work","need":"subcontractor-application","page":"/","state":{"body":"We're a small electrical firm and we'd like to pick up more building work. We're registered and insured, just need to know who to talk to about getting on your books."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Join our subcontractor list"]}
|
||||
{"id":"scaffolding-firm@/","persona":"scaffolding-firm","need":"subcontractor-application","page":"/","state":{"body":"We put up and take down scaffolding for building sites. We'd like to be one of the firms you call when a job needs it."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Join our subcontractor list"]}
|
||||
{"id":"apprentice-asking@/","persona":"apprentice-asking","need":"job-application","page":"/","state":{"body":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after. Are you taking anyone on right now?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Ask about working with us"]}
|
||||
{"id":"experienced-carpenter@/","persona":"experienced-carpenter","need":"job-application","page":"/","state":{"body":"I've been doing carpentry for eight years, mostly older buildings. Wondered if you had any openings on site."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Ask about working with us"]}
|
||||
{"id":"crew-loose-scaffold@/","persona":"crew-loose-scaffold","need":"report-site-issue","page":"/","state":{"body":"Noticed a scaffold board that's not sitting right, feels loose when you step on it. Wanted to flag it straight away before someone gets hurt, but I've got gloves on and no time for a long form."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Report something from site"]}
|
||||
{"id":"subcontractor-wrong-delivery@/","persona":"subcontractor-wrong-delivery","need":"report-site-issue","page":"/","state":{"body":"The delivery this morning was the wrong type of insulation, not what was on the drawings. Someone needs to know before it gets used."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Report something from site"]}
|
||||
@@ -0,0 +1,4 @@
|
||||
needs round 1: needs.yaml parses, frozen
|
||||
structure round 1: green
|
||||
wording round 0: headings only: wording: 10/10 routed right (100%) | headings and descriptions: wording: 10/10 routed right (100%)
|
||||
content repo written to /tmp/claude-1000/-home-bl-repos-portal/b7802cea-728f-42d2-a751-680a973ba17d/scratchpad/gen/repo
|
||||
@@ -0,0 +1,10 @@
|
||||
{"id":"housing-board-damp@/","choice":"Get someone to look at a building","confidence":0.99}
|
||||
{"id":"buyer-before-purchase@/","choice":"Get someone to look at a building","confidence":0.99}
|
||||
{"id":"attic-conversion@/","choice":"Get a price for a build","confidence":0.99}
|
||||
{"id":"shop-to-flat@/","choice":"Get a price for a build","confidence":0.99}
|
||||
{"id":"electrician-firm@/","choice":"Join our subcontractor list","confidence":0.99}
|
||||
{"id":"scaffolder@/","choice":"Join our subcontractor list","confidence":0.99}
|
||||
{"id":"carpenter-jobseeker@/","choice":"Ask about working with us","confidence":0.99}
|
||||
{"id":"apprentice@/","choice":"Ask about working with us","confidence":0.99}
|
||||
{"id":"loose-railing@/","choice":"Report something from site","confidence":0.99}
|
||||
{"id":"wrong-membrane@/","choice":"Report something from site","confidence":0.99}
|
||||
@@ -0,0 +1,10 @@
|
||||
{"id":"housing-board-damp@/","choice":"Get someone to look at a building","confidence":0.95}
|
||||
{"id":"buyer-before-purchase@/","choice":"Get someone to look at a building","confidence":0.95}
|
||||
{"id":"attic-conversion@/","choice":"Get someone to look at a building","confidence":0.95}
|
||||
{"id":"shop-to-flat@/","choice":"Get a price for a build","confidence":0.95}
|
||||
{"id":"electrician-firm@/","choice":"Join our subcontractor list","confidence":0.95}
|
||||
{"id":"scaffolder@/","choice":"Ask about working with us","confidence":0.95}
|
||||
{"id":"carpenter-jobseeker@/","choice":"Ask about working with us","confidence":0.95}
|
||||
{"id":"apprentice@/","choice":"Ask about working with us","confidence":0.95}
|
||||
{"id":"loose-railing@/","choice":"Report something from site","confidence":0.95}
|
||||
{"id":"wrong-membrane@/","choice":"Report something from site","confidence":0.95}
|
||||
@@ -0,0 +1,10 @@
|
||||
{"id":"housing-board-damp@/","persona":"housing-board-damp","need":"survey-enquiry","page":"/","state":{"body":"I chair the board of a housing cooperative from the seventies. Two ground-floor flats have damp in the walls and we don't know if it's drainage or the facade. We need someone to tell us."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Get someone to look at a building"]}
|
||||
{"id":"buyer-before-purchase@/","persona":"buyer-before-purchase","need":"survey-enquiry","page":"/","state":{"body":"We are about to buy an old timber house. Before we sign we want a professional to go through it and tell us what is wrong with it."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Get someone to look at a building"]}
|
||||
{"id":"attic-conversion@/","persona":"attic-conversion","need":"build-price-enquiry","page":"/","state":{"body":"We want to turn our attic into two bedrooms and a bathroom. We need drawings and someone who handles the application to the municipality."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Get a price for a build"]}
|
||||
{"id":"shop-to-flat@/","persona":"shop-to-flat","need":"build-price-enquiry","page":"/","state":{"body":"I own a former shop on the ground floor and want to make it a flat. I have no idea what is allowed. Can you sort that out and give me a price?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Get a price for a build"]}
|
||||
{"id":"electrician-firm@/","persona":"electrician-firm","need":"subcontractor-application","page":"/","state":{"body":"We are a four-person electrical firm, fully certified. We would like to get on your list so you call us when you need electricians."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Join our subcontractor list"]}
|
||||
{"id":"scaffolder@/","persona":"scaffolder","need":"subcontractor-application","page":"/","state":{"body":"I run a scaffolding company. How do I get to do jobs for you?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Join our subcontractor list"]}
|
||||
{"id":"carpenter-jobseeker@/","persona":"carpenter-jobseeker","need":"job-application","page":"/","state":{"body":"I'm a certified carpenter with eight years on rehabilitation jobs. Are you hiring?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Ask about working with us"]}
|
||||
{"id":"apprentice@/","persona":"apprentice","need":"job-application","page":"/","state":{"body":"I finish vocational school this spring and need an apprenticeship as a bricklayer."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Ask about working with us"]}
|
||||
{"id":"loose-railing@/","persona":"loose-railing","need":"report-site-issue","page":"/","state":{"body":"The railing on the third level of the scaffold on the north side is loose. Nobody got hurt but someone will."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Report something from site"]}
|
||||
{"id":"wrong-membrane@/","persona":"wrong-membrane","need":"report-site-issue","page":"/","state":{"body":"The bathroom membrane delivered today is not the one in the specification. We stopped work on it."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"For carpenters and apprentices who want to know if we're hiring.","Get a price for a build":"For owners who already know what they want built and need drawings, a permit application and a price.","Get someone to look at a building":"For housing boards and private owners with a problem in a building who want us to come and take a look.","Join our subcontractor list":"For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.","Report something from site":"For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials."}}},"expect":["Report something from site"]}
|
||||
@@ -0,0 +1,10 @@
|
||||
{"id":"housing-board-damp@/","persona":"housing-board-damp","need":"survey-enquiry","page":"/","state":{"body":"I chair the board of a housing cooperative from the seventies. Two ground-floor flats have damp in the walls and we don't know if it's drainage or the facade. We need someone to tell us."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Get someone to look at a building"]}
|
||||
{"id":"buyer-before-purchase@/","persona":"buyer-before-purchase","need":"survey-enquiry","page":"/","state":{"body":"We are about to buy an old timber house. Before we sign we want a professional to go through it and tell us what is wrong with it."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Get someone to look at a building"]}
|
||||
{"id":"attic-conversion@/","persona":"attic-conversion","need":"build-price-enquiry","page":"/","state":{"body":"We want to turn our attic into two bedrooms and a bathroom. We need drawings and someone who handles the application to the municipality."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Get a price for a build"]}
|
||||
{"id":"shop-to-flat@/","persona":"shop-to-flat","need":"build-price-enquiry","page":"/","state":{"body":"I own a former shop on the ground floor and want to make it a flat. I have no idea what is allowed. Can you sort that out and give me a price?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Get a price for a build"]}
|
||||
{"id":"electrician-firm@/","persona":"electrician-firm","need":"subcontractor-application","page":"/","state":{"body":"We are a four-person electrical firm, fully certified. We would like to get on your list so you call us when you need electricians."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Join our subcontractor list"]}
|
||||
{"id":"scaffolder@/","persona":"scaffolder","need":"subcontractor-application","page":"/","state":{"body":"I run a scaffolding company. How do I get to do jobs for you?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Join our subcontractor list"]}
|
||||
{"id":"carpenter-jobseeker@/","persona":"carpenter-jobseeker","need":"job-application","page":"/","state":{"body":"I'm a certified carpenter with eight years on rehabilitation jobs. Are you hiring?"},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Ask about working with us"]}
|
||||
{"id":"apprentice@/","persona":"apprentice","need":"job-application","page":"/","state":{"body":"I finish vocational school this spring and need an apprenticeship as a bricklayer."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Ask about working with us"]}
|
||||
{"id":"loose-railing@/","persona":"loose-railing","need":"report-site-issue","page":"/","state":{"body":"The railing on the third level of the scaffold on the north side is loose. Nobody got hurt but someone will."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Report something from site"]}
|
||||
{"id":"wrong-membrane@/","persona":"wrong-membrane","need":"report-site-issue","page":"/","state":{"body":"The bathroom membrane delivered today is not the one in the specification. We stopped work on it."},"questions":{"pick":{"type":"choice","instructions":"A visitor reads the page question \"What brings you here?\". Which alternative do they choose?","criteria":{"Ask about working with us":"Ask about working with us","Get a price for a build":"Get a price for a build","Get someone to look at a building":"Get someone to look at a building","Join our subcontractor list":"Join our subcontractor list","Report something from site":"Report something from site"}}},"expect":["Report something from site"]}
|
||||
+720
@@ -0,0 +1,720 @@
|
||||
{
|
||||
"buckets": {
|
||||
"applicants": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Invite to interview",
|
||||
"to": "interviewing"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
},
|
||||
{
|
||||
"from": "interviewing",
|
||||
"label": "Hire",
|
||||
"to": "hired"
|
||||
},
|
||||
{
|
||||
"from": "interviewing",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"interviewing": [
|
||||
"hired",
|
||||
"declined"
|
||||
],
|
||||
"open": [
|
||||
"interviewing",
|
||||
"declined"
|
||||
]
|
||||
}
|
||||
},
|
||||
"enquiries": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Looked at the building",
|
||||
"to": "surveyed"
|
||||
},
|
||||
{
|
||||
"from": "surveyed",
|
||||
"label": "Quote sent",
|
||||
"to": "quoted"
|
||||
},
|
||||
{
|
||||
"from": "surveyed",
|
||||
"label": "Not worth quoting",
|
||||
"to": "lost"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Not for us",
|
||||
"to": "lost"
|
||||
},
|
||||
{
|
||||
"from": "quoted",
|
||||
"label": "Won",
|
||||
"to": "won"
|
||||
},
|
||||
{
|
||||
"from": "quoted",
|
||||
"label": "Lost",
|
||||
"to": "lost"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"open": [
|
||||
"surveyed",
|
||||
"lost"
|
||||
],
|
||||
"quoted": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"surveyed": [
|
||||
"quoted",
|
||||
"lost"
|
||||
]
|
||||
}
|
||||
},
|
||||
"site_issues": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "safety_officer",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Look into it",
|
||||
"to": "in_hand"
|
||||
},
|
||||
{
|
||||
"from": "in_hand",
|
||||
"label": "Mark fixed",
|
||||
"to": "closed"
|
||||
}
|
||||
],
|
||||
"page": "/safety"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"in_hand": [
|
||||
"closed"
|
||||
],
|
||||
"open": [
|
||||
"in_hand"
|
||||
]
|
||||
}
|
||||
},
|
||||
"subcontractors": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Ask for missing papers",
|
||||
"to": "awaiting_papers"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Approve",
|
||||
"to": "approved"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
},
|
||||
{
|
||||
"from": "awaiting_papers",
|
||||
"label": "Approve",
|
||||
"to": "approved"
|
||||
},
|
||||
{
|
||||
"from": "awaiting_papers",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"awaiting_papers": [
|
||||
"approved",
|
||||
"declined"
|
||||
],
|
||||
"open": [
|
||||
"awaiting_papers",
|
||||
"approved",
|
||||
"declined"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"needs": [
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "survey-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Get someone to look at a building",
|
||||
"expect": [
|
||||
"Get someone to look at a building"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Address of the building",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What's wrong",
|
||||
"name": "problem",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "Submission of requests pertaining to structural or condition-related evaluation of existing properties.",
|
||||
"name": "Building condition assessment request"
|
||||
},
|
||||
{
|
||||
"description": "Applicants must provide documentation of intended works for the purposes of cost estimation.",
|
||||
"name": "Construction quotation request"
|
||||
},
|
||||
{
|
||||
"description": "Registration of enterprises for prequalification subject to verification of mandatory documentation.",
|
||||
"name": "Subcontractor prequalification"
|
||||
},
|
||||
{
|
||||
"description": "Unsolicited applications are processed in accordance with applicable recruitment procedures.",
|
||||
"name": "Employment enquiries"
|
||||
},
|
||||
{
|
||||
"description": "Mandatory registration of nonconformities in accordance with internal control requirements.",
|
||||
"name": "Deviation and incident reporting"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "Please select the applicable category for your submission"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "someone from Nordvik Bygg to come and look at the building and tell them what a fix would cost",
|
||||
"who": "a housing board member or private owner with a problem in a building"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "build-price-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Get a price for a build",
|
||||
"expect": [
|
||||
"Get a price for a build"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Address of the site",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What you want built",
|
||||
"name": "project",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
},
|
||||
{
|
||||
"label": "When you'd like to start",
|
||||
"name": "timeframe",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"As soon as possible",
|
||||
"Within a year",
|
||||
"Just exploring"
|
||||
],
|
||||
"type": "select"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "Submission of requests pertaining to structural or condition-related evaluation of existing properties.",
|
||||
"name": "Building condition assessment request"
|
||||
},
|
||||
{
|
||||
"description": "Applicants must provide documentation of intended works for the purposes of cost estimation.",
|
||||
"name": "Construction quotation request"
|
||||
},
|
||||
{
|
||||
"description": "Registration of enterprises for prequalification subject to verification of mandatory documentation.",
|
||||
"name": "Subcontractor prequalification"
|
||||
},
|
||||
{
|
||||
"description": "Unsolicited applications are processed in accordance with applicable recruitment procedures.",
|
||||
"name": "Employment enquiries"
|
||||
},
|
||||
{
|
||||
"description": "Mandatory registration of nonconformities in accordance with internal control requirements.",
|
||||
"name": "Deviation and incident reporting"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "Please select the applicable category for your submission"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "drawings, a permit application and a price for the work",
|
||||
"who": "an owner who already knows what they want built"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"approved",
|
||||
"declined"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "subcontractor-application",
|
||||
"lands_in": "subcontractors",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Join our subcontractor list",
|
||||
"expect": [
|
||||
"Join our subcontractor list"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Company name",
|
||||
"name": "company_name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "contact_email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Trade",
|
||||
"name": "trade",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Electrical",
|
||||
"Plumbing",
|
||||
"Scaffolding"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Company registration number",
|
||||
"name": "registration_number",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Insurance policy details",
|
||||
"name": "insurance",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Trade approval reference",
|
||||
"name": "trade_approval",
|
||||
"optional": true,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "Submission of requests pertaining to structural or condition-related evaluation of existing properties.",
|
||||
"name": "Building condition assessment request"
|
||||
},
|
||||
{
|
||||
"description": "Applicants must provide documentation of intended works for the purposes of cost estimation.",
|
||||
"name": "Construction quotation request"
|
||||
},
|
||||
{
|
||||
"description": "Registration of enterprises for prequalification subject to verification of mandatory documentation.",
|
||||
"name": "Subcontractor prequalification"
|
||||
},
|
||||
{
|
||||
"description": "Unsolicited applications are processed in accordance with applicable recruitment procedures.",
|
||||
"name": "Employment enquiries"
|
||||
},
|
||||
{
|
||||
"description": "Mandatory registration of nonconformities in accordance with internal control requirements.",
|
||||
"name": "Deviation and incident reporting"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "Please select the applicable category for your submission"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"approved"
|
||||
],
|
||||
"wants": "to get on Nordvik Bygg's list of subcontractors they call for work",
|
||||
"who": "a trade firm doing electrical, plumbing or scaffolding work"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"hired",
|
||||
"declined"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "job-application",
|
||||
"lands_in": "applicants",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Ask about working with us",
|
||||
"expect": [
|
||||
"Ask about working with us"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "What you do",
|
||||
"name": "role",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Carpenter",
|
||||
"Apprentice carpenter",
|
||||
"Other"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Anything else we should know",
|
||||
"name": "message",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "Submission of requests pertaining to structural or condition-related evaluation of existing properties.",
|
||||
"name": "Building condition assessment request"
|
||||
},
|
||||
{
|
||||
"description": "Applicants must provide documentation of intended works for the purposes of cost estimation.",
|
||||
"name": "Construction quotation request"
|
||||
},
|
||||
{
|
||||
"description": "Registration of enterprises for prequalification subject to verification of mandatory documentation.",
|
||||
"name": "Subcontractor prequalification"
|
||||
},
|
||||
{
|
||||
"description": "Unsolicited applications are processed in accordance with applicable recruitment procedures.",
|
||||
"name": "Employment enquiries"
|
||||
},
|
||||
{
|
||||
"description": "Mandatory registration of nonconformities in accordance with internal control requirements.",
|
||||
"name": "Deviation and incident reporting"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "Please select the applicable category for your submission"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"hired"
|
||||
],
|
||||
"wants": "to find out if Nordvik Bygg is hiring and put themselves forward",
|
||||
"who": "a carpenter or apprentice looking for work"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"closed"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "safety_officer",
|
||||
"id": "report-site-issue",
|
||||
"lands_in": "site_issues",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Report something from site",
|
||||
"expect": [
|
||||
"Report something from site"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "What kind of issue",
|
||||
"name": "issue_type",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Hazard",
|
||||
"Near miss",
|
||||
"Wrong materials delivered"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Where on site",
|
||||
"name": "location",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What happened",
|
||||
"name": "details",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "Submission of requests pertaining to structural or condition-related evaluation of existing properties.",
|
||||
"name": "Building condition assessment request"
|
||||
},
|
||||
{
|
||||
"description": "Applicants must provide documentation of intended works for the purposes of cost estimation.",
|
||||
"name": "Construction quotation request"
|
||||
},
|
||||
{
|
||||
"description": "Registration of enterprises for prequalification subject to verification of mandatory documentation.",
|
||||
"name": "Subcontractor prequalification"
|
||||
},
|
||||
{
|
||||
"description": "Unsolicited applications are processed in accordance with applicable recruitment procedures.",
|
||||
"name": "Employment enquiries"
|
||||
},
|
||||
{
|
||||
"description": "Mandatory registration of nonconformities in accordance with internal control requirements.",
|
||||
"name": "Deviation and incident reporting"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "Please select the applicable category for your submission"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"closed"
|
||||
],
|
||||
"wants": "to flag a hazard, a near miss or wrong materials fast, from their phone",
|
||||
"who": "a crew member on site, ours or a subcontractor's"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": "project_managers",
|
||||
"handled_by": "project_managers",
|
||||
"id": "log-phone-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Log this enquiry",
|
||||
"expect": [
|
||||
"Log this enquiry"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Their name",
|
||||
"name": "caller_name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Phone or email",
|
||||
"name": "contact",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Address of the building",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What they told you",
|
||||
"name": "problem",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
},
|
||||
{
|
||||
"label": "How soon",
|
||||
"name": "urgency",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"This week",
|
||||
"This month",
|
||||
"No rush"
|
||||
],
|
||||
"type": "select"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "",
|
||||
"name": "Log this enquiry"
|
||||
}
|
||||
],
|
||||
"page": "/desk/phone-enquiry",
|
||||
"question": "Please select the applicable category for your submission"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "to get the enquiry into the system before it gets lost",
|
||||
"who": "a project manager who just took a call, email or text about a building"
|
||||
}
|
||||
],
|
||||
"personas": [
|
||||
{
|
||||
"id": "housing-board-cracks",
|
||||
"need": "survey-enquiry",
|
||||
"text": "There are cracks running up the outside wall of our building and none of us know if it's serious. We just want someone qualified to come look at it and tell us what we're dealing with."
|
||||
},
|
||||
{
|
||||
"id": "homeowner-leaking-roof",
|
||||
"need": "survey-enquiry",
|
||||
"text": "Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse."
|
||||
},
|
||||
{
|
||||
"id": "homeowner-extension",
|
||||
"need": "build-price-enquiry",
|
||||
"text": "We want to add a room above the garage. We know roughly what we want, we just need someone to draw it up, sort the paperwork with the municipality, and tell us what it will cost."
|
||||
},
|
||||
{
|
||||
"id": "owner-basement-conversion",
|
||||
"need": "build-price-enquiry",
|
||||
"text": "I'd like to turn the basement into a flat. Need drawings, the permit sorted, and a proper price before I commit to anything."
|
||||
},
|
||||
{
|
||||
"id": "electrician-more-work",
|
||||
"need": "subcontractor-application",
|
||||
"text": "We're a small electrical firm and we'd like to pick up more building work. We're registered and insured, just need to know who to talk to about getting on your books."
|
||||
},
|
||||
{
|
||||
"id": "scaffolding-firm",
|
||||
"need": "subcontractor-application",
|
||||
"text": "We put up and take down scaffolding for building sites. We'd like to be one of the firms you call when a job needs it."
|
||||
},
|
||||
{
|
||||
"id": "apprentice-asking",
|
||||
"need": "job-application",
|
||||
"text": "I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after. Are you taking anyone on right now?"
|
||||
},
|
||||
{
|
||||
"id": "experienced-carpenter",
|
||||
"need": "job-application",
|
||||
"text": "I've been doing carpentry for eight years, mostly older buildings. Wondered if you had any openings on site."
|
||||
},
|
||||
{
|
||||
"id": "crew-loose-scaffold",
|
||||
"need": "report-site-issue",
|
||||
"text": "Noticed a scaffold board that's not sitting right, feels loose when you step on it. Wanted to flag it straight away before someone gets hurt, but I've got gloves on and no time for a long form."
|
||||
},
|
||||
{
|
||||
"id": "subcontractor-wrong-delivery",
|
||||
"need": "report-site-issue",
|
||||
"text": "The delivery this morning was the wrong type of insulation, not what was on the drawings. Someone needs to know before it gets used."
|
||||
}
|
||||
]
|
||||
}
|
||||
+720
@@ -0,0 +1,720 @@
|
||||
{
|
||||
"buckets": {
|
||||
"applicants": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Invite to interview",
|
||||
"to": "interviewing"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
},
|
||||
{
|
||||
"from": "interviewing",
|
||||
"label": "Hire",
|
||||
"to": "hired"
|
||||
},
|
||||
{
|
||||
"from": "interviewing",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"interviewing": [
|
||||
"hired",
|
||||
"declined"
|
||||
],
|
||||
"open": [
|
||||
"interviewing",
|
||||
"declined"
|
||||
]
|
||||
}
|
||||
},
|
||||
"enquiries": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Looked at the building",
|
||||
"to": "surveyed"
|
||||
},
|
||||
{
|
||||
"from": "surveyed",
|
||||
"label": "Quote sent",
|
||||
"to": "quoted"
|
||||
},
|
||||
{
|
||||
"from": "surveyed",
|
||||
"label": "Not worth quoting",
|
||||
"to": "lost"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Not for us",
|
||||
"to": "lost"
|
||||
},
|
||||
{
|
||||
"from": "quoted",
|
||||
"label": "Won",
|
||||
"to": "won"
|
||||
},
|
||||
{
|
||||
"from": "quoted",
|
||||
"label": "Lost",
|
||||
"to": "lost"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"open": [
|
||||
"surveyed",
|
||||
"lost"
|
||||
],
|
||||
"quoted": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"surveyed": [
|
||||
"quoted",
|
||||
"lost"
|
||||
]
|
||||
}
|
||||
},
|
||||
"site_issues": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "safety_officer",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Look into it",
|
||||
"to": "in_hand"
|
||||
},
|
||||
{
|
||||
"from": "in_hand",
|
||||
"label": "Mark fixed",
|
||||
"to": "closed"
|
||||
}
|
||||
],
|
||||
"page": "/safety"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"in_hand": [
|
||||
"closed"
|
||||
],
|
||||
"open": [
|
||||
"in_hand"
|
||||
]
|
||||
}
|
||||
},
|
||||
"subcontractors": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Ask for missing papers",
|
||||
"to": "awaiting_papers"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Approve",
|
||||
"to": "approved"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
},
|
||||
{
|
||||
"from": "awaiting_papers",
|
||||
"label": "Approve",
|
||||
"to": "approved"
|
||||
},
|
||||
{
|
||||
"from": "awaiting_papers",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"awaiting_papers": [
|
||||
"approved",
|
||||
"declined"
|
||||
],
|
||||
"open": [
|
||||
"awaiting_papers",
|
||||
"approved",
|
||||
"declined"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"needs": [
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "survey-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Get someone to look at a building",
|
||||
"expect": [
|
||||
"Get someone to look at a building"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Address of the building",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What's wrong",
|
||||
"name": "problem",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look. A project manager reads it and calls you within two working days to agree a time to come.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price. A project manager reads it and replies within two working days.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them. A project manager checks your papers and answers within a week.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring. A project manager reads every one and answers within a week.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials. The safety officer sees it at once.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "someone from Nordvik Bygg to come and look at the building and tell them what a fix would cost",
|
||||
"who": "a housing board member or private owner with a problem in a building"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "build-price-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Get a price for a build",
|
||||
"expect": [
|
||||
"Get a price for a build"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Address of the site",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What you want built",
|
||||
"name": "project",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
},
|
||||
{
|
||||
"label": "When you'd like to start",
|
||||
"name": "timeframe",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"As soon as possible",
|
||||
"Within a year",
|
||||
"Just exploring"
|
||||
],
|
||||
"type": "select"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look. A project manager reads it and calls you within two working days to agree a time to come.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price. A project manager reads it and replies within two working days.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them. A project manager checks your papers and answers within a week.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring. A project manager reads every one and answers within a week.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials. The safety officer sees it at once.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "drawings, a permit application and a price for the work",
|
||||
"who": "an owner who already knows what they want built"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"approved",
|
||||
"declined"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "subcontractor-application",
|
||||
"lands_in": "subcontractors",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Join our subcontractor list",
|
||||
"expect": [
|
||||
"Join our subcontractor list"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Company name",
|
||||
"name": "company_name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "contact_email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Trade",
|
||||
"name": "trade",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Electrical",
|
||||
"Plumbing",
|
||||
"Scaffolding"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Company registration number",
|
||||
"name": "registration_number",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Insurance policy details",
|
||||
"name": "insurance",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Trade approval reference",
|
||||
"name": "trade_approval",
|
||||
"optional": true,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look. A project manager reads it and calls you within two working days to agree a time to come.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price. A project manager reads it and replies within two working days.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them. A project manager checks your papers and answers within a week.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring. A project manager reads every one and answers within a week.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials. The safety officer sees it at once.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"approved"
|
||||
],
|
||||
"wants": "to get on Nordvik Bygg's list of subcontractors they call for work",
|
||||
"who": "a trade firm doing electrical, plumbing or scaffolding work"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"hired",
|
||||
"declined"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "job-application",
|
||||
"lands_in": "applicants",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Ask about working with us",
|
||||
"expect": [
|
||||
"Ask about working with us"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "What you do",
|
||||
"name": "role",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Carpenter",
|
||||
"Apprentice carpenter",
|
||||
"Other"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Anything else we should know",
|
||||
"name": "message",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look. A project manager reads it and calls you within two working days to agree a time to come.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price. A project manager reads it and replies within two working days.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them. A project manager checks your papers and answers within a week.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring. A project manager reads every one and answers within a week.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials. The safety officer sees it at once.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"hired"
|
||||
],
|
||||
"wants": "to find out if Nordvik Bygg is hiring and put themselves forward",
|
||||
"who": "a carpenter or apprentice looking for work"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"closed"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "safety_officer",
|
||||
"id": "report-site-issue",
|
||||
"lands_in": "site_issues",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Report something from site",
|
||||
"expect": [
|
||||
"Report something from site"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "What kind of issue",
|
||||
"name": "issue_type",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Hazard",
|
||||
"Near miss",
|
||||
"Wrong materials delivered"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Where on site",
|
||||
"name": "location",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What happened",
|
||||
"name": "details",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look. A project manager reads it and calls you within two working days to agree a time to come.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price. A project manager reads it and replies within two working days.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them. A project manager checks your papers and answers within a week.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring. A project manager reads every one and answers within a week.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials. The safety officer sees it at once.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"closed"
|
||||
],
|
||||
"wants": "to flag a hazard, a near miss or wrong materials fast, from their phone",
|
||||
"who": "a crew member on site, ours or a subcontractor's"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": "project_managers",
|
||||
"handled_by": "project_managers",
|
||||
"id": "log-phone-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Log this enquiry",
|
||||
"expect": [
|
||||
"Log this enquiry"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Their name",
|
||||
"name": "caller_name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Phone or email",
|
||||
"name": "contact",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Address of the building",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What they told you",
|
||||
"name": "problem",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
},
|
||||
{
|
||||
"label": "How soon",
|
||||
"name": "urgency",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"This week",
|
||||
"This month",
|
||||
"No rush"
|
||||
],
|
||||
"type": "select"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "",
|
||||
"name": "Log this enquiry"
|
||||
}
|
||||
],
|
||||
"page": "/desk/phone-enquiry",
|
||||
"question": "What did they tell you?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "to get the enquiry into the system before it gets lost",
|
||||
"who": "a project manager who just took a call, email or text about a building"
|
||||
}
|
||||
],
|
||||
"personas": [
|
||||
{
|
||||
"id": "housing-board-cracks",
|
||||
"need": "survey-enquiry",
|
||||
"text": "There are cracks running up the outside wall of our building and none of us know if it's serious. We just want someone qualified to come look at it and tell us what we're dealing with."
|
||||
},
|
||||
{
|
||||
"id": "homeowner-leaking-roof",
|
||||
"need": "survey-enquiry",
|
||||
"text": "Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse."
|
||||
},
|
||||
{
|
||||
"id": "homeowner-extension",
|
||||
"need": "build-price-enquiry",
|
||||
"text": "We want to add a room above the garage. We know roughly what we want, we just need someone to draw it up, sort the paperwork with the municipality, and tell us what it will cost."
|
||||
},
|
||||
{
|
||||
"id": "owner-basement-conversion",
|
||||
"need": "build-price-enquiry",
|
||||
"text": "I'd like to turn the basement into a flat. Need drawings, the permit sorted, and a proper price before I commit to anything."
|
||||
},
|
||||
{
|
||||
"id": "electrician-more-work",
|
||||
"need": "subcontractor-application",
|
||||
"text": "We're a small electrical firm and we'd like to pick up more building work. We're registered and insured, just need to know who to talk to about getting on your books."
|
||||
},
|
||||
{
|
||||
"id": "scaffolding-firm",
|
||||
"need": "subcontractor-application",
|
||||
"text": "We put up and take down scaffolding for building sites. We'd like to be one of the firms you call when a job needs it."
|
||||
},
|
||||
{
|
||||
"id": "apprentice-asking",
|
||||
"need": "job-application",
|
||||
"text": "I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after. Are you taking anyone on right now?"
|
||||
},
|
||||
{
|
||||
"id": "experienced-carpenter",
|
||||
"need": "job-application",
|
||||
"text": "I've been doing carpentry for eight years, mostly older buildings. Wondered if you had any openings on site."
|
||||
},
|
||||
{
|
||||
"id": "crew-loose-scaffold",
|
||||
"need": "report-site-issue",
|
||||
"text": "Noticed a scaffold board that's not sitting right, feels loose when you step on it. Wanted to flag it straight away before someone gets hurt, but I've got gloves on and no time for a long form."
|
||||
},
|
||||
{
|
||||
"id": "subcontractor-wrong-delivery",
|
||||
"need": "report-site-issue",
|
||||
"text": "The delivery this morning was the wrong type of insulation, not what was on the drawings. Someone needs to know before it gets used."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"build-price-enquiry": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 25.593406593406595,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 5,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"job-application": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 26.44899072558647,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 4,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"report-site-issue": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 26.557413600891863,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 3,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"subcontractor-application": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 30.64138678223185,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 5,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"survey-enquiry": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 27.867430441898527,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 4,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"build-price-enquiry": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 28.462059620596207,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 5,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"job-application": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 29.146007816862088,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 4,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"report-site-issue": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 29.2562358276644,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 3,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"subcontractor-application": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 32.111111111111114,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 5,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"survey-enquiry": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 30.151032942490225,
|
||||
"options": 5,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 4,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# Simulating the generated contractor site, 2026-09-21
|
||||
|
||||
Ten personas, three runs each, on ergo. Version A is the site as
|
||||
generated (`enquiries: open -> quoted`). Version B adds the stage the
|
||||
owner described and the generator dropped (`open -> surveyed -> quoted`).
|
||||
|
||||
## What held up
|
||||
|
||||
- **The simulation found a defect the verifier could not.** Reading
|
||||
the first run's records next to the intake showed the generated
|
||||
machine had skipped "we go and look at the building". That became
|
||||
the `stages` field in needs.yaml, which the lint now enforces, so
|
||||
the same omission fails deterministically from here on.
|
||||
- **Routing and form-filling are stable.** 0 misroutes and 0 abandoned
|
||||
forms in 60 cases, once choices were matched by heading (the first
|
||||
run's "100% misrouted" was the model answering "Heading: description").
|
||||
- **One recurring question is a real gap.** Handlers asked about
|
||||
arranging a site visit seven times. The enquiry forms collect an
|
||||
email address and nothing about access or when someone can come,
|
||||
for a business whose first step is a visit.
|
||||
|
||||
## What did not
|
||||
|
||||
- **Letting a model decide outcomes is worthless.** In the first
|
||||
design qwen3:8b sent every case to its success state; after one
|
||||
sentence telling it that losing is normal, every enquiry was "lost"
|
||||
in one touch (`first-design-qwen3-8b/`). Routes are now scripted and
|
||||
who wins is left to the live bucket.
|
||||
- **The ask-back rate does not discriminate yet.** With
|
||||
nemotron-3.5-lightning:30b-a3b as handler, nearly every button drew
|
||||
a question (4 of 4), including nonsense (a title deed; an email
|
||||
address the form already requires). A measure stuck at its maximum
|
||||
cannot rank version A against version B: the A -> B rise in
|
||||
ask-backs per case (1.7 -> 2.3) is just B having one more button.
|
||||
|
||||
## What it needs before its numbers mean anything
|
||||
|
||||
A control for the instrument: run the handler on a record that is
|
||||
deliberately complete and on one deliberately stripped. A usable judge
|
||||
asks on the stripped record and stays quiet on the complete one. Until
|
||||
a prompt and model pass that, read the questions, not the rates.
|
||||
|
||||
Speed: nemotron on both sides took about nine minutes per 30 cases;
|
||||
qwen3:8b about two.
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
{"persona":"housing-board-cracks","need":"survey-enquiry","run":0,"target":"won","record":{"address":"1200 Maple Avenue, Unit 4B, Springfield","email":"alex.ramirez@email.com","follow_up_1":{"answered":"This is the first time a quote is being requested.","asked":"Has Nordvik Bygg already provided a formal quote for this specific issue, or is this the first time a quote is being requested?"},"follow_up_2":{"answered":"This is the first time a quote is being requested.","asked":"Has Nordvik Bygg already provided a formal quote for this specific issue, or is this the first time a quote is being requested?"},"name":"Alex Ramirez","problem":"There are cracks running up the outside wall of our building. None of us know if it's serious. We just want someone qualified to come look at it and tell us what we're dealing with."},"states":["open","quoted","won"],"pressed":["open -> Quote sent","quoted -> Won"],"touches":4,"ask_backs":[{"state":"open","button":"Quote sent","question":"Has Nordvik Bygg already provided a formal quote for this specific issue, or is this the first time a quote is being requested?","answerable":false},{"state":"quoted","button":"Won","question":"Has Nordvik Bygg already provided a formal quote for this specific issue, or is this the first time a quote is being requested?","answerable":false}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"housing-board-cracks","need":"survey-enquiry","run":1,"target":"lost","record":{"address":"Our building, but I don't know the exact address","follow_up_1":{"answered":"I don't have it.","asked":"What is the exact address of the building?"},"name":"Anon","problem":"Cracks running up the outside wall. Don't know if serious."},"states":["open","lost"],"pressed":["open -> Not for us"],"touches":2,"ask_backs":[{"state":"open","button":"Not for us","question":"What is the exact address of the building?","answerable":false}],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"housing-board-cracks","need":"survey-enquiry","run":2,"target":"won","record":{"address":"12 Maple Avenue, Apt 3B, Springfield","email":"mia.torres@email.com","follow_up_1":{"answered":"No, I haven't received a quote or price estimate from Nordvik Bygg yet. I'm just hoping someone can come take a look and tell us what's going on first.","asked":"Have you already received a quote or price estimate from Nordvik Bygg for this assessment?"},"follow_up_2":{"answered":"No, we've never had a Nordvik Bygg rep visit. We've been trying to get someone out here to look at the cracks for months.","asked":"Has a Nordvik Bygg representative already visited the site and provided a written assessment and cost estimate?"},"name":"Mia Torres","problem":"There are significant cracks running up the exterior wall of our building. The masonry appears to be deteriorating, and we are unsure if this indicates structural failure or something less serious. We need a qualified professional to assess the cause and provide a report on the severity and necessary repairs."},"states":["open","quoted","won"],"pressed":["open -> Quote sent","quoted -> Won"],"touches":4,"ask_backs":[{"state":"open","button":"Quote sent","question":"Have you already received a quote or price estimate from Nordvik Bygg for this assessment?","answerable":false},{"state":"quoted","button":"Won","question":"Has a Nordvik Bygg representative already visited the site and provided a written assessment and cost estimate?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"homeowner-leaking-roof","need":"survey-enquiry","run":0,"target":"won","record":{"address":"1234 Pine Street, Apartment 5B, Atlanta, GA 30309","email":"spike@southernliving.com","follow_up_1":{"answered":"No, this is the first time anyone has inspected it.","asked":"Has Nordvik Bygg already inspected this property before, or is this the first time?"},"follow_up_2":{"answered":"No, this is the first time anyone has been called out to look at it.","asked":"Can you please confirm if Nordvik Bygg has already inspected this property before, or is this the first time?"},"name":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse.","problem":"Water is leaking through the ceiling every time it rains. I'm not sure if it's the roof or something else. Need someone to inspect it before the damage gets worse."},"states":["open","quoted","won"],"pressed":["open -> Quote sent","quoted -> Won"],"touches":4,"ask_backs":[{"state":"open","button":"Quote sent","question":"Has Nordvik Bygg already inspected this property before, or is this the first time?","answerable":false},{"state":"quoted","button":"Won","question":"Can you please confirm if Nordvik Bygg has already inspected this property before, or is this the first time?","answerable":false}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"homeowner-leaking-roof","need":"survey-enquiry","run":1,"target":"lost","record":{"address":"Unknown address","email":"unknown@domain.com","follow_up_1":{"answered":"I don't have that info.","asked":"What is the address of the building?"},"name":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse.","problem":"Water leaking through ceiling during rain. Need inspection to determine if roof or other issue."},"states":["open","lost"],"pressed":["open -> Not for us"],"touches":2,"ask_backs":[{"state":"open","button":"Not for us","question":"What is the address of the building?","answerable":false}],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"homeowner-leaking-roof","need":"survey-enquiry","run":2,"target":"won","record":{"address":"37 Orchard Lane, Apartment 4B, Southhill","email":"not_sharing@protonmail.com","follow_up_1":{"answered":"The building is occupied. I live here, so there's always someone around when the rain starts.","asked":"Is the building currently occupied or vacant?"},"follow_up_2":{"answered":"I don't know. I'm not there all the time, and the landlord never told me. I just know the water comes down whenever it rains, and I'm tired of buckets.","asked":"Is the building currently occupied or vacant?"},"name":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse.","problem":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse."},"states":["open","quoted","won"],"pressed":["open -> Quote sent","quoted -> Won"],"touches":4,"ask_backs":[{"state":"open","button":"Quote sent","question":"Is the building currently occupied or vacant?","answerable":true},{"state":"quoted","button":"Won","question":"Is the building currently occupied or vacant?","answerable":false}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"homeowner-extension","need":"build-price-enquiry","run":0,"target":"won","record":{"address":"42 Maple Street, Unit 3B, Portland, OR 97201","email":"sarah.chen@email.com","follow_up_1":{"answered":"I don't know if a site visit has been performed, but it's a necessary step to verify existing conditions and structural feasibility before drawing up plans.","asked":"Has a site visit been performed to verify the existing conditions and structural feasibility of the proposed addition?"},"follow_up_2":{"answered":"We require a site visit to verify existing conditions and structural feasibility before any design or cost estimation can proceed.","asked":"Has a site visit been performed to verify the existing conditions and structural feasibility of the proposed addition?"},"name":"Sarah Chen","project":"Addition of a 24' x 16' room above the existing garage. Two-story design with dormer windows. Open floor plan living area with master suite. Budget range: $250,000 - $350,000. Current garage to be converted to workshop/storage.","timeframe":"Within a year"},"states":["open","quoted","won"],"pressed":["open -> Quote sent","quoted -> Won"],"touches":4,"ask_backs":[{"state":"open","button":"Quote sent","question":"Has a site visit been performed to verify the existing conditions and structural feasibility of the proposed addition?","answerable":false},{"state":"quoted","button":"Won","question":"Has a site visit been performed to verify the existing conditions and structural feasibility of the proposed addition?","answerable":false}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"homeowner-extension","need":"build-price-enquiry","run":1,"target":"lost","record":{"address":"123 Maple St, Anytown","email":"quickquote@example.com","follow_up_1":{"answered":"Yes, we still want to do it.","asked":"Is this project still a possibility, or have you already decided not to proceed?"},"name":"Quick Quote Bot","project":"Room addition above garage","timeframe":"Just exploring"},"states":["open","lost"],"pressed":["open -> Not for us"],"touches":2,"ask_backs":[{"state":"open","button":"Not for us","question":"Is this project still a possibility, or have you already decided not to proceed?","answerable":true}],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"homeowner-extension","need":"build-price-enquiry","run":2,"target":"won","record":{"address":"123 Maple Street, Anytown, State, 12345","email":"jane.smith@email.com","follow_up_1":{"answered":"No, I'm a new client inquiry and haven't received any quote from you yet.","asked":"Can you confirm that the quote has been prepared and sent to Jane Smith?"},"follow_up_2":{"answered":"I don't know. I haven't prepared or sent a quote to Jane Smith, and I have no idea who she is.","asked":"Can you confirm that the quote has been prepared and sent to Jane Smith?"},"name":"Jane Smith","project":"Addition of a 20'x24' room above existing single-car garage. Client has conceptual sketches but requires full architectural drawings, municipal permit set, and cost estimation for structural and MEP integration.","timeframe":"Within a year"},"states":["open","quoted","won"],"pressed":["open -> Quote sent","quoted -> Won"],"touches":4,"ask_backs":[{"state":"open","button":"Quote sent","question":"Can you confirm that the quote has been prepared and sent to Jane Smith?","answerable":false},{"state":"quoted","button":"Won","question":"Can you confirm that the quote has been prepared and sent to Jane Smith?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"owner-basement-conversion","need":"build-price-enquiry","run":0,"target":"won","record":{"address":"123 Maple Street, Apt 4B, Cityville, CA 90210","email":"info@basementflat.arch","follow_up_1":{"answered":"No, I haven't visited the site yet. I'll need to see the space in person before I can give you accurate drawings, permits, or pricing.","asked":"Has a site visit been conducted to verify the current condition of the basement and confirm the proposed layout is feasible?"},"follow_up_2":{"answered":"No site visit has been conducted yet.","asked":"Can you please confirm that a site visit has been conducted to verify the current condition of the basement?"},"name":"I. Architect","project":"Conversion of basement into a residential flat with separate entrance, kitchenette, bathroom, and bedroom. Requires architectural drawings, planning permit application, and detailed cost estimate for client approval prior to commencement.","timeframe":"Within a year"},"states":["open","quoted","won"],"pressed":["open -> Quote sent","quoted -> Won"],"touches":4,"ask_backs":[{"state":"open","button":"Quote sent","question":"Has a site visit been conducted to verify the current condition of the basement and confirm the proposed layout is feasible?","answerable":false},{"state":"quoted","button":"Won","question":"Can you please confirm that a site visit has been conducted to verify the current condition of the basement?","answerable":false}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"owner-basement-conversion","need":"build-price-enquiry","run":1,"target":"lost","record":{"address":"123 Basement Lane","email":"me@basement.com","follow_up_1":{"answered":"Still exploring. Let's get the ball rolling.","asked":"Has your project moved forward, or would you still like to explore options?"},"name":"Me","project":"Convert basement into a flat","timeframe":"Just exploring"},"states":["open","lost"],"pressed":["open -> Not for us"],"touches":2,"ask_backs":[{"state":"open","button":"Not for us","question":"Has your project moved forward, or would you still like to explore options?","answerable":true}],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"owner-basement-conversion","need":"build-price-enquiry","run":2,"target":"won","record":{"address":"42 Maple Crescent, Basingstoke, RG24 9JX","email":"sarah.jenkins@email.com","follow_up_1":{"answered":"No, I haven't had a site visit yet. I'm waiting to get the project started properly.","asked":"Has a site visit been conducted to verify the existing conditions of the basement and the feasibility of the conversion?"},"follow_up_2":{"answered":"No, I haven't had a site visit yet. The plans I'm working from are based on the original building drawings and a quick look around, but I need someone to actually measure the space, check the ceiling height, and look at the services before I can give you proper drawings or a fixed price.","asked":"Has a site visit been conducted to verify the existing conditions of the basement and the feasibility of the conversion?"},"name":"Sarah Jenkins","project":"Convert existing basement into a one-bedroom flat with kitchenette, bathroom, and living area. Requires full architectural drawings, building regulation approval, and planning permission. Need detailed cost breakdown for structural work, MEP services, and finishes.","timeframe":"Within a year"},"states":["open","quoted","won"],"pressed":["open -> Quote sent","quoted -> Won"],"touches":4,"ask_backs":[{"state":"open","button":"Quote sent","question":"Has a site visit been conducted to verify the existing conditions of the basement and the feasibility of the conversion?","answerable":false},{"state":"quoted","button":"Won","question":"Has a site visit been conducted to verify the existing conditions of the basement and the feasibility of the conversion?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"electrician-more-work","need":"subcontractor-application","run":0,"target":"approved","record":{"company_name":"We're a small electrical firm","contact_email":"contact@weareaelectricalfirm.com","follow_up_1":{"answered":"We don't have a company registration number.","asked":"What is your company registration number?"},"insurance":"We have current public liability cover","registration_number":"We are registered but number not to hand right now","trade":"Electrical","trade_approval":""},"states":["open","approved"],"pressed":["open -> Approve"],"touches":2,"ask_backs":[{"state":"open","button":"Approve","question":"What is your company registration number?","answerable":false}],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"electrician-more-work","need":"subcontractor-application","run":1,"target":"declined","record":{"company_name":"We're a small electrical firm and we'd like to pick up more building work. We're registered and insured, just need to know who to talk to about getting on your books.","contact_email":"email@example.com","follow_up_1":{"answered":"I don't know what you're talking about.","asked":"What is your company registration number and insurance provider details?"},"insurance":"Registered and insured, just need to know who to talk to about getting on your books.","registration_number":"Registered and insured, just need to know who to talk to about getting on your books.","trade":"Electrical","trade_approval":""},"states":["open","declined"],"pressed":["open -> Decline"],"touches":2,"ask_backs":[{"state":"open","button":"Decline","question":"What is your company registration number and insurance provider details?","answerable":false}],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"electrician-more-work","need":"subcontractor-application","run":2,"target":"approved","record":{"company_name":"C&W Electrical Services Ltd","contact_email":"info@cwelectricalservices.co.uk","follow_up_1":{"answered":"Yes, we have submitted all required insurance certificates and signed the standard subcontractor agreement. We're ready to go.","asked":"Has the company submitted the required insurance certificates and signed the standard subcontractor agreement?"},"insurance":"Public liability insurance held with Hiscox policy number HL-987654, cover limit £2,000,000. Electrical indemnity insurance with Allianz policy number AL-345321, cover limit £1,000,000.","registration_number":"OC345678","trade":"Electrical","trade_approval":"NICEIC approved contractor since 2015"},"states":["open","approved"],"pressed":["open -> Approve"],"touches":2,"ask_backs":[{"state":"open","button":"Approve","question":"Has the company submitted the required insurance certificates and signed the standard subcontractor agreement?","answerable":true}],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"scaffolding-firm","need":"subcontractor-application","run":0,"target":"approved","record":{"company_name":"QuickSet Scaffolding Ltd","contact_email":"admin@quickset-scaffold.co.uk","follow_up_1":{"answered":"We are a scaffolding company, not a construction site with assigned operatives. We hire qualified scaffolders as needed, but we do not have CISRS cards for our own staff.","asked":"Do you have a valid and current CISRS card for the operatives assigned to Nordvik Bygg projects?"},"insurance":"Public Liability £5M / Employers Liability £10M","registration_number":"12345678","trade":"Scaffolding","trade_approval":"CISRS Registered - Ref: CIS/2024/001"},"states":["open","approved"],"pressed":["open -> Approve"],"touches":2,"ask_backs":[{"state":"open","button":"Approve","question":"Do you have a valid and current CISRS card for the operatives assigned to Nordvik Bygg projects?","answerable":false}],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"scaffolding-firm","need":"subcontractor-application","run":1,"target":"declined","record":{"company_name":"We put up and take down scaffolding for building sites.","contact_email":"contact@scaffoldingco.uk","follow_up_1":{"answered":"I don't have the registration number.","asked":"What is the company's registration number?"},"insurance":"We have public liability cover, policy number available on request.","registration_number":"Would prefer not to share this publicly.","trade":"Scaffolding"},"states":["open","declined"],"pressed":["open -> Decline"],"touches":2,"ask_backs":[{"state":"open","button":"Decline","question":"What is the company's registration number?","answerable":false}],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"scaffolding-firm","need":"subcontractor-application","run":2,"target":"approved","record":{"company_name":"Rapid Response Scaffolding Ltd","contact_email":"admin@rapidresponse-scaffold.co.uk","follow_up_1":{"answered":"No, I'm just a person writing a message on your behalf. You'll need to check with the actual scaffolding company about their certifications.","asked":"Do you have a valid and current scaffolding-specific certification (e.g., PASMA, CISRS) or relevant trade accreditation for the work you perform?"},"insurance":"Public Liability £5M; Employers Liability £10M; Certificate current to 31/12/2025","registration_number":"OC327489","trade":"Scaffolding","trade_approval":"N/A"},"states":["open","approved"],"pressed":["open -> Approve"],"touches":2,"ask_backs":[{"state":"open","button":"Approve","question":"Do you have a valid and current scaffolding-specific certification (e.g., PASMA, CISRS) or relevant trade accreditation for the work you perform?","answerable":true}],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"apprentice-asking","need":"job-application","run":0,"target":"hired","record":{"follow_up_1":{"answered":"206-555-0199","asked":"What is your phone number?"},"follow_up_2":{"answered":"I'm applying for an apprentice position.","asked":"Which specific carpentry role are you applying for (e.g., apprentice, journeyman, project lead)?"},"message":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after the apprenticeship. Are you taking anyone on right now?","name":"Jordan","role":"Apprentice carpenter"},"states":["open","interviewing","hired"],"pressed":["open -> Invite to interview","interviewing -> Hire"],"touches":4,"ask_backs":[{"state":"open","button":"Invite to interview","question":"What is your phone number?","answerable":true},{"state":"interviewing","button":"Hire","question":"Which specific carpentry role are you applying for (e.g., apprentice, journeyman, project lead)?","answerable":true}],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"apprentice-asking","need":"job-application","run":1,"target":"declined","record":{"email":"","follow_up_1":{"answered":"I don't know it.","asked":"What is your email address?"},"message":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after.","name":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after.","role":"Apprentice carpenter"},"states":["open","declined"],"pressed":["open -> Decline"],"touches":2,"ask_backs":[{"state":"open","button":"Decline","question":"What is your email address?","answerable":false}],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"apprentice-asking","need":"job-application","run":2,"target":"hired","record":{"follow_up_1":{"answered":"it's me@email.com","asked":"What is your email address?"},"follow_up_2":{"answered":"I'm not taking anyone on right now. I'm finishing up a job and sorting out my own schedule for next season. I don't have the time to train a new apprentice while I'm trying to keep my own crew running. If you're serious, ask me again in a few months when things settle down.","asked":"Do you want to proceed with hiring this applicant?"},"message":"I'm currently in my second year of carpentry apprenticeship and looking for a firm that will take me on permanently after I complete my training. I have hands-on experience with framing, finish work, and tool maintenance, and I'm eager to find a workplace where I can grow long-term.","name":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after.","role":"Apprentice carpenter"},"states":["open","interviewing","hired"],"pressed":["open -> Invite to interview","interviewing -> Hire"],"touches":4,"ask_backs":[{"state":"open","button":"Invite to interview","question":"What is your email address?","answerable":true},{"state":"interviewing","button":"Hire","question":"Do you want to proceed with hiring this applicant?","answerable":false}],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"experienced-carpenter","need":"job-application","run":0,"target":"hired","record":{"email":"alex.miller@example.com","follow_up_1":{"answered":"925-555-0198","asked":"What is your phone number?"},"follow_up_2":{"answered":"I'm available on the 15th, but I need to know the start time. I have a morning job that day, so I can only make it in after 10 AM.","asked":"Can you come in for an interview on [Date]?"},"message":"Eight years experience specializing in older buildings. I have hand tools for precise joinery and familiarity with period materials. Available for site work.","name":"Alex Miller","role":"Carpenter"},"states":["open","interviewing","hired"],"pressed":["open -> Invite to interview","interviewing -> Hire"],"touches":4,"ask_backs":[{"state":"open","button":"Invite to interview","question":"What is your phone number?","answerable":true},{"state":"interviewing","button":"Hire","question":"Can you come in for an interview on [Date]?","answerable":true}],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"experienced-carpenter","need":"job-application","run":1,"target":"declined","record":{"email":"eli.carpenter8@protonmail.com","message":"Eight years in older buildings. Prefer hand tools, lime mortar, and keeping things standing.","name":"Eli","role":"Carpenter"},"states":["open","declined"],"pressed":["open -> Decline"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"experienced-carpenter","need":"job-application","run":2,"target":"hired","record":{"email":"james.miller@example.com","follow_up_1":{"answered":"I'm a carpenter, not a citizen. I just have a passport.","asked":"Do you have the legal right to work in the country where Nordvik Bygg operates?"},"message":"I'm James, an experienced carpenter with eight years specializing in older buildings. I have a strong background in structural restoration, period joinery, and working with reclaimed materials. I'm looking for a position where I can apply my skills to heritage projects and continue learning from experienced craftsmen.","name":"James Miller","role":"Carpenter"},"states":["open","interviewing","hired"],"pressed":["open -> Invite to interview","interviewing -> Hire"],"touches":3,"ask_backs":[{"state":"interviewing","button":"Hire","question":"Do you have the legal right to work in the country where Nordvik Bygg operates?","answerable":true}],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"crew-loose-scaffold","need":"report-site-issue","run":0,"target":"closed","record":{"details":"Board feels loose under weight; gloves on, no time for detailed investigation","follow_up_1":{"answered":"First name's Mark, I'm a labourer on site. No time for faffing about.","asked":"What is your full name and role (e.g., employee or subcontractor) so I can assign the follow-up correctly?"},"follow_up_2":{"answered":"the crew member who flagged it","asked":"Which person marked this as fixed: the crew member who flagged it, or the subcontractor's worker?"},"issue_type":"Hazard","location":"Scaffold walkway near Zone 3"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"What is your full name and role (e.g., employee or subcontractor) so I can assign the follow-up correctly?","answerable":true},{"state":"in_hand","button":"Mark fixed","question":"Which person marked this as fixed: the crew member who flagged it, or the subcontractor's worker?","answerable":true}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"crew-loose-scaffold","need":"report-site-issue","run":1,"target":"closed","record":{"details":"Board feels loose under weight, gloves on, needs checking","follow_up_1":{"answered":"No, I was stepping on it.","asked":"Has a visual inspection of the scaffold board near main entrance been completed?"},"follow_up_2":{"answered":"No, I just noticed it.","asked":"Has a visual inspection of the scaffold board near main entrance been completed?"},"issue_type":"Hazard","location":"Scaffold board near main entrance"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"Has a visual inspection of the scaffold board near main entrance been completed?","answerable":false},{"state":"in_hand","button":"Mark fixed","question":"Has a visual inspection of the scaffold board near main entrance been completed?","answerable":false}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"crew-loose-scaffold","need":"report-site-issue","run":2,"target":"closed","record":{"details":"Scaffold board feels loose and unstable under foot. Gloves on, time limited. Board not sitting right, risk of slip or fall if stepped on. Flagging immediately to prevent injury.","follow_up_1":{"answered":"Scaffold bay 4, Level 3. The board is over the walkway. It's still in use, no cordon up yet. I just stepped on it and it dipped.","asked":"Can you confirm the exact location of the scaffold board issue? For example, which specific scaffold bay or level, and the current status of the area (e.g., is the scaffold still in use or has it been cordoned off)?"},"follow_up_2":{"answered":"Board is still up, no cordon up yet. I stepped on it to test it, wobbled a bit, then got off. Didn't tie it off or rope it off because I was in a rush and just wanted to warn the boss. Gonna go back with proper gear later to fix it for real.","asked":"Has the scaffold board been secured or removed, and has the area been cordoned off to prevent further use?"},"issue_type":"Hazard","location":"Scaffold area, near main entrance"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"Can you confirm the exact location of the scaffold board issue? For example, which specific scaffold bay or level, and the current status of the area (e.g., is the scaffold still in use or has it been cordoned off)?","answerable":true},{"state":"in_hand","button":"Mark fixed","question":"Has the scaffold board been secured or removed, and has the area been cordoned off to prevent further use?","answerable":true}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"subcontractor-wrong-delivery","need":"report-site-issue","run":0,"target":"closed","record":{"details":"Delivery this morning arrived with standard fiberglass batts instead of the specified mineral wool board. Packaging labels match the delivery note but not the structural drawings. Awaiting confirmation on whether to reject the shipment or hold for exchange.","follow_up_1":{"answered":"Counted 25 rolls of fiberglass batts against the spec for mineral wool. I only noticed because I cross-referenced the truck tag against the manifest before unloading.","asked":"What is the quantity of wrong materials delivered?"},"follow_up_2":{"answered":"Left on the truck. I haven't unloaded it yet, waiting for clarification before proceeding.","asked":"How has the wrong material been handled since delivery? (e.g., moved to quarantine, used in work, left in the storage area)"},"issue_type":"Wrong materials delivered","location":"Storage area, Zone B"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"What is the quantity of wrong materials delivered?","answerable":true},{"state":"in_hand","button":"Mark fixed","question":"How has the wrong material been handled since delivery? (e.g., moved to quarantine, used in work, left in the storage area)","answerable":true}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"subcontractor-wrong-delivery","need":"report-site-issue","run":1,"target":"closed","record":{"details":"Wrong type of insulation delivered this morning. Not what was on the drawings.","follow_up_1":{"answered":"No, the wrong insulation is still on site.","asked":"Has the wrong insulation been removed or replaced with the correct type?"},"issue_type":"Wrong materials delivered","location":"Main entrance staging area"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":3,"ask_backs":[{"state":"in_hand","button":"Mark fixed","question":"Has the wrong insulation been removed or replaced with the correct type?","answerable":false}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"subcontractor-wrong-delivery","need":"report-site-issue","run":2,"target":"closed","record":{"details":"The delivery arrived this morning. I was expecting the blue fiberglass batts shown on the project drawings, but the delivery contained mineral wool boards instead. The packaging was labeled for a different job number. I stopped the crew from offloading it. Someone needs to verify the correct material before it gets installed, as the R-value and fit are different from what's specified. I don't have the delivery ticket number handy, but the driver said it was a substitute from the supplier's stock.","follow_up_1":{"answered":"Yes, I have the delivery ticket number from the manifest on the pallet, but the supplier's contact details are just the generic office number on the invoice, not a specific representative. I can read the ticket number off the label if you need me to verify the substitution details.","asked":"Do you have the delivery ticket number or the supplier's contact details to verify the substitution?"},"follow_up_2":{"answered":"I don't have the delivery ticket or the label in front of me right now, so I can't read the number off the pallet. I need someone to physically check the pallet tag or look up the shipment record in the system to get that number and confirm what was actually delivered versus what was specified on the drawings.","asked":"Can you read the delivery ticket number from the label on the pallet to verify the substitution details?"},"issue_type":"Wrong materials delivered","location":"Warehouse staging area, Bay 4"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"Do you have the delivery ticket number or the supplier's contact details to verify the substitution?","answerable":true},{"state":"in_hand","button":"Mark fixed","question":"Can you read the delivery ticket number from the label on the pallet to verify the substitution details?","answerable":false}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
+706
@@ -0,0 +1,706 @@
|
||||
{
|
||||
"buckets": {
|
||||
"applicants": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Invite to interview",
|
||||
"to": "interviewing"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
},
|
||||
{
|
||||
"from": "interviewing",
|
||||
"label": "Hire",
|
||||
"to": "hired"
|
||||
},
|
||||
{
|
||||
"from": "interviewing",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"interviewing": [
|
||||
"hired",
|
||||
"declined"
|
||||
],
|
||||
"open": [
|
||||
"interviewing",
|
||||
"declined"
|
||||
]
|
||||
}
|
||||
},
|
||||
"enquiries": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Quote sent",
|
||||
"to": "quoted"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Not for us",
|
||||
"to": "lost"
|
||||
},
|
||||
{
|
||||
"from": "quoted",
|
||||
"label": "Won",
|
||||
"to": "won"
|
||||
},
|
||||
{
|
||||
"from": "quoted",
|
||||
"label": "Lost",
|
||||
"to": "lost"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"open": [
|
||||
"quoted",
|
||||
"lost"
|
||||
],
|
||||
"quoted": [
|
||||
"won",
|
||||
"lost"
|
||||
]
|
||||
}
|
||||
},
|
||||
"site_issues": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "safety_officer",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Look into it",
|
||||
"to": "in_hand"
|
||||
},
|
||||
{
|
||||
"from": "in_hand",
|
||||
"label": "Mark fixed",
|
||||
"to": "closed"
|
||||
}
|
||||
],
|
||||
"page": "/safety"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"in_hand": [
|
||||
"closed"
|
||||
],
|
||||
"open": [
|
||||
"in_hand"
|
||||
]
|
||||
}
|
||||
},
|
||||
"subcontractors": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Ask for missing papers",
|
||||
"to": "awaiting_papers"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Approve",
|
||||
"to": "approved"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
},
|
||||
{
|
||||
"from": "awaiting_papers",
|
||||
"label": "Approve",
|
||||
"to": "approved"
|
||||
},
|
||||
{
|
||||
"from": "awaiting_papers",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"awaiting_papers": [
|
||||
"approved",
|
||||
"declined"
|
||||
],
|
||||
"open": [
|
||||
"awaiting_papers",
|
||||
"approved",
|
||||
"declined"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"needs": [
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "survey-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Get someone to look at a building",
|
||||
"expect": [
|
||||
"Get someone to look at a building"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Address of the building",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What's wrong",
|
||||
"name": "problem",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "someone from Nordvik Bygg to come and look at the building and tell them what a fix would cost",
|
||||
"who": "a housing board member or private owner with a problem in a building"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "build-price-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Get a price for a build",
|
||||
"expect": [
|
||||
"Get a price for a build"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Address of the site",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What you want built",
|
||||
"name": "project",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
},
|
||||
{
|
||||
"label": "When you'd like to start",
|
||||
"name": "timeframe",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"As soon as possible",
|
||||
"Within a year",
|
||||
"Just exploring"
|
||||
],
|
||||
"type": "select"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "drawings, a permit application and a price for the work",
|
||||
"who": "an owner who already knows what they want built"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"approved",
|
||||
"declined"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "subcontractor-application",
|
||||
"lands_in": "subcontractors",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Join our subcontractor list",
|
||||
"expect": [
|
||||
"Join our subcontractor list"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Company name",
|
||||
"name": "company_name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "contact_email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Trade",
|
||||
"name": "trade",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Electrical",
|
||||
"Plumbing",
|
||||
"Scaffolding"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Company registration number",
|
||||
"name": "registration_number",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Insurance policy details",
|
||||
"name": "insurance",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Trade approval reference",
|
||||
"name": "trade_approval",
|
||||
"optional": true,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"approved"
|
||||
],
|
||||
"wants": "to get on Nordvik Bygg's list of subcontractors they call for work",
|
||||
"who": "a trade firm doing electrical, plumbing or scaffolding work"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"hired",
|
||||
"declined"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "job-application",
|
||||
"lands_in": "applicants",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Ask about working with us",
|
||||
"expect": [
|
||||
"Ask about working with us"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "What you do",
|
||||
"name": "role",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Carpenter",
|
||||
"Apprentice carpenter",
|
||||
"Other"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Anything else we should know",
|
||||
"name": "message",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"hired"
|
||||
],
|
||||
"wants": "to find out if Nordvik Bygg is hiring and put themselves forward",
|
||||
"who": "a carpenter or apprentice looking for work"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"closed"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "safety_officer",
|
||||
"id": "report-site-issue",
|
||||
"lands_in": "site_issues",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Report something from site",
|
||||
"expect": [
|
||||
"Report something from site"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "What kind of issue",
|
||||
"name": "issue_type",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Hazard",
|
||||
"Near miss",
|
||||
"Wrong materials delivered"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Where on site",
|
||||
"name": "location",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What happened",
|
||||
"name": "details",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"closed"
|
||||
],
|
||||
"wants": "to flag a hazard, a near miss or wrong materials fast, from their phone",
|
||||
"who": "a crew member on site, ours or a subcontractor's"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": "project_managers",
|
||||
"handled_by": "project_managers",
|
||||
"id": "log-phone-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Log this enquiry",
|
||||
"expect": [
|
||||
"Log this enquiry"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Their name",
|
||||
"name": "caller_name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Phone or email",
|
||||
"name": "contact",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Address of the building",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What they told you",
|
||||
"name": "problem",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
},
|
||||
{
|
||||
"label": "How soon",
|
||||
"name": "urgency",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"This week",
|
||||
"This month",
|
||||
"No rush"
|
||||
],
|
||||
"type": "select"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "",
|
||||
"name": "Log this enquiry"
|
||||
}
|
||||
],
|
||||
"page": "/desk/phone-enquiry",
|
||||
"question": "What did they tell you?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "to get the enquiry into the system before it gets lost",
|
||||
"who": "a project manager who just took a call, email or text about a building"
|
||||
}
|
||||
],
|
||||
"personas": [
|
||||
{
|
||||
"id": "housing-board-cracks",
|
||||
"need": "survey-enquiry",
|
||||
"text": "There are cracks running up the outside wall of our building and none of us know if it's serious. We just want someone qualified to come look at it and tell us what we're dealing with."
|
||||
},
|
||||
{
|
||||
"id": "homeowner-leaking-roof",
|
||||
"need": "survey-enquiry",
|
||||
"text": "Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse."
|
||||
},
|
||||
{
|
||||
"id": "homeowner-extension",
|
||||
"need": "build-price-enquiry",
|
||||
"text": "We want to add a room above the garage. We know roughly what we want, we just need someone to draw it up, sort the paperwork with the municipality, and tell us what it will cost."
|
||||
},
|
||||
{
|
||||
"id": "owner-basement-conversion",
|
||||
"need": "build-price-enquiry",
|
||||
"text": "I'd like to turn the basement into a flat. Need drawings, the permit sorted, and a proper price before I commit to anything."
|
||||
},
|
||||
{
|
||||
"id": "electrician-more-work",
|
||||
"need": "subcontractor-application",
|
||||
"text": "We're a small electrical firm and we'd like to pick up more building work. We're registered and insured, just need to know who to talk to about getting on your books."
|
||||
},
|
||||
{
|
||||
"id": "scaffolding-firm",
|
||||
"need": "subcontractor-application",
|
||||
"text": "We put up and take down scaffolding for building sites. We'd like to be one of the firms you call when a job needs it."
|
||||
},
|
||||
{
|
||||
"id": "apprentice-asking",
|
||||
"need": "job-application",
|
||||
"text": "I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after. Are you taking anyone on right now?"
|
||||
},
|
||||
{
|
||||
"id": "experienced-carpenter",
|
||||
"need": "job-application",
|
||||
"text": "I've been doing carpentry for eight years, mostly older buildings. Wondered if you had any openings on site."
|
||||
},
|
||||
{
|
||||
"id": "crew-loose-scaffold",
|
||||
"need": "report-site-issue",
|
||||
"text": "Noticed a scaffold board that's not sitting right, feels loose when you step on it. Wanted to flag it straight away before someone gets hurt, but I've got gloves on and no time for a long form."
|
||||
},
|
||||
{
|
||||
"id": "subcontractor-wrong-delivery",
|
||||
"need": "report-site-issue",
|
||||
"text": "The delivery this morning was the wrong type of insulation, not what was on the drawings. Someone needs to know before it gets used."
|
||||
}
|
||||
]
|
||||
}
|
||||
+409
@@ -0,0 +1,409 @@
|
||||
{
|
||||
"build-price-enquiry": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 20,
|
||||
"ask_backs": 10,
|
||||
"unanswerable": 6,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Quote sent",
|
||||
"question": "Has a site visit been performed to verify the existing conditions and structural feasibility of the proposed addition?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Has a site visit been performed to verify the existing conditions and structural feasibility of the proposed addition?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Not for us",
|
||||
"question": "Is this project still a possibility, or have you already decided not to proceed?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Quote sent",
|
||||
"question": "Can you confirm that the quote has been prepared and sent to Jane Smith?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Can you confirm that the quote has been prepared and sent to Jane Smith?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Quote sent",
|
||||
"question": "Has a site visit been conducted to verify the current condition of the basement and confirm the proposed layout is feasible?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Can you please confirm that a site visit has been conducted to verify the current condition of the basement?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Not for us",
|
||||
"question": "Has your project moved forward, or would you still like to explore options?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Quote sent",
|
||||
"question": "Has a site visit been conducted to verify the existing conditions of the basement and the feasibility of the conversion?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Has a site visit been conducted to verify the existing conditions of the basement and the feasibility of the conversion?",
|
||||
"answerable": true
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"open -> Not for us": [
|
||||
2,
|
||||
2
|
||||
],
|
||||
"open -> Quote sent": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"quoted -> Won": [
|
||||
4,
|
||||
4
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
},
|
||||
"job-application": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 18,
|
||||
"ask_backs": 8,
|
||||
"unanswerable": 2,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Invite to interview",
|
||||
"question": "What is your phone number?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "interviewing",
|
||||
"button": "Hire",
|
||||
"question": "Which specific carpentry role are you applying for (e.g., apprentice, journeyman, project lead)?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Decline",
|
||||
"question": "What is your email address?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Invite to interview",
|
||||
"question": "What is your email address?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "interviewing",
|
||||
"button": "Hire",
|
||||
"question": "Do you want to proceed with hiring this applicant?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Invite to interview",
|
||||
"question": "What is your phone number?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "interviewing",
|
||||
"button": "Hire",
|
||||
"question": "Can you come in for an interview on [Date]?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "interviewing",
|
||||
"button": "Hire",
|
||||
"question": "Do you have the legal right to work in the country where Nordvik Bygg operates?",
|
||||
"answerable": true
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"interviewing -> Hire": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"open -> Decline": [
|
||||
2,
|
||||
1
|
||||
],
|
||||
"open -> Invite to interview": [
|
||||
4,
|
||||
3
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
},
|
||||
"report-site-issue": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 23,
|
||||
"ask_backs": 11,
|
||||
"unanswerable": 4,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "What is your full name and role (e.g., employee or subcontractor) so I can assign the follow-up correctly?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Which person marked this as fixed: the crew member who flagged it, or the subcontractor's worker?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "Has a visual inspection of the scaffold board near main entrance been completed?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Has a visual inspection of the scaffold board near main entrance been completed?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "Can you confirm the exact location of the scaffold board issue? For example, which specific scaffold bay or level, and the current status of the area (e.g., is the scaffold still in use or has it been cordoned off)?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Has the scaffold board been secured or removed, and has the area been cordoned off to prevent further use?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "What is the quantity of wrong materials delivered?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "How has the wrong material been handled since delivery? (e.g., moved to quarantine, used in work, left in the storage area)",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Has the wrong insulation been removed or replaced with the correct type?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "Do you have the delivery ticket number or the supplier's contact details to verify the substitution?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Can you read the delivery ticket number from the label on the pallet to verify the substitution details?",
|
||||
"answerable": false
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"in_hand -> Mark fixed": [
|
||||
6,
|
||||
6
|
||||
],
|
||||
"open -> Look into it": [
|
||||
6,
|
||||
5
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
},
|
||||
"subcontractor-application": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 12,
|
||||
"ask_backs": 6,
|
||||
"unanswerable": 4,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Approve",
|
||||
"question": "What is your company registration number?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Decline",
|
||||
"question": "What is your company registration number and insurance provider details?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Approve",
|
||||
"question": "Has the company submitted the required insurance certificates and signed the standard subcontractor agreement?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Approve",
|
||||
"question": "Do you have a valid and current CISRS card for the operatives assigned to Nordvik Bygg projects?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Decline",
|
||||
"question": "What is the company's registration number?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Approve",
|
||||
"question": "Do you have a valid and current scaffolding-specific certification (e.g., PASMA, CISRS) or relevant trade accreditation for the work you perform?",
|
||||
"answerable": true
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"open -> Approve": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"open -> Decline": [
|
||||
2,
|
||||
2
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
},
|
||||
"survey-enquiry": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 20,
|
||||
"ask_backs": 10,
|
||||
"unanswerable": 8,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Quote sent",
|
||||
"question": "Has Nordvik Bygg already provided a formal quote for this specific issue, or is this the first time a quote is being requested?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Has Nordvik Bygg already provided a formal quote for this specific issue, or is this the first time a quote is being requested?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Not for us",
|
||||
"question": "What is the exact address of the building?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Quote sent",
|
||||
"question": "Have you already received a quote or price estimate from Nordvik Bygg for this assessment?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Has a Nordvik Bygg representative already visited the site and provided a written assessment and cost estimate?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Quote sent",
|
||||
"question": "Has Nordvik Bygg already inspected this property before, or is this the first time?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Can you please confirm if Nordvik Bygg has already inspected this property before, or is this the first time?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Not for us",
|
||||
"question": "What is the address of the building?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Quote sent",
|
||||
"question": "Is the building currently occupied or vacant?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Is the building currently occupied or vacant?",
|
||||
"answerable": false
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"open -> Not for us": [
|
||||
2,
|
||||
2
|
||||
],
|
||||
"open -> Quote sent": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"quoted -> Won": [
|
||||
4,
|
||||
4
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
{"persona":"housing-board-cracks","need":"survey-enquiry","run":0,"target":"won","record":{"address":"1200 Maple Avenue, Unit 4B, Springfield","email":"alex.ramirez@email.com","follow_up_1":{"answered":"We have a master key in the office, but the current caretaker is on leave until Tuesday. I can arrange access then, or you can coordinate with the building manager for an earlier time.","asked":"Do you have access to the building right now, or can you arrange for someone to let me in?"},"follow_up_2":{"answered":"The property manager is available on weekdays between 9am and 4pm. Please coordinate a specific time slot.","asked":"Are you or the building manager available to grant access to the property for a site visit?"},"follow_up_3":{"answered":"I can send a specific time slot for the site visit once you provide your availability. I typically request the building manager's preferred date and time, then confirm with the structural engineer's schedule before finalizing. I can usually accommodate a visit within 3-5 business days, depending on urgency and engineer availability.","asked":"Can you coordinate a specific time for a site visit that works for the building manager or property manager?"},"name":"Alex Ramirez","problem":"There are cracks running up the outside wall of our building. None of us know if it's serious. We just want someone qualified to come look at it and tell us what we're dealing with."},"states":["open","surveyed","quoted","won"],"pressed":["open -> Looked at the building","surveyed -> Quote sent","quoted -> Won"],"touches":6,"ask_backs":[{"state":"open","button":"Looked at the building","question":"Do you have access to the building right now, or can you arrange for someone to let me in?","answerable":true},{"state":"surveyed","button":"Quote sent","question":"Are you or the building manager available to grant access to the property for a site visit?","answerable":true},{"state":"quoted","button":"Won","question":"Can you coordinate a specific time for a site visit that works for the building manager or property manager?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"housing-board-cracks","need":"survey-enquiry","run":1,"target":"lost","record":{"address":"Our building, but I don't know the exact address","follow_up_1":{"answered":"I don't have it.","asked":"What is the exact address of the building?"},"name":"Anon","problem":"Cracks running up the outside wall. Don't know if serious."},"states":["open","lost"],"pressed":["open -> Not for us"],"touches":2,"ask_backs":[{"state":"open","button":"Not for us","question":"What is the exact address of the building?","answerable":false}],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"housing-board-cracks","need":"survey-enquiry","run":2,"target":"won","record":{"address":"12 Maple Avenue, Apt 3B, Springfield","email":"mia.torres@email.com","follow_up_1":{"answered":"We are occupied. It's a mixed-use building with retail on the ground floor and apartments above. Nobody has moved out, and we're all still here hoping this isn't something catastrophic.","asked":"Is the building currently occupied or vacant?"},"follow_up_2":{"answered":"I don't have a calendar or scheduling system. You'll need to check the voicemail or ask the office staff for available slots.","asked":"Can you provide a convenient time for a site visit?"},"follow_up_3":{"answered":"Yes, I have a convenient time tomorrow afternoon after 2 PM. Please send someone qualified to assess the structural integrity of the building.","asked":"Do you have a convenient time for a site visit?"},"name":"Mia Torres","problem":"There are significant cracks running up the exterior wall of our building. The masonry appears to be deteriorating, and we are unsure if this indicates structural failure or something less serious. We need a qualified professional to assess the cause and provide a report on the severity and necessary repairs."},"states":["open","surveyed","quoted","won"],"pressed":["open -> Looked at the building","surveyed -> Quote sent","quoted -> Won"],"touches":6,"ask_backs":[{"state":"open","button":"Looked at the building","question":"Is the building currently occupied or vacant?","answerable":true},{"state":"surveyed","button":"Quote sent","question":"Can you provide a convenient time for a site visit?","answerable":false},{"state":"quoted","button":"Won","question":"Do you have a convenient time for a site visit?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"homeowner-leaking-roof","need":"survey-enquiry","run":0,"target":"won","record":{"address":"1234 Pine Street, Apartment 5B, Atlanta, GA 30309","email":"spike@southernliving.com","follow_up_1":{"answered":"No, I don't have access right now. I work full-time and the building is locked. I can do evenings or weekends if that works.","asked":"Do you have access to the building right now, or would you need to schedule an appointment?"},"follow_up_2":{"answered":"I'm at work during the day, so a morning appointment would be best.","asked":"Could you grant access to the building or schedule an appointment for us to inspect the leak?"},"follow_up_3":{"answered":"Yes, that works. I'll ensure someone is there.","asked":"Can you grant access to the building for an inspection during a morning appointment?"},"name":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse.","problem":"Water is leaking through the ceiling every time it rains. I'm not sure if it's the roof or something else. Need someone to inspect it before the damage gets worse."},"states":["open","surveyed","quoted","won"],"pressed":["open -> Looked at the building","surveyed -> Quote sent","quoted -> Won"],"touches":6,"ask_backs":[{"state":"open","button":"Looked at the building","question":"Do you have access to the building right now, or would you need to schedule an appointment?","answerable":true},{"state":"surveyed","button":"Quote sent","question":"Could you grant access to the building or schedule an appointment for us to inspect the leak?","answerable":true},{"state":"quoted","button":"Won","question":"Can you grant access to the building for an inspection during a morning appointment?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"homeowner-leaking-roof","need":"survey-enquiry","run":1,"target":"lost","record":{"address":"Unknown address","email":"unknown@domain.com","follow_up_1":{"answered":"I don't have that info.","asked":"What is the address of the building?"},"name":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse.","problem":"Water leaking through ceiling during rain. Need inspection to determine if roof or other issue."},"states":["open","lost"],"pressed":["open -> Not for us"],"touches":2,"ask_backs":[{"state":"open","button":"Not for us","question":"What is the address of the building?","answerable":false}],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"homeowner-leaking-roof","need":"survey-enquiry","run":2,"target":"won","record":{"address":"37 Orchard Lane, Apartment 4B, Southhill","email":"not_sharing@protonmail.com","follow_up_1":{"answered":"212 Oakridge Avenue, Apartment 4B","asked":"Could you confirm the exact address of the building, including the street number and apartment/unit number?"},"follow_up_2":{"answered":"I don't have the exact address or unit number written down in front of me, but I know the building is on Maple Avenue and it's the third floor on the left side.","asked":"Can you confirm the exact address of the building, including the street number and apartment/unit number?"},"follow_up_3":{"answered":"123 Maple Avenue, Apt 4B","asked":"Can you provide the exact street number and apartment/unit number for the address?"},"name":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse.","problem":"Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse."},"states":["open","surveyed","quoted","won"],"pressed":["open -> Looked at the building","surveyed -> Quote sent","quoted -> Won"],"touches":6,"ask_backs":[{"state":"open","button":"Looked at the building","question":"Could you confirm the exact address of the building, including the street number and apartment/unit number?","answerable":true},{"state":"surveyed","button":"Quote sent","question":"Can you confirm the exact address of the building, including the street number and apartment/unit number?","answerable":false},{"state":"quoted","button":"Won","question":"Can you provide the exact street number and apartment/unit number for the address?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"homeowner-extension","need":"build-price-enquiry","run":0,"target":"won","record":{"address":"42 Maple Street, Unit 3B, Portland, OR 97201","email":"sarah.chen@email.com","follow_up_1":{"answered":"Go ahead. I'm expecting you.","asked":"Can I have your permission to visit the property at 42 Maple Street, Unit 3B, Portland, OR 97201 to take measurements and assess the existing structure?"},"follow_up_2":{"answered":"Site visit is mandatory. I need to verify ceiling height, roof pitch, and load-bearing walls before drawing anything.","asked":"Is the owner available for a site visit to take measurements and assess the existing structure?"},"follow_up_3":{"answered":"No, they haven't signed the contract or submitted the deposit.","asked":"Has the owner signed the contract and submitted the deposit?"},"name":"Sarah Chen","project":"Addition of a 24' x 16' room above the existing garage. Two-story design with dormer windows. Open floor plan living area with master suite. Budget range: $250,000 - $350,000. Current garage to be converted to workshop/storage.","timeframe":"Within a year"},"states":["open","surveyed","quoted","won"],"pressed":["open -> Looked at the building","surveyed -> Quote sent","quoted -> Won"],"touches":6,"ask_backs":[{"state":"open","button":"Looked at the building","question":"Can I have your permission to visit the property at 42 Maple Street, Unit 3B, Portland, OR 97201 to take measurements and assess the existing structure?","answerable":true},{"state":"surveyed","button":"Quote sent","question":"Is the owner available for a site visit to take measurements and assess the existing structure?","answerable":true},{"state":"quoted","button":"Won","question":"Has the owner signed the contract and submitted the deposit?","answerable":false}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"homeowner-extension","need":"build-price-enquiry","run":1,"target":"lost","record":{"address":"123 Maple St, Anytown","email":"quickquote@example.com","follow_up_1":{"answered":"Yes, we still want to do it.","asked":"Is this project still a possibility, or have you already decided not to proceed?"},"name":"Quick Quote Bot","project":"Room addition above garage","timeframe":"Just exploring"},"states":["open","lost"],"pressed":["open -> Not for us"],"touches":2,"ask_backs":[{"state":"open","button":"Not for us","question":"Is this project still a possibility, or have you already decided not to proceed?","answerable":true}],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"homeowner-extension","need":"build-price-enquiry","run":2,"target":"won","record":{"address":"123 Maple Street, Anytown, State, 12345","email":"jane.smith@email.com","follow_up_1":{"answered":null,"asked":"What is the current condition of the existing garage structure and the site (soil, grade, access) that would need to be surveyed?"},"follow_up_2":{"answered":"I don't have access to your property or the garage. You'll need to hire a surveyor or structural engineer to document the existing conditions, soil, and grade before any drawings can be done.","asked":"Can you provide the current condition of the existing garage structure and the site (soil, grade, access) that would need to be surveyed?"},"follow_up_3":{"answered":"No, we haven't hired a surveyor or structural engineer yet. We were hoping you could handle the design and coordinate those as part of the project, or at least tell us who to call and what order things need to happen in.","asked":"Has the surveyor or structural engineer been hired and completed the documentation of the existing conditions, soil, and grade?"},"name":"Jane Smith","project":"Addition of a 20'x24' room above existing single-car garage. Client has conceptual sketches but requires full architectural drawings, municipal permit set, and cost estimation for structural and MEP integration.","timeframe":"Within a year"},"states":["open","surveyed","quoted","won"],"pressed":["open -> Looked at the building","surveyed -> Quote sent","quoted -> Won"],"touches":6,"ask_backs":[{"state":"open","button":"Looked at the building","question":"What is the current condition of the existing garage structure and the site (soil, grade, access) that would need to be surveyed?","answerable":true},{"state":"surveyed","button":"Quote sent","question":"Can you provide the current condition of the existing garage structure and the site (soil, grade, access) that would need to be surveyed?","answerable":false},{"state":"quoted","button":"Won","question":"Has the surveyor or structural engineer been hired and completed the documentation of the existing conditions, soil, and grade?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"owner-basement-conversion","need":"build-price-enquiry","run":0,"target":"won","record":{"address":"123 Maple Street, Apt 4B, Cityville, CA 90210","email":"info@basementflat.arch","follow_up_1":{"answered":"Currently unoccupied, but the lock needs changing before access can be granted.","asked":"Can we proceed with a site visit, or is the basement currently occupied/locked?"},"follow_up_2":{"answered":"No site visit has been conducted yet.","asked":"Has the site been visited to assess the current condition and verify the lock status?"},"follow_up_3":{"answered":"No, but I have the original blueprints and a full condition report from the previous owner.","asked":"Has a site visit been conducted to verify the lock status and current condition of the basement?"},"name":"I. Architect","project":"Conversion of basement into a residential flat with separate entrance, kitchenette, bathroom, and bedroom. Requires architectural drawings, planning permit application, and detailed cost estimate for client approval prior to commencement.","timeframe":"Within a year"},"states":["open","surveyed","quoted","won"],"pressed":["open -> Looked at the building","surveyed -> Quote sent","quoted -> Won"],"touches":6,"ask_backs":[{"state":"open","button":"Looked at the building","question":"Can we proceed with a site visit, or is the basement currently occupied/locked?","answerable":true},{"state":"surveyed","button":"Quote sent","question":"Has the site been visited to assess the current condition and verify the lock status?","answerable":false},{"state":"quoted","button":"Won","question":"Has a site visit been conducted to verify the lock status and current condition of the basement?","answerable":false}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"owner-basement-conversion","need":"build-price-enquiry","run":1,"target":"lost","record":{"address":"123 Basement Lane","email":"me@basement.com","follow_up_1":{"answered":"Still exploring. Let's get the ball rolling.","asked":"Has your project moved forward, or would you still like to explore options?"},"name":"Me","project":"Convert basement into a flat","timeframe":"Just exploring"},"states":["open","lost"],"pressed":["open -> Not for us"],"touches":2,"ask_backs":[{"state":"open","button":"Not for us","question":"Has your project moved forward, or would you still like to explore options?","answerable":true}],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"owner-basement-conversion","need":"build-price-enquiry","run":2,"target":"won","record":{"address":"42 Maple Crescent, Basingstoke, RG24 9JX","email":"sarah.jenkins@email.com","follow_up_1":{"answered":"No, I don't have the title deed. I'm just looking to turn the basement into a flat, so I haven't sorted out the paperwork yet.","asked":"Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?"},"follow_up_2":{"answered":"No, I do not have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX. I'm currently renting the basement or looking to convert it, but I haven't secured the legal paperwork yet.","asked":"Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?"},"follow_up_3":{"answered":"No, I don't have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX. I'm hoping to get one sorted before I proceed with the basement conversion, but right now I'm just the person wanting to turn it into a flat. I need to sort out the legal paperwork first.","asked":"Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?"},"name":"Sarah Jenkins","project":"Convert existing basement into a one-bedroom flat with kitchenette, bathroom, and living area. Requires full architectural drawings, building regulation approval, and planning permission. Need detailed cost breakdown for structural work, MEP services, and finishes.","timeframe":"Within a year"},"states":["open","surveyed","quoted","won"],"pressed":["open -> Looked at the building","surveyed -> Quote sent","quoted -> Won"],"touches":6,"ask_backs":[{"state":"open","button":"Looked at the building","question":"Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?","answerable":false},{"state":"surveyed","button":"Quote sent","question":"Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?","answerable":true},{"state":"quoted","button":"Won","question":"Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?","answerable":true}],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"electrician-more-work","need":"subcontractor-application","run":0,"target":"approved","record":{"company_name":"We're a small electrical firm","contact_email":"contact@weareaelectricalfirm.com","follow_up_1":{"answered":"We don't have a company registration number.","asked":"What is your company registration number?"},"insurance":"We have current public liability cover","registration_number":"We are registered but number not to hand right now","trade":"Electrical","trade_approval":""},"states":["open","approved"],"pressed":["open -> Approve"],"touches":2,"ask_backs":[{"state":"open","button":"Approve","question":"What is your company registration number?","answerable":false}],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"electrician-more-work","need":"subcontractor-application","run":1,"target":"declined","record":{"company_name":"We're a small electrical firm and we'd like to pick up more building work. We're registered and insured, just need to know who to talk to about getting on your books.","contact_email":"email@example.com","follow_up_1":{"answered":"I don't know what you're talking about.","asked":"What is your company registration number and insurance provider details?"},"insurance":"Registered and insured, just need to know who to talk to about getting on your books.","registration_number":"Registered and insured, just need to know who to talk to about getting on your books.","trade":"Electrical","trade_approval":""},"states":["open","declined"],"pressed":["open -> Decline"],"touches":2,"ask_backs":[{"state":"open","button":"Decline","question":"What is your company registration number and insurance provider details?","answerable":false}],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"electrician-more-work","need":"subcontractor-application","run":2,"target":"approved","record":{"company_name":"C&W Electrical Services Ltd","contact_email":"info@cwelectricalservices.co.uk","follow_up_1":{"answered":"Yes, we have submitted all required insurance certificates and signed the standard subcontractor agreement. We're ready to go.","asked":"Has the company submitted the required insurance certificates and signed the standard subcontractor agreement?"},"insurance":"Public liability insurance held with Hiscox policy number HL-987654, cover limit £2,000,000. Electrical indemnity insurance with Allianz policy number AL-345321, cover limit £1,000,000.","registration_number":"OC345678","trade":"Electrical","trade_approval":"NICEIC approved contractor since 2015"},"states":["open","approved"],"pressed":["open -> Approve"],"touches":2,"ask_backs":[{"state":"open","button":"Approve","question":"Has the company submitted the required insurance certificates and signed the standard subcontractor agreement?","answerable":true}],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"scaffolding-firm","need":"subcontractor-application","run":0,"target":"approved","record":{"company_name":"QuickSet Scaffolding Ltd","contact_email":"admin@quickset-scaffold.co.uk","follow_up_1":{"answered":"We are a scaffolding company, not a construction site with assigned operatives. We hire qualified scaffolders as needed, but we do not have CISRS cards for our own staff.","asked":"Do you have a valid and current CISRS card for the operatives assigned to Nordvik Bygg projects?"},"insurance":"Public Liability £5M / Employers Liability £10M","registration_number":"12345678","trade":"Scaffolding","trade_approval":"CISRS Registered - Ref: CIS/2024/001"},"states":["open","approved"],"pressed":["open -> Approve"],"touches":2,"ask_backs":[{"state":"open","button":"Approve","question":"Do you have a valid and current CISRS card for the operatives assigned to Nordvik Bygg projects?","answerable":false}],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"scaffolding-firm","need":"subcontractor-application","run":1,"target":"declined","record":{"company_name":"We put up and take down scaffolding for building sites.","contact_email":"contact@scaffoldingco.uk","follow_up_1":{"answered":"I don't have the registration number.","asked":"What is the company's registration number?"},"insurance":"We have public liability cover, policy number available on request.","registration_number":"Would prefer not to share this publicly.","trade":"Scaffolding"},"states":["open","declined"],"pressed":["open -> Decline"],"touches":2,"ask_backs":[{"state":"open","button":"Decline","question":"What is the company's registration number?","answerable":false}],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"scaffolding-firm","need":"subcontractor-application","run":2,"target":"approved","record":{"company_name":"Rapid Response Scaffolding Ltd","contact_email":"admin@rapidresponse-scaffold.co.uk","follow_up_1":{"answered":"No, I'm just a person writing a message on your behalf. You'll need to check with the actual scaffolding company about their certifications.","asked":"Do you have a valid and current scaffolding-specific certification (e.g., PASMA, CISRS) or relevant trade accreditation for the work you perform?"},"insurance":"Public Liability £5M; Employers Liability £10M; Certificate current to 31/12/2025","registration_number":"OC327489","trade":"Scaffolding","trade_approval":"N/A"},"states":["open","approved"],"pressed":["open -> Approve"],"touches":2,"ask_backs":[{"state":"open","button":"Approve","question":"Do you have a valid and current scaffolding-specific certification (e.g., PASMA, CISRS) or relevant trade accreditation for the work you perform?","answerable":true}],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"apprentice-asking","need":"job-application","run":0,"target":"hired","record":{"follow_up_1":{"answered":"206-555-0199","asked":"What is your phone number?"},"follow_up_2":{"answered":"I'm applying for an apprentice position.","asked":"Which specific carpentry role are you applying for (e.g., apprentice, journeyman, project lead)?"},"message":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after the apprenticeship. Are you taking anyone on right now?","name":"Jordan","role":"Apprentice carpenter"},"states":["open","interviewing","hired"],"pressed":["open -> Invite to interview","interviewing -> Hire"],"touches":4,"ask_backs":[{"state":"open","button":"Invite to interview","question":"What is your phone number?","answerable":true},{"state":"interviewing","button":"Hire","question":"Which specific carpentry role are you applying for (e.g., apprentice, journeyman, project lead)?","answerable":true}],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"apprentice-asking","need":"job-application","run":1,"target":"declined","record":{"email":"","follow_up_1":{"answered":"I don't know it.","asked":"What is your email address?"},"message":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after.","name":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after.","role":"Apprentice carpenter"},"states":["open","declined"],"pressed":["open -> Decline"],"touches":2,"ask_backs":[{"state":"open","button":"Decline","question":"What is your email address?","answerable":false}],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"apprentice-asking","need":"job-application","run":2,"target":"hired","record":{"follow_up_1":{"answered":"it's me@email.com","asked":"What is your email address?"},"follow_up_2":{"answered":"I'm not taking anyone on right now. I'm finishing up a job and sorting out my own schedule for next season. I don't have the time to train a new apprentice while I'm trying to keep my own crew running. If you're serious, ask me again in a few months when things settle down.","asked":"Do you want to proceed with hiring this applicant?"},"message":"I'm currently in my second year of carpentry apprenticeship and looking for a firm that will take me on permanently after I complete my training. I have hands-on experience with framing, finish work, and tool maintenance, and I'm eager to find a workplace where I can grow long-term.","name":"I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after.","role":"Apprentice carpenter"},"states":["open","interviewing","hired"],"pressed":["open -> Invite to interview","interviewing -> Hire"],"touches":4,"ask_backs":[{"state":"open","button":"Invite to interview","question":"What is your email address?","answerable":true},{"state":"interviewing","button":"Hire","question":"Do you want to proceed with hiring this applicant?","answerable":false}],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"experienced-carpenter","need":"job-application","run":0,"target":"hired","record":{"email":"alex.miller@example.com","follow_up_1":{"answered":"925-555-0198","asked":"What is your phone number?"},"follow_up_2":{"answered":"I'm available on the 15th, but I need to know the start time. I have a morning job that day, so I can only make it in after 10 AM.","asked":"Can you come in for an interview on [Date]?"},"message":"Eight years experience specializing in older buildings. I have hand tools for precise joinery and familiarity with period materials. Available for site work.","name":"Alex Miller","role":"Carpenter"},"states":["open","interviewing","hired"],"pressed":["open -> Invite to interview","interviewing -> Hire"],"touches":4,"ask_backs":[{"state":"open","button":"Invite to interview","question":"What is your phone number?","answerable":true},{"state":"interviewing","button":"Hire","question":"Can you come in for an interview on [Date]?","answerable":true}],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"experienced-carpenter","need":"job-application","run":1,"target":"declined","record":{"email":"eli.carpenter8@protonmail.com","message":"Eight years in older buildings. Prefer hand tools, lime mortar, and keeping things standing.","name":"Eli","role":"Carpenter"},"states":["open","declined"],"pressed":["open -> Decline"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"experienced-carpenter","need":"job-application","run":2,"target":"hired","record":{"email":"james.miller@example.com","follow_up_1":{"answered":"I'm a carpenter, not a citizen. I just have a passport.","asked":"Do you have the legal right to work in the country where Nordvik Bygg operates?"},"message":"I'm James, an experienced carpenter with eight years specializing in older buildings. I have a strong background in structural restoration, period joinery, and working with reclaimed materials. I'm looking for a position where I can apply my skills to heritage projects and continue learning from experienced craftsmen.","name":"James Miller","role":"Carpenter"},"states":["open","interviewing","hired"],"pressed":["open -> Invite to interview","interviewing -> Hire"],"touches":3,"ask_backs":[{"state":"interviewing","button":"Hire","question":"Do you have the legal right to work in the country where Nordvik Bygg operates?","answerable":true}],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"crew-loose-scaffold","need":"report-site-issue","run":0,"target":"closed","record":{"details":"Board feels loose under weight; gloves on, no time for detailed investigation","follow_up_1":{"answered":"First name's Mark, I'm a labourer on site. No time for faffing about.","asked":"What is your full name and role (e.g., employee or subcontractor) so I can assign the follow-up correctly?"},"follow_up_2":{"answered":"the crew member who flagged it","asked":"Which person marked this as fixed: the crew member who flagged it, or the subcontractor's worker?"},"issue_type":"Hazard","location":"Scaffold walkway near Zone 3"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"What is your full name and role (e.g., employee or subcontractor) so I can assign the follow-up correctly?","answerable":true},{"state":"in_hand","button":"Mark fixed","question":"Which person marked this as fixed: the crew member who flagged it, or the subcontractor's worker?","answerable":true}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"crew-loose-scaffold","need":"report-site-issue","run":1,"target":"closed","record":{"details":"Board feels loose under weight, gloves on, needs checking","follow_up_1":{"answered":"No, I was stepping on it.","asked":"Has a visual inspection of the scaffold board near main entrance been completed?"},"follow_up_2":{"answered":"No, I just noticed it.","asked":"Has a visual inspection of the scaffold board near main entrance been completed?"},"issue_type":"Hazard","location":"Scaffold board near main entrance"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"Has a visual inspection of the scaffold board near main entrance been completed?","answerable":false},{"state":"in_hand","button":"Mark fixed","question":"Has a visual inspection of the scaffold board near main entrance been completed?","answerable":false}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"crew-loose-scaffold","need":"report-site-issue","run":2,"target":"closed","record":{"details":"Scaffold board feels loose and unstable under foot. Gloves on, time limited. Board not sitting right, risk of slip or fall if stepped on. Flagging immediately to prevent injury.","follow_up_1":{"answered":"Scaffold bay 4, Level 3. The board is over the walkway. It's still in use, no cordon up yet. I just stepped on it and it dipped.","asked":"Can you confirm the exact location of the scaffold board issue? For example, which specific scaffold bay or level, and the current status of the area (e.g., is the scaffold still in use or has it been cordoned off)?"},"follow_up_2":{"answered":"Board is still up, no cordon up yet. I stepped on it to test it, wobbled a bit, then got off. Didn't tie it off or rope it off because I was in a rush and just wanted to warn the boss. Gonna go back with proper gear later to fix it for real.","asked":"Has the scaffold board been secured or removed, and has the area been cordoned off to prevent further use?"},"issue_type":"Hazard","location":"Scaffold area, near main entrance"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"Can you confirm the exact location of the scaffold board issue? For example, which specific scaffold bay or level, and the current status of the area (e.g., is the scaffold still in use or has it been cordoned off)?","answerable":true},{"state":"in_hand","button":"Mark fixed","question":"Has the scaffold board been secured or removed, and has the area been cordoned off to prevent further use?","answerable":true}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"subcontractor-wrong-delivery","need":"report-site-issue","run":0,"target":"closed","record":{"details":"Delivery this morning arrived with standard fiberglass batts instead of the specified mineral wool board. Packaging labels match the delivery note but not the structural drawings. Awaiting confirmation on whether to reject the shipment or hold for exchange.","follow_up_1":{"answered":"Counted 25 rolls of fiberglass batts against the spec for mineral wool. I only noticed because I cross-referenced the truck tag against the manifest before unloading.","asked":"What is the quantity of wrong materials delivered?"},"follow_up_2":{"answered":"Left on the truck. I haven't unloaded it yet, waiting for clarification before proceeding.","asked":"How has the wrong material been handled since delivery? (e.g., moved to quarantine, used in work, left in the storage area)"},"issue_type":"Wrong materials delivered","location":"Storage area, Zone B"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"What is the quantity of wrong materials delivered?","answerable":true},{"state":"in_hand","button":"Mark fixed","question":"How has the wrong material been handled since delivery? (e.g., moved to quarantine, used in work, left in the storage area)","answerable":true}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"subcontractor-wrong-delivery","need":"report-site-issue","run":1,"target":"closed","record":{"details":"Wrong type of insulation delivered this morning. Not what was on the drawings.","follow_up_1":{"answered":"No, the wrong insulation is still on site.","asked":"Has the wrong insulation been removed or replaced with the correct type?"},"issue_type":"Wrong materials delivered","location":"Main entrance staging area"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":3,"ask_backs":[{"state":"in_hand","button":"Mark fixed","question":"Has the wrong insulation been removed or replaced with the correct type?","answerable":false}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"subcontractor-wrong-delivery","need":"report-site-issue","run":2,"target":"closed","record":{"details":"The delivery arrived this morning. I was expecting the blue fiberglass batts shown on the project drawings, but the delivery contained mineral wool boards instead. The packaging was labeled for a different job number. I stopped the crew from offloading it. Someone needs to verify the correct material before it gets installed, as the R-value and fit are different from what's specified. I don't have the delivery ticket number handy, but the driver said it was a substitute from the supplier's stock.","follow_up_1":{"answered":"Yes, I have the delivery ticket number from the manifest on the pallet, but the supplier's contact details are just the generic office number on the invoice, not a specific representative. I can read the ticket number off the label if you need me to verify the substitution details.","asked":"Do you have the delivery ticket number or the supplier's contact details to verify the substitution?"},"follow_up_2":{"answered":"I don't have the delivery ticket or the label in front of me right now, so I can't read the number off the pallet. I need someone to physically check the pallet tag or look up the shipment record in the system to get that number and confirm what was actually delivered versus what was specified on the drawings.","asked":"Can you read the delivery ticket number from the label on the pallet to verify the substitution details?"},"issue_type":"Wrong materials delivered","location":"Warehouse staging area, Bay 4"},"states":["open","in_hand","closed"],"pressed":["open -> Look into it","in_hand -> Mark fixed"],"touches":4,"ask_backs":[{"state":"open","button":"Look into it","question":"Do you have the delivery ticket number or the supplier's contact details to verify the substitution?","answerable":true},{"state":"in_hand","button":"Mark fixed","question":"Can you read the delivery ticket number from the label on the pallet to verify the substitution details?","answerable":false}],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
+720
@@ -0,0 +1,720 @@
|
||||
{
|
||||
"buckets": {
|
||||
"applicants": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Invite to interview",
|
||||
"to": "interviewing"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
},
|
||||
{
|
||||
"from": "interviewing",
|
||||
"label": "Hire",
|
||||
"to": "hired"
|
||||
},
|
||||
{
|
||||
"from": "interviewing",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"interviewing": [
|
||||
"hired",
|
||||
"declined"
|
||||
],
|
||||
"open": [
|
||||
"interviewing",
|
||||
"declined"
|
||||
]
|
||||
}
|
||||
},
|
||||
"enquiries": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Looked at the building",
|
||||
"to": "surveyed"
|
||||
},
|
||||
{
|
||||
"from": "surveyed",
|
||||
"label": "Quote sent",
|
||||
"to": "quoted"
|
||||
},
|
||||
{
|
||||
"from": "surveyed",
|
||||
"label": "Not worth quoting",
|
||||
"to": "lost"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Not for us",
|
||||
"to": "lost"
|
||||
},
|
||||
{
|
||||
"from": "quoted",
|
||||
"label": "Won",
|
||||
"to": "won"
|
||||
},
|
||||
{
|
||||
"from": "quoted",
|
||||
"label": "Lost",
|
||||
"to": "lost"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"open": [
|
||||
"surveyed",
|
||||
"lost"
|
||||
],
|
||||
"quoted": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"surveyed": [
|
||||
"quoted",
|
||||
"lost"
|
||||
]
|
||||
}
|
||||
},
|
||||
"site_issues": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "safety_officer",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Look into it",
|
||||
"to": "in_hand"
|
||||
},
|
||||
{
|
||||
"from": "in_hand",
|
||||
"label": "Mark fixed",
|
||||
"to": "closed"
|
||||
}
|
||||
],
|
||||
"page": "/safety"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"in_hand": [
|
||||
"closed"
|
||||
],
|
||||
"open": [
|
||||
"in_hand"
|
||||
]
|
||||
}
|
||||
},
|
||||
"subcontractors": {
|
||||
"desks": [
|
||||
{
|
||||
"group": "project_managers",
|
||||
"moves": [
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Ask for missing papers",
|
||||
"to": "awaiting_papers"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Approve",
|
||||
"to": "approved"
|
||||
},
|
||||
{
|
||||
"from": "open",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
},
|
||||
{
|
||||
"from": "awaiting_papers",
|
||||
"label": "Approve",
|
||||
"to": "approved"
|
||||
},
|
||||
{
|
||||
"from": "awaiting_papers",
|
||||
"label": "Decline",
|
||||
"to": "declined"
|
||||
}
|
||||
],
|
||||
"page": "/desk"
|
||||
}
|
||||
],
|
||||
"initial": "open",
|
||||
"self_moves": [],
|
||||
"transitions": {
|
||||
"awaiting_papers": [
|
||||
"approved",
|
||||
"declined"
|
||||
],
|
||||
"open": [
|
||||
"awaiting_papers",
|
||||
"approved",
|
||||
"declined"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"needs": [
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "survey-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Get someone to look at a building",
|
||||
"expect": [
|
||||
"Get someone to look at a building"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Address of the building",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What's wrong",
|
||||
"name": "problem",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "someone from Nordvik Bygg to come and look at the building and tell them what a fix would cost",
|
||||
"who": "a housing board member or private owner with a problem in a building"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "build-price-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Get a price for a build",
|
||||
"expect": [
|
||||
"Get a price for a build"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Address of the site",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What you want built",
|
||||
"name": "project",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
},
|
||||
{
|
||||
"label": "When you'd like to start",
|
||||
"name": "timeframe",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"As soon as possible",
|
||||
"Within a year",
|
||||
"Just exploring"
|
||||
],
|
||||
"type": "select"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "drawings, a permit application and a price for the work",
|
||||
"who": "an owner who already knows what they want built"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"approved",
|
||||
"declined"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "subcontractor-application",
|
||||
"lands_in": "subcontractors",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Join our subcontractor list",
|
||||
"expect": [
|
||||
"Join our subcontractor list"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Company name",
|
||||
"name": "company_name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "contact_email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "Trade",
|
||||
"name": "trade",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Electrical",
|
||||
"Plumbing",
|
||||
"Scaffolding"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Company registration number",
|
||||
"name": "registration_number",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Insurance policy details",
|
||||
"name": "insurance",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Trade approval reference",
|
||||
"name": "trade_approval",
|
||||
"optional": true,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"approved"
|
||||
],
|
||||
"wants": "to get on Nordvik Bygg's list of subcontractors they call for work",
|
||||
"who": "a trade firm doing electrical, plumbing or scaffolding work"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"hired",
|
||||
"declined"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "project_managers",
|
||||
"id": "job-application",
|
||||
"lands_in": "applicants",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Ask about working with us",
|
||||
"expect": [
|
||||
"Ask about working with us"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Your name",
|
||||
"name": "name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Email",
|
||||
"name": "email",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "email"
|
||||
},
|
||||
{
|
||||
"label": "What you do",
|
||||
"name": "role",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Carpenter",
|
||||
"Apprentice carpenter",
|
||||
"Other"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Anything else we should know",
|
||||
"name": "message",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"hired"
|
||||
],
|
||||
"wants": "to find out if Nordvik Bygg is hiring and put themselves forward",
|
||||
"who": "a carpenter or apprentice looking for work"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"closed"
|
||||
],
|
||||
"enters_as": null,
|
||||
"handled_by": "safety_officer",
|
||||
"id": "report-site-issue",
|
||||
"lands_in": "site_issues",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Report something from site",
|
||||
"expect": [
|
||||
"Report something from site"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "What kind of issue",
|
||||
"name": "issue_type",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"Hazard",
|
||||
"Near miss",
|
||||
"Wrong materials delivered"
|
||||
],
|
||||
"type": "select"
|
||||
},
|
||||
{
|
||||
"label": "Where on site",
|
||||
"name": "location",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What happened",
|
||||
"name": "details",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "For housing boards and private owners with a problem in a building who want us to come and take a look.",
|
||||
"name": "Get someone to look at a building"
|
||||
},
|
||||
{
|
||||
"description": "For owners who already know what they want built and need drawings, a permit application and a price.",
|
||||
"name": "Get a price for a build"
|
||||
},
|
||||
{
|
||||
"description": "For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"name": "Join our subcontractor list"
|
||||
},
|
||||
{
|
||||
"description": "For carpenters and apprentices who want to know if we're hiring.",
|
||||
"name": "Ask about working with us"
|
||||
},
|
||||
{
|
||||
"description": "For crew on site, ours or a subcontractor's, who've spotted a hazard, a near miss or the wrong materials.",
|
||||
"name": "Report something from site"
|
||||
}
|
||||
],
|
||||
"page": "/",
|
||||
"question": "What brings you here?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"closed"
|
||||
],
|
||||
"wants": "to flag a hazard, a near miss or wrong materials fast, from their phone",
|
||||
"who": "a crew member on site, ours or a subcontractor's"
|
||||
},
|
||||
{
|
||||
"done_when": [
|
||||
"won",
|
||||
"lost"
|
||||
],
|
||||
"enters_as": "project_managers",
|
||||
"handled_by": "project_managers",
|
||||
"id": "log-phone-enquiry",
|
||||
"lands_in": "enquiries",
|
||||
"steps": [
|
||||
{
|
||||
"alternative": "Log this enquiry",
|
||||
"expect": [
|
||||
"Log this enquiry"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"label": "Their name",
|
||||
"name": "caller_name",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Phone or email",
|
||||
"name": "contact",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "Address of the building",
|
||||
"name": "address",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"label": "What they told you",
|
||||
"name": "problem",
|
||||
"optional": false,
|
||||
"options": [],
|
||||
"type": "textarea"
|
||||
},
|
||||
{
|
||||
"label": "How soon",
|
||||
"name": "urgency",
|
||||
"optional": false,
|
||||
"options": [
|
||||
"This week",
|
||||
"This month",
|
||||
"No rush"
|
||||
],
|
||||
"type": "select"
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"description": "",
|
||||
"name": "Log this enquiry"
|
||||
}
|
||||
],
|
||||
"page": "/desk/phone-enquiry",
|
||||
"question": "What did they tell you?"
|
||||
}
|
||||
],
|
||||
"success": [
|
||||
"won"
|
||||
],
|
||||
"wants": "to get the enquiry into the system before it gets lost",
|
||||
"who": "a project manager who just took a call, email or text about a building"
|
||||
}
|
||||
],
|
||||
"personas": [
|
||||
{
|
||||
"id": "housing-board-cracks",
|
||||
"need": "survey-enquiry",
|
||||
"text": "There are cracks running up the outside wall of our building and none of us know if it's serious. We just want someone qualified to come look at it and tell us what we're dealing with."
|
||||
},
|
||||
{
|
||||
"id": "homeowner-leaking-roof",
|
||||
"need": "survey-enquiry",
|
||||
"text": "Water's coming through the ceiling every time it rains. I don't know if it's the roof or something else, I just want someone to come out and have a look before it gets worse."
|
||||
},
|
||||
{
|
||||
"id": "homeowner-extension",
|
||||
"need": "build-price-enquiry",
|
||||
"text": "We want to add a room above the garage. We know roughly what we want, we just need someone to draw it up, sort the paperwork with the municipality, and tell us what it will cost."
|
||||
},
|
||||
{
|
||||
"id": "owner-basement-conversion",
|
||||
"need": "build-price-enquiry",
|
||||
"text": "I'd like to turn the basement into a flat. Need drawings, the permit sorted, and a proper price before I commit to anything."
|
||||
},
|
||||
{
|
||||
"id": "electrician-more-work",
|
||||
"need": "subcontractor-application",
|
||||
"text": "We're a small electrical firm and we'd like to pick up more building work. We're registered and insured, just need to know who to talk to about getting on your books."
|
||||
},
|
||||
{
|
||||
"id": "scaffolding-firm",
|
||||
"need": "subcontractor-application",
|
||||
"text": "We put up and take down scaffolding for building sites. We'd like to be one of the firms you call when a job needs it."
|
||||
},
|
||||
{
|
||||
"id": "apprentice-asking",
|
||||
"need": "job-application",
|
||||
"text": "I'm in my second year as an apprentice carpenter and looking for a firm that'll keep me on after. Are you taking anyone on right now?"
|
||||
},
|
||||
{
|
||||
"id": "experienced-carpenter",
|
||||
"need": "job-application",
|
||||
"text": "I've been doing carpentry for eight years, mostly older buildings. Wondered if you had any openings on site."
|
||||
},
|
||||
{
|
||||
"id": "crew-loose-scaffold",
|
||||
"need": "report-site-issue",
|
||||
"text": "Noticed a scaffold board that's not sitting right, feels loose when you step on it. Wanted to flag it straight away before someone gets hurt, but I've got gloves on and no time for a long form."
|
||||
},
|
||||
{
|
||||
"id": "subcontractor-wrong-delivery",
|
||||
"need": "report-site-issue",
|
||||
"text": "The delivery this morning was the wrong type of insulation, not what was on the drawings. Someone needs to know before it gets used."
|
||||
}
|
||||
]
|
||||
}
|
||||
+465
@@ -0,0 +1,465 @@
|
||||
{
|
||||
"build-price-enquiry": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 28,
|
||||
"ask_backs": 14,
|
||||
"unanswerable": 5,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Looked at the building",
|
||||
"question": "Can I have your permission to visit the property at 42 Maple Street, Unit 3B, Portland, OR 97201 to take measurements and assess the existing structure?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "surveyed",
|
||||
"button": "Quote sent",
|
||||
"question": "Is the owner available for a site visit to take measurements and assess the existing structure?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Has the owner signed the contract and submitted the deposit?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Not for us",
|
||||
"question": "Is this project still a possibility, or have you already decided not to proceed?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Looked at the building",
|
||||
"question": "What is the current condition of the existing garage structure and the site (soil, grade, access) that would need to be surveyed?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "surveyed",
|
||||
"button": "Quote sent",
|
||||
"question": "Can you provide the current condition of the existing garage structure and the site (soil, grade, access) that would need to be surveyed?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Has the surveyor or structural engineer been hired and completed the documentation of the existing conditions, soil, and grade?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Looked at the building",
|
||||
"question": "Can we proceed with a site visit, or is the basement currently occupied/locked?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "surveyed",
|
||||
"button": "Quote sent",
|
||||
"question": "Has the site been visited to assess the current condition and verify the lock status?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Has a site visit been conducted to verify the lock status and current condition of the basement?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Not for us",
|
||||
"question": "Has your project moved forward, or would you still like to explore options?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Looked at the building",
|
||||
"question": "Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "surveyed",
|
||||
"button": "Quote sent",
|
||||
"question": "Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Do you have a valid title deed or proof of ownership for the property at 42 Maple Crescent, RG24 9JX?",
|
||||
"answerable": true
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"open -> Looked at the building": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"open -> Not for us": [
|
||||
2,
|
||||
2
|
||||
],
|
||||
"quoted -> Won": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"surveyed -> Quote sent": [
|
||||
4,
|
||||
4
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
},
|
||||
"job-application": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 18,
|
||||
"ask_backs": 8,
|
||||
"unanswerable": 2,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Invite to interview",
|
||||
"question": "What is your phone number?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "interviewing",
|
||||
"button": "Hire",
|
||||
"question": "Which specific carpentry role are you applying for (e.g., apprentice, journeyman, project lead)?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Decline",
|
||||
"question": "What is your email address?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Invite to interview",
|
||||
"question": "What is your email address?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "interviewing",
|
||||
"button": "Hire",
|
||||
"question": "Do you want to proceed with hiring this applicant?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Invite to interview",
|
||||
"question": "What is your phone number?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "interviewing",
|
||||
"button": "Hire",
|
||||
"question": "Can you come in for an interview on [Date]?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "interviewing",
|
||||
"button": "Hire",
|
||||
"question": "Do you have the legal right to work in the country where Nordvik Bygg operates?",
|
||||
"answerable": true
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"interviewing -> Hire": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"open -> Decline": [
|
||||
2,
|
||||
1
|
||||
],
|
||||
"open -> Invite to interview": [
|
||||
4,
|
||||
3
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
},
|
||||
"report-site-issue": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 23,
|
||||
"ask_backs": 11,
|
||||
"unanswerable": 4,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "What is your full name and role (e.g., employee or subcontractor) so I can assign the follow-up correctly?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Which person marked this as fixed: the crew member who flagged it, or the subcontractor's worker?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "Has a visual inspection of the scaffold board near main entrance been completed?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Has a visual inspection of the scaffold board near main entrance been completed?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "Can you confirm the exact location of the scaffold board issue? For example, which specific scaffold bay or level, and the current status of the area (e.g., is the scaffold still in use or has it been cordoned off)?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Has the scaffold board been secured or removed, and has the area been cordoned off to prevent further use?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "What is the quantity of wrong materials delivered?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "How has the wrong material been handled since delivery? (e.g., moved to quarantine, used in work, left in the storage area)",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Has the wrong insulation been removed or replaced with the correct type?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Look into it",
|
||||
"question": "Do you have the delivery ticket number or the supplier's contact details to verify the substitution?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "in_hand",
|
||||
"button": "Mark fixed",
|
||||
"question": "Can you read the delivery ticket number from the label on the pallet to verify the substitution details?",
|
||||
"answerable": false
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"in_hand -> Mark fixed": [
|
||||
6,
|
||||
6
|
||||
],
|
||||
"open -> Look into it": [
|
||||
6,
|
||||
5
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
},
|
||||
"subcontractor-application": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 12,
|
||||
"ask_backs": 6,
|
||||
"unanswerable": 4,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Approve",
|
||||
"question": "What is your company registration number?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Decline",
|
||||
"question": "What is your company registration number and insurance provider details?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Approve",
|
||||
"question": "Has the company submitted the required insurance certificates and signed the standard subcontractor agreement?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Approve",
|
||||
"question": "Do you have a valid and current CISRS card for the operatives assigned to Nordvik Bygg projects?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Decline",
|
||||
"question": "What is the company's registration number?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Approve",
|
||||
"question": "Do you have a valid and current scaffolding-specific certification (e.g., PASMA, CISRS) or relevant trade accreditation for the work you perform?",
|
||||
"answerable": true
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"open -> Approve": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"open -> Decline": [
|
||||
2,
|
||||
2
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
},
|
||||
"survey-enquiry": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 28,
|
||||
"ask_backs": 14,
|
||||
"unanswerable": 4,
|
||||
"asked": [
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Looked at the building",
|
||||
"question": "Do you have access to the building right now, or can you arrange for someone to let me in?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "surveyed",
|
||||
"button": "Quote sent",
|
||||
"question": "Are you or the building manager available to grant access to the property for a site visit?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Can you coordinate a specific time for a site visit that works for the building manager or property manager?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Not for us",
|
||||
"question": "What is the exact address of the building?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Looked at the building",
|
||||
"question": "Is the building currently occupied or vacant?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "surveyed",
|
||||
"button": "Quote sent",
|
||||
"question": "Can you provide a convenient time for a site visit?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Do you have a convenient time for a site visit?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Looked at the building",
|
||||
"question": "Do you have access to the building right now, or would you need to schedule an appointment?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "surveyed",
|
||||
"button": "Quote sent",
|
||||
"question": "Could you grant access to the building or schedule an appointment for us to inspect the leak?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Can you grant access to the building for an inspection during a morning appointment?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Not for us",
|
||||
"question": "What is the address of the building?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "open",
|
||||
"button": "Looked at the building",
|
||||
"question": "Could you confirm the exact address of the building, including the street number and apartment/unit number?",
|
||||
"answerable": true
|
||||
},
|
||||
{
|
||||
"state": "surveyed",
|
||||
"button": "Quote sent",
|
||||
"question": "Can you confirm the exact address of the building, including the street number and apartment/unit number?",
|
||||
"answerable": false
|
||||
},
|
||||
{
|
||||
"state": "quoted",
|
||||
"button": "Won",
|
||||
"question": "Can you provide the exact street number and apartment/unit number for the address?",
|
||||
"answerable": true
|
||||
}
|
||||
],
|
||||
"buttons": {
|
||||
"open -> Looked at the building": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"open -> Not for us": [
|
||||
2,
|
||||
2
|
||||
],
|
||||
"quoted -> Won": [
|
||||
4,
|
||||
4
|
||||
],
|
||||
"surveyed -> Quote sent": [
|
||||
4,
|
||||
4
|
||||
]
|
||||
},
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": []
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"build-price-enquiry": {
|
||||
"cases": 10,
|
||||
"finished": 10,
|
||||
"success": 0,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 10,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"lost": 10
|
||||
}
|
||||
},
|
||||
"job-application": {
|
||||
"cases": 10,
|
||||
"finished": 10,
|
||||
"success": 0,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 10,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"declined": 10
|
||||
}
|
||||
},
|
||||
"report-site-issue": {
|
||||
"cases": 10,
|
||||
"finished": 10,
|
||||
"success": 10,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 21,
|
||||
"ask_backs": 1,
|
||||
"asked": [
|
||||
[
|
||||
"in_hand",
|
||||
"Can you confirm if the wrong insulation was delivered to the Main site entrance and if it's still on site?"
|
||||
]
|
||||
],
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"closed": 10
|
||||
}
|
||||
},
|
||||
"subcontractor-application": {
|
||||
"cases": 10,
|
||||
"finished": 10,
|
||||
"success": 5,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 19,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"approved": 5,
|
||||
"declined": 5
|
||||
}
|
||||
},
|
||||
"survey-enquiry": {
|
||||
"cases": 10,
|
||||
"finished": 10,
|
||||
"success": 0,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 10,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"lost": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"build-price-enquiry": {
|
||||
"cases": 6,
|
||||
"finished": 5,
|
||||
"success": 5,
|
||||
"stuck": 0,
|
||||
"misrouted": 1,
|
||||
"abandoned": 0,
|
||||
"touches": 10,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [
|
||||
"owner-basement-conversion: Get a price for a build: For owners who already know what they want built and need drawings, a permit application and a price."
|
||||
],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"won": 5
|
||||
}
|
||||
},
|
||||
"job-application": {
|
||||
"cases": 6,
|
||||
"finished": 0,
|
||||
"success": 0,
|
||||
"stuck": 0,
|
||||
"misrouted": 6,
|
||||
"abandoned": 0,
|
||||
"touches": 0,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [
|
||||
"apprentice-asking: Ask about working with us: For carpenters and apprentices who want to know if we're hiring.",
|
||||
"apprentice-asking: Ask about working with us: For carpenters and apprentices who want to know if we're hiring.",
|
||||
"apprentice-asking: Ask about working with us: For carpenters and apprentices who want to know if we're hiring.",
|
||||
"experienced-carpenter: Ask about working with us: For carpenters and apprentices who want to know if we're hiring.",
|
||||
"experienced-carpenter: Ask about working with us: For carpenters and apprentices who want to know if we're hiring.",
|
||||
"experienced-carpenter: Ask about working with us: For carpenters and apprentices who want to know if we're hiring."
|
||||
],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {}
|
||||
},
|
||||
"report-site-issue": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"success": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 12,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"closed": 6
|
||||
}
|
||||
},
|
||||
"subcontractor-application": {
|
||||
"cases": 6,
|
||||
"finished": 3,
|
||||
"success": 3,
|
||||
"stuck": 0,
|
||||
"misrouted": 3,
|
||||
"abandoned": 0,
|
||||
"touches": 6,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [
|
||||
"scaffolding-firm: Join our subcontractor list: For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"scaffolding-firm: Join our subcontractor list: For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them.",
|
||||
"scaffolding-firm: Join our subcontractor list: For electrical, plumbing and scaffolding firms who want to be one of the firms we call when a job needs them."
|
||||
],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"approved": 3
|
||||
}
|
||||
},
|
||||
"survey-enquiry": {
|
||||
"cases": 6,
|
||||
"finished": 6,
|
||||
"success": 6,
|
||||
"stuck": 0,
|
||||
"misrouted": 0,
|
||||
"abandoned": 0,
|
||||
"touches": 12,
|
||||
"ask_backs": 0,
|
||||
"asked": [],
|
||||
"stuck_at": [],
|
||||
"misroutes": [],
|
||||
"abandon_reasons": [],
|
||||
"ended_in": {
|
||||
"won": 6
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{"id":"housing-board-damp@/","choice":"Get a professional building survey","confidence":0.95}
|
||||
{"id":"buyer-before-purchase@/","choice":"Get a professional building survey","confidence":0.95}
|
||||
{"id":"attic-conversion@/","choice":"Plan your building project with us","confidence":0.95}
|
||||
{"id":"shop-to-flat@/","choice":"Plan your building project with us","confidence":0.95}
|
||||
{"id":"electrician-firm@/","choice":"Become a trusted subcontractor","confidence":0.95}
|
||||
{"id":"scaffolder@/","choice":"Become a trusted subcontractor","confidence":0.95}
|
||||
{"id":"carpenter-jobseeker@/","choice":"Join our carpentry team","confidence":0.95}
|
||||
{"id":"apprentice@/","choice":"Join our carpentry team","confidence":0.95}
|
||||
@@ -0,0 +1,8 @@
|
||||
{"id":"housing-board-damp@/","choice":"Get a professional building survey","confidence":0.95}
|
||||
{"id":"buyer-before-purchase@/","choice":"Get a professional building survey","confidence":0.95}
|
||||
{"id":"attic-conversion@/","choice":"Plan your building project with us","confidence":0.95}
|
||||
{"id":"shop-to-flat@/","choice":"Plan your building project with us","confidence":0.95}
|
||||
{"id":"electrician-firm@/","choice":"Become a trusted subcontractor","confidence":0.95}
|
||||
{"id":"scaffolder@/","choice":"Become a trusted subcontractor","confidence":0.95}
|
||||
{"id":"carpenter-jobseeker@/","choice":"Join our carpentry team","confidence":0.95}
|
||||
{"id":"apprentice@/","choice":"Join our carpentry team","confidence":0.95}
|
||||
@@ -0,0 +1,75 @@
|
||||
aggregates:
|
||||
- bucket: applicants
|
||||
initial: open
|
||||
states:
|
||||
declined:
|
||||
event: declined
|
||||
hired:
|
||||
event: hired
|
||||
interviewing:
|
||||
event: interviewing
|
||||
open:
|
||||
event: received
|
||||
transitions:
|
||||
interviewing:
|
||||
- hired
|
||||
- declined
|
||||
open:
|
||||
- interviewing
|
||||
- declined
|
||||
- bucket: enquiries
|
||||
initial: open
|
||||
states:
|
||||
lost:
|
||||
event: lost
|
||||
open:
|
||||
event: received
|
||||
quoted:
|
||||
event: quoted
|
||||
surveyed:
|
||||
event: surveyed
|
||||
won:
|
||||
event: won
|
||||
transitions:
|
||||
open:
|
||||
- surveyed
|
||||
- lost
|
||||
quoted:
|
||||
- won
|
||||
- lost
|
||||
surveyed:
|
||||
- quoted
|
||||
- lost
|
||||
- bucket: site_issues
|
||||
initial: open
|
||||
states:
|
||||
closed:
|
||||
event: closed
|
||||
in_hand:
|
||||
event: in_hand
|
||||
open:
|
||||
event: received
|
||||
transitions:
|
||||
in_hand:
|
||||
- closed
|
||||
open:
|
||||
- in_hand
|
||||
- bucket: subcontractors
|
||||
initial: open
|
||||
states:
|
||||
approved:
|
||||
event: approved
|
||||
awaiting_papers:
|
||||
event: awaiting_papers
|
||||
declined:
|
||||
event: declined
|
||||
open:
|
||||
event: received
|
||||
transitions:
|
||||
awaiting_papers:
|
||||
- approved
|
||||
- declined
|
||||
open:
|
||||
- awaiting_papers
|
||||
- approved
|
||||
- declined
|
||||
@@ -0,0 +1,149 @@
|
||||
needs:
|
||||
- done_when:
|
||||
- won
|
||||
- lost
|
||||
enters: /
|
||||
handled_by: project_managers
|
||||
id: survey-enquiry
|
||||
lands_in: enquiries
|
||||
max_fields: 4
|
||||
max_steps: 1
|
||||
stages:
|
||||
- open
|
||||
- surveyed
|
||||
- quoted
|
||||
- won
|
||||
- lost
|
||||
success:
|
||||
- won
|
||||
via: Get a professional building survey
|
||||
wants: someone qualified to come and look at it and say what it takes
|
||||
who: a housing board or private owner with a problem in a building
|
||||
- done_when:
|
||||
- won
|
||||
- lost
|
||||
enters: /
|
||||
handled_by: project_managers
|
||||
id: build-enquiry
|
||||
lands_in: enquiries
|
||||
max_fields: 5
|
||||
max_steps: 1
|
||||
stages:
|
||||
- open
|
||||
- surveyed
|
||||
- quoted
|
||||
- won
|
||||
- lost
|
||||
success:
|
||||
- won
|
||||
via: Plan your building project with us
|
||||
wants: drawings, a permit application and a price
|
||||
who: an owner who already knows what they want built or changed
|
||||
- done_when:
|
||||
- won
|
||||
- lost
|
||||
enters: /project_managers/log-phone-enquiry
|
||||
enters_as: project_managers
|
||||
handled_by: project_managers
|
||||
id: log-phone-enquiry
|
||||
lands_in: enquiries
|
||||
max_fields: 4
|
||||
max_steps: 1
|
||||
stages:
|
||||
- open
|
||||
- surveyed
|
||||
- quoted
|
||||
- won
|
||||
- lost
|
||||
success:
|
||||
- won
|
||||
via: Log a phone enquiry
|
||||
wants: the enquiry written down before it gets lost
|
||||
who: a project manager who just took a call or a text about a building
|
||||
- done_when:
|
||||
- approved
|
||||
- declined
|
||||
enters: /
|
||||
handled_by: project_managers
|
||||
id: subcontractor-application
|
||||
lands_in: subcontractors
|
||||
max_fields: 5
|
||||
max_steps: 1
|
||||
stages:
|
||||
- open
|
||||
- awaiting_papers
|
||||
- approved
|
||||
- declined
|
||||
success:
|
||||
- approved
|
||||
via: Become a trusted subcontractor
|
||||
wants: to be approved once, and then be called when a job needs them
|
||||
who: a trade firm doing electrical, plumbing or scaffolding work
|
||||
- done_when:
|
||||
- hired
|
||||
- declined
|
||||
enters: /
|
||||
handled_by: project_managers
|
||||
id: job-application
|
||||
lands_in: applicants
|
||||
max_fields: 3
|
||||
max_steps: 1
|
||||
stages:
|
||||
- open
|
||||
- interviewing
|
||||
- hired
|
||||
- declined
|
||||
success:
|
||||
- hired
|
||||
via: Join our carpentry team
|
||||
wants: to be considered, without writing a letter
|
||||
who: a carpenter, bricklayer or apprentice looking for work
|
||||
- done_when:
|
||||
- closed
|
||||
enters: /crew/report-site-issue
|
||||
enters_as: crew
|
||||
handled_by: safety_officer
|
||||
id: report-site-issue
|
||||
lands_in: site_issues
|
||||
max_fields: 3
|
||||
max_steps: 1
|
||||
stages:
|
||||
- open
|
||||
- in_hand
|
||||
- closed
|
||||
success:
|
||||
- closed
|
||||
via: Report a safety issue on site
|
||||
wants: to report a hazard, a near miss or wrong materials before they forget
|
||||
who: anyone on site, ours or a subcontractor's, on a phone with gloves on
|
||||
personas:
|
||||
- id: housing-board-damp
|
||||
need: survey-enquiry
|
||||
text: I chair the board of a housing cooperative from the seventies. Two ground-floor flats have damp in the walls and we don't know if it's drainage or the facade. We need someone to tell us.
|
||||
- id: buyer-before-purchase
|
||||
need: survey-enquiry
|
||||
text: We are about to buy an old timber house. Before we sign we want a professional to go through it and tell us what is wrong with it.
|
||||
- id: attic-conversion
|
||||
need: build-enquiry
|
||||
text: We want to turn our attic into two bedrooms and a bathroom. We need drawings and someone who handles the application to the municipality.
|
||||
- id: shop-to-flat
|
||||
need: build-enquiry
|
||||
text: I own a former shop on the ground floor and want to make it a flat. I have no idea what is allowed. Can you sort that out and give me a price?
|
||||
- id: electrician-firm
|
||||
need: subcontractor-application
|
||||
text: We are a four-person electrical firm, fully certified. We would like to get on your list so you call us when you need electricians.
|
||||
- id: scaffolder
|
||||
need: subcontractor-application
|
||||
text: I run a scaffolding company. How do I get to do jobs for you?
|
||||
- id: carpenter-jobseeker
|
||||
need: job-application
|
||||
text: I'm a certified carpenter with eight years on rehabilitation jobs. Are you hiring?
|
||||
- id: apprentice
|
||||
need: job-application
|
||||
text: I finish vocational school this spring and need an apprenticeship as a bricklayer.
|
||||
- id: loose-railing
|
||||
need: report-site-issue
|
||||
text: The railing on the third level of the scaffold on the north side is loose. Nobody got hurt but someone will.
|
||||
- id: wrong-membrane
|
||||
need: report-site-issue
|
||||
text: The bathroom membrane delivered today is not the one in the specification. We stopped work on it.
|
||||
@@ -0,0 +1 @@
|
||||
qualifies: crew
|
||||
@@ -0,0 +1,11 @@
|
||||
alternatives:
|
||||
- action: /crew/report-site-issue
|
||||
consequence:
|
||||
- Report issue
|
||||
description: Write down a hazard, near miss or wrong materials from the site.
|
||||
name: Report a site issue
|
||||
description: A desk for the project managers and safety officer. Move cases through stages, approve subs, and log issues.
|
||||
name: What do you need to do today?
|
||||
responsible:
|
||||
contact: ingrid@nordvikbygg.example
|
||||
name: Ingrid Nordvik
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
alternatives:
|
||||
- description: A safety officer will assess the issue and assign it to the right person.
|
||||
name: What happens next
|
||||
- action: /crew
|
||||
consequence:
|
||||
- Back to form
|
||||
description: ''
|
||||
name: Back to form
|
||||
description: Your report has been received. We will review it and get back to you.
|
||||
name: What type of issue did you report?
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
alternatives:
|
||||
- action: /crew/report-site-issue-sent
|
||||
consequence:
|
||||
- Send report
|
||||
description: Use this form to report a safety issue, near miss, or wrong materials while on site.
|
||||
features:
|
||||
- name: Report a site issue
|
||||
requirements:
|
||||
- label: Issue type
|
||||
name: kind
|
||||
options:
|
||||
- Hazard
|
||||
- Near miss
|
||||
- Wrong materials
|
||||
- Other
|
||||
type: select
|
||||
- label: Where on site
|
||||
name: where
|
||||
type: text
|
||||
- label: What happened
|
||||
name: what_happened
|
||||
type: textarea
|
||||
name: Report a safety issue on site
|
||||
record_as: site_issues
|
||||
description: Report hazards, near misses, or wrong materials so they can be fixed.
|
||||
followup: false
|
||||
name: What happened on site?
|
||||
responsible:
|
||||
contact: ingrid@nordvikbygg.example
|
||||
name: Ingrid Nordvik
|
||||
@@ -0,0 +1,123 @@
|
||||
alternatives:
|
||||
- action: /received/survey-enquiry
|
||||
consequence:
|
||||
- Book a survey
|
||||
description: We visit, assess and give you a quote for the repair work.
|
||||
features:
|
||||
- name: Survey enquiry
|
||||
requirements:
|
||||
- label: Your name
|
||||
name: name
|
||||
type: text
|
||||
- label: Phone number
|
||||
name: phone
|
||||
type: tel
|
||||
- label: Building address
|
||||
name: address
|
||||
type: text
|
||||
- label: Describe the problem
|
||||
name: problem
|
||||
type: textarea
|
||||
- label: Site access
|
||||
name: access
|
||||
optional: true
|
||||
type: text
|
||||
name: Get a professional building survey
|
||||
record_as: enquiries
|
||||
- action: /received/build-enquiry
|
||||
consequence:
|
||||
- Start project
|
||||
description: We handle drawings, permits and price for your building plans.
|
||||
features:
|
||||
- name: Building project
|
||||
requirements:
|
||||
- label: Your name
|
||||
name: name
|
||||
type: text
|
||||
- label: Phone number
|
||||
name: phone
|
||||
type: tel
|
||||
- label: Project address
|
||||
name: address
|
||||
type: text
|
||||
- label: Project description
|
||||
name: project
|
||||
type: textarea
|
||||
- label: When do you want it done
|
||||
name: timeframe
|
||||
options:
|
||||
- This year
|
||||
- Next year
|
||||
- No fixed date
|
||||
type: select
|
||||
name: Plan your building project with us
|
||||
record_as: enquiries
|
||||
- action: /received/subcontractor-application
|
||||
consequence:
|
||||
- Apply now
|
||||
description: Register your trade firm so we can call you for jobs.
|
||||
features:
|
||||
- name: Subcontractor sign-up
|
||||
requirements:
|
||||
- label: Company name
|
||||
name: company
|
||||
type: text
|
||||
- label: Org number
|
||||
name: registration_number
|
||||
type: text
|
||||
- label: Your trade
|
||||
name: trade
|
||||
options:
|
||||
- Electrical
|
||||
- Plumbing
|
||||
- Scaffolding
|
||||
- Sheet metal
|
||||
- Other
|
||||
type: select
|
||||
- label: Contact email
|
||||
name: contact_email
|
||||
type: email
|
||||
- label: Insurance confirmed
|
||||
name: insurance_confirmed
|
||||
options:
|
||||
- Yes
|
||||
- Not yet
|
||||
type: select
|
||||
- label: Trade approval
|
||||
name: trade_approval
|
||||
optional: true
|
||||
type: text
|
||||
name: Become a trusted subcontractor
|
||||
record_as: subcontractors
|
||||
- action: /received/job-application
|
||||
consequence:
|
||||
- Apply for work
|
||||
description: Share your trade and skills so we can find you a job.
|
||||
features:
|
||||
- name: Job application
|
||||
requirements:
|
||||
- label: Your name
|
||||
name: name
|
||||
type: text
|
||||
- label: Phone number
|
||||
name: phone
|
||||
type: tel
|
||||
- label: Your trade
|
||||
name: trade
|
||||
options:
|
||||
- Carpenter
|
||||
- Bricklayer
|
||||
- Apprentice
|
||||
- Other
|
||||
type: select
|
||||
- label: Your experience
|
||||
name: experience
|
||||
optional: true
|
||||
type: textarea
|
||||
name: Join our carpentry team
|
||||
record_as: applicants
|
||||
description: 'Pick what you need: a building check, a new project, or joining the team.'
|
||||
name: What brings you to Nordvik Bygg today?
|
||||
responsible:
|
||||
contact: ingrid@nordvikbygg.example
|
||||
name: Ingrid Nordvik
|
||||
+1
@@ -0,0 +1 @@
|
||||
qualifies: project_managers
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
alternatives:
|
||||
- action: /project_managers
|
||||
consequence:
|
||||
- Continue
|
||||
description: A carpenter, bricklayer or apprentice looking for their next job can be added here. The team reviews their skills and experience.
|
||||
features:
|
||||
- description: ''
|
||||
name: ''
|
||||
resource:
|
||||
requires_group: project_managers
|
||||
source:
|
||||
bucket: applicants
|
||||
kind: kv
|
||||
transitions:
|
||||
- from: interviewing
|
||||
label: Hired
|
||||
to: hired
|
||||
- from: interviewing
|
||||
label: Declined
|
||||
to: declined
|
||||
- from: open
|
||||
label: Start interview
|
||||
to: interviewing
|
||||
- from: open
|
||||
label: Declined
|
||||
to: declined
|
||||
name: Job applicants
|
||||
- action: /project_managers
|
||||
consequence:
|
||||
- Continue
|
||||
description: A housing board or private owner with a building problem, or an owner who wants something built or changed. Track the case from first contact to final result.
|
||||
features:
|
||||
- description: ''
|
||||
name: ''
|
||||
resource:
|
||||
requires_group: project_managers
|
||||
source:
|
||||
bucket: enquiries
|
||||
kind: kv
|
||||
transitions:
|
||||
- from: open
|
||||
label: Start survey
|
||||
to: surveyed
|
||||
- from: open
|
||||
label: Mark lost
|
||||
to: lost
|
||||
- from: quoted
|
||||
label: Won
|
||||
to: won
|
||||
- from: quoted
|
||||
label: Mark lost
|
||||
to: lost
|
||||
- from: surveyed
|
||||
label: Make quote
|
||||
to: quoted
|
||||
- from: surveyed
|
||||
label: Mark lost
|
||||
to: lost
|
||||
name: Building enquiries
|
||||
- action: /project_managers
|
||||
consequence:
|
||||
- Continue
|
||||
description: A trade firm doing electrical, plumbing or scaffolding work can be approved once and then called when a job needs them.
|
||||
features:
|
||||
- description: ''
|
||||
name: ''
|
||||
resource:
|
||||
requires_group: project_managers
|
||||
source:
|
||||
bucket: subcontractors
|
||||
kind: kv
|
||||
transitions:
|
||||
- from: awaiting_papers
|
||||
label: Approve
|
||||
to: approved
|
||||
- from: awaiting_papers
|
||||
label: Decline
|
||||
to: declined
|
||||
- from: open
|
||||
label: Await papers
|
||||
to: awaiting_papers
|
||||
- from: open
|
||||
label: Approve
|
||||
to: approved
|
||||
- from: open
|
||||
label: Decline
|
||||
to: declined
|
||||
name: Subcontractors
|
||||
- action: /project_managers/log-phone-enquiry
|
||||
consequence:
|
||||
- Log call
|
||||
description: Write down a phone call or text about a building issue before it gets lost.
|
||||
name: Log phone enquiry
|
||||
description: Use the buckets below to move cases through their stages. Each bucket is a list of jobs waiting for action.
|
||||
name: What needs doing today?
|
||||
responsible:
|
||||
contact: ingrid@nordvikbygg.example
|
||||
name: Ingrid Nordvik
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
alternatives:
|
||||
- description: Ingrid and the team will review the details and get back to you within one business day.
|
||||
name: What happens next
|
||||
- action: /project_managers
|
||||
consequence:
|
||||
- Back to form
|
||||
description: ''
|
||||
name: Back to form
|
||||
description: Your phone call or text has been recorded. It will not be forgotten.
|
||||
name: Did the message go through?
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
alternatives:
|
||||
- action: /project_managers/log-phone-enquiry-sent
|
||||
consequence:
|
||||
- Log phone call
|
||||
description: Write down the enquiry before it gets lost.
|
||||
features:
|
||||
- name: Log phone enquiry
|
||||
requirements:
|
||||
- label: Your name
|
||||
name: caller
|
||||
type: text
|
||||
- label: Phone number
|
||||
name: phone
|
||||
type: tel
|
||||
- label: Address
|
||||
name: address
|
||||
type: text
|
||||
- label: What happened?
|
||||
name: problem
|
||||
type: textarea
|
||||
name: Log a phone enquiry
|
||||
record_as: enquiries
|
||||
description: Quickly record a building enquiry from a phone call or text.
|
||||
followup: false
|
||||
name: What happened on the phone?
|
||||
responsible:
|
||||
contact: ingrid@nordvikbygg.example
|
||||
name: Ingrid Nordvik
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
alternatives:
|
||||
- description: We will contact you within two business days to discuss your project and send a quote.
|
||||
name: 'Next steps: quote and timeline'
|
||||
- action: /
|
||||
consequence:
|
||||
- Back to form
|
||||
description: ''
|
||||
name: Back to form
|
||||
description: Your build enquiry has been received. A project manager will review it.
|
||||
name: What happens next?
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
alternatives:
|
||||
- description: Project managers will review your profile and contact you if they want to interview.
|
||||
name: Next steps
|
||||
- action: /
|
||||
consequence:
|
||||
- Back to form
|
||||
description: ''
|
||||
name: Back to form
|
||||
description: Your job application has been received.
|
||||
name: What are you looking for?
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
alternatives:
|
||||
- description: Once approved, you will be added to our approved subcontractor list and contacted when relevant projects arise.
|
||||
name: Approved and added to list
|
||||
- action: /
|
||||
consequence:
|
||||
- Back to form
|
||||
description: ''
|
||||
name: Back to form
|
||||
description: Subcontractor applications are reviewed by our project managers to verify credentials and suitability before approval.
|
||||
name: What is your trade?
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
alternatives:
|
||||
- description: A project manager will review the details and contact you to schedule a site visit.
|
||||
name: 'Next: Site survey'
|
||||
- action: /
|
||||
consequence:
|
||||
- Back to form
|
||||
description: ''
|
||||
name: Back to form
|
||||
description: You sent a survey enquiry. This page tells you who will handle it and what happens next.
|
||||
name: Who will handle your enquiry?
|
||||
+1
@@ -0,0 +1 @@
|
||||
qualifies: safety_officer
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
alternatives:
|
||||
- action: /safety_officer
|
||||
consequence:
|
||||
- Submit
|
||||
description: Report hazards, near misses, or wrong materials before you forget them.
|
||||
features:
|
||||
- description: ''
|
||||
name: ''
|
||||
resource:
|
||||
requires_group: safety_officer
|
||||
source:
|
||||
bucket: site_issues
|
||||
kind: kv
|
||||
transitions:
|
||||
- from: in_hand
|
||||
label: Mark as closed
|
||||
to: closed
|
||||
- from: open
|
||||
label: Report issue
|
||||
to: in_hand
|
||||
name: Report a site issue
|
||||
description: Log a safety concern or material issue from the site.
|
||||
name: What issue do you need to report?
|
||||
responsible:
|
||||
contact: ingrid@nordvikbygg.example
|
||||
name: Ingrid Nordvik
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"build-enquiry": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 27.477272727272727,
|
||||
"options": 4,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 5,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"job-application": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 23.909090909090907,
|
||||
"options": 4,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 3,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"report-site-issue": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 15.618181818181819,
|
||||
"options": 1,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 3,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 1
|
||||
}
|
||||
},
|
||||
"subcontractor-application": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 29.01581027667984,
|
||||
"options": 4,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 5,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"survey-enquiry": {
|
||||
"control_ok": true,
|
||||
"control_which": 0,
|
||||
"lix": 27.92885375494071,
|
||||
"options": 4,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 4,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 0,
|
||||
"which": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# The same site, re-scored with the per-task answerer
|
||||
|
||||
The site is the one in the directory above, built 2026-09-21 and
|
||||
untouched. Visitor: qwen3:8b on ergo's Ollama, one call per task,
|
||||
options shuffled per task, seeded from the task id. question_lint
|
||||
from portal at d7f60ea.
|
||||
|
||||
| Visitor could read | 2026-09-21, all tasks in one prompt | 2026-09-22, one task per call |
|
||||
|---|---|---|
|
||||
| Headings and descriptions | 8 of 8 | 8 of 8 |
|
||||
| Headings only | 8 of 8 | 7 of 8 |
|
||||
|
||||
The one misroute: the apprentice ("I finish vocational school this
|
||||
spring and need an apprenticeship as a bricklayer") reads the four
|
||||
headings alone and picks "Get a professional building survey" at
|
||||
0.85, over "Join our carpentry team". Read as a bricklayer would, the
|
||||
heading names a trade that is not theirs, and nothing on the page
|
||||
says the team hires bricklayers or apprentices. That is a heading
|
||||
defect the batched answerer did not find, because with all eight
|
||||
personas in one prompt the model had two obvious jobseekers and one
|
||||
obvious jobs heading.
|
||||
|
||||
`rate`, on the same site, with the followup page shown and every
|
||||
question controlled against the gutted twin:
|
||||
|
||||
| need | LIX | which | asked | next | twin says |
|
||||
|---|---|---|---|---|---|
|
||||
| survey-enquiry | 25 | 2/2 | 2/2 | 2/2 | 0/0/0 |
|
||||
| build-enquiry | 26 | 2/2 | 2/2 | 2/2 | 0/0/0 |
|
||||
| subcontractor-application | 35 | 2/2 | 2/2 | 2/2 | 0/0/0 |
|
||||
| job-application | 27 | 1/2 | 2/2 | 2/2 | 0/0/0 |
|
||||
| report-site-issue | 18 | 2/2 | 2/2 | 2/2 | 0/0/0 |
|
||||
|
||||
- "next" was 0 of 2 everywhere on 2026-09-21 because the front door
|
||||
was rated without its followup page. With the followup read from
|
||||
the repo it is 2 of 2, and 0 on the twin: the followup pages do say
|
||||
what happens.
|
||||
- "asked" was 2 of 2 on the twin as well, at first, when the twin
|
||||
listed "Field 1, Field 2, Field 3": the count alone got a yes. The
|
||||
twin now has no form line, and the control passes.
|
||||
- LIX rose from 16-29 to 18-35 once headings and labels were left out
|
||||
of the count; the subcontractor page is the one that reads "easy"
|
||||
rather than "very easy".
|
||||
- The 1 of 2 on job-application is the apprentice, the same persona
|
||||
the answerer misroutes on headings alone.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{"choice":"Get a professional building survey","confidence":0.95,"id":"housing-board-damp@/"}
|
||||
{"choice":"Get a professional building survey","confidence":0.95,"id":"buyer-before-purchase@/"}
|
||||
{"choice":"Plan your building project with us","confidence":0.95,"id":"attic-conversion@/"}
|
||||
{"choice":"Plan your building project with us","confidence":0.95,"id":"shop-to-flat@/"}
|
||||
{"choice":"Become a trusted subcontractor","confidence":0.95,"id":"electrician-firm@/"}
|
||||
{"choice":"Become a trusted subcontractor","confidence":0.95,"id":"scaffolder@/"}
|
||||
{"choice":"Join our carpentry team","confidence":0.95,"id":"carpenter-jobseeker@/"}
|
||||
{"choice":"Join our carpentry team","confidence":0.95,"id":"apprentice@/"}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{"choice":"Get a professional building survey","confidence":0.95,"id":"housing-board-damp@/"}
|
||||
{"choice":"Get a professional building survey","confidence":0.95,"id":"buyer-before-purchase@/"}
|
||||
{"choice":"Plan your building project with us","confidence":0.95,"id":"attic-conversion@/"}
|
||||
{"choice":"Plan your building project with us","confidence":0.95,"id":"shop-to-flat@/"}
|
||||
{"choice":"Become a trusted subcontractor","confidence":0.95,"id":"electrician-firm@/"}
|
||||
{"choice":"Become a trusted subcontractor","confidence":0.95,"id":"scaffolder@/"}
|
||||
{"choice":"Join our carpentry team","confidence":0.95,"id":"carpenter-jobseeker@/"}
|
||||
{"choice":"Get a professional building survey","confidence":0.85,"id":"apprentice@/"}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"build-enquiry": {
|
||||
"control": {
|
||||
"asked": 0,
|
||||
"next": 0,
|
||||
"which": 0
|
||||
},
|
||||
"control_ok": true,
|
||||
"followup_shown": true,
|
||||
"lix": 26.25,
|
||||
"options": 4,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 5,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"job-application": {
|
||||
"control": {
|
||||
"asked": 0,
|
||||
"next": 0,
|
||||
"which": 0
|
||||
},
|
||||
"control_ok": true,
|
||||
"followup_shown": true,
|
||||
"lix": 26.952380952380956,
|
||||
"options": 4,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 3,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 1
|
||||
}
|
||||
},
|
||||
"report-site-issue": {
|
||||
"control": {
|
||||
"asked": 0,
|
||||
"next": 0,
|
||||
"which": 0
|
||||
},
|
||||
"control_ok": true,
|
||||
"followup_shown": true,
|
||||
"lix": 17.933333333333334,
|
||||
"options": 1,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 3,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"subcontractor-application": {
|
||||
"control": {
|
||||
"asked": 0,
|
||||
"next": 0,
|
||||
"which": 0
|
||||
},
|
||||
"control_ok": true,
|
||||
"followup_shown": true,
|
||||
"lix": 34.61904761904762,
|
||||
"options": 4,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 5,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
},
|
||||
"survey-enquiry": {
|
||||
"control": {
|
||||
"asked": 0,
|
||||
"next": 0,
|
||||
"which": 0
|
||||
},
|
||||
"control_ok": true,
|
||||
"followup_shown": true,
|
||||
"lix": 24.785714285714285,
|
||||
"options": 4,
|
||||
"overloaded": false,
|
||||
"personas": 2,
|
||||
"required_fields": 4,
|
||||
"steps": 1,
|
||||
"understanding": {
|
||||
"asked": 2,
|
||||
"next": 2,
|
||||
"which": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
content repo written to /tmp/claude-1000/-home-bl-repos-portal/b7802cea-728f-42d2-a751-680a973ba17d/scratchpad/det/nemotron2
|
||||
OK: 12 question(s), 5 aggregate(s) valid
|
||||
need "survey-enquiry": / [Get a professional building survey] -> "enquiries"
|
||||
need "build-enquiry": / [Plan your building project with us] -> "enquiries"
|
||||
need "log-phone-enquiry": /project_managers/log-phone-enquiry [Log a phone enquiry] -> "enquiries"
|
||||
need "subcontractor-application": / [Become a trusted subcontractor] -> "subcontractors"
|
||||
need "job-application": / [Join our carpentry team] -> "applicants"
|
||||
need "report-site-issue": /crew/report-site-issue [Report a safety issue on site] -> "site_issues"
|
||||
OK: 6 need(s) structurally met, 0 planned, 10 persona(s)
|
||||
BUILD_EXIT=0 in 130s
|
||||
=== held-out personas, qwen3:8b, full ===
|
||||
wording: 8/8 routed right (100%)
|
||||
=== held-out personas, qwen3:8b, skim ===
|
||||
wording: 8/8 routed right (100%)
|
||||
=== rate ===
|
||||
need LIX which asked next gutted twin says page load
|
||||
survey-enquiry 28 very easy 2/2 2/2 0/2 0/2 ok 4 options, 4 required
|
||||
build-enquiry 27 very easy 2/2 2/2 0/2 0/2 ok 4 options, 5 required
|
||||
subcontractor-application 29 very easy 2/2 2/2 0/2 0/2 ok 4 options, 5 required
|
||||
job-application 24 very easy 2/2 2/2 0/2 0/2 ok 4 options, 3 required
|
||||
report-site-issue 16 very easy 1/2 2/2 0/2 0/2 ok 1 options, 3 required
|
||||
ALL_DONE
|
||||
@@ -0,0 +1,2 @@
|
||||
lang: en
|
||||
title: Nordvik Bygg
|
||||
@@ -0,0 +1,44 @@
|
||||
# The whole operation: 13 needs, 6 roles, 10 aggregates, overlapping
|
||||
|
||||
Plan: `plans/contractor-full.yaml`. Built with no model, walked dry
|
||||
(every route of every aggregate), and replayed through portal's real
|
||||
aggregate engine on a throwaway NATS.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Verifier | 13 of 13 needs met, 28 pages, by construction |
|
||||
| Routes walked | 40, of which 6 are relays between roles |
|
||||
| Real engine | 40 aggregates created, 78 transitions accepted, 0 refused, 118 events |
|
||||
|
||||
Who holds buttons on what, as built:
|
||||
|
||||
- `enquiries`: project managers (6), site managers (mark surveyed; otherwise watch)
|
||||
- `claims`: site managers inspect and fix, project managers accept or reject
|
||||
- `change_orders`: project managers price, **the client approves or
|
||||
declines through their own link**, site managers complete
|
||||
- `material_orders`: site managers order, the crew confirms delivery
|
||||
- `site_issues`: site managers or the safety officer take in hand, only
|
||||
the safety officer closes; project managers watch
|
||||
- `job_requests`: project managers award; **subcontractors watch**,
|
||||
which is how they see what there is to bid on
|
||||
|
||||
What this plan exposed, none of it fixed yet:
|
||||
|
||||
1. **The project managers' desk is one page with 9 aggregates and 32
|
||||
buttons.** The builder puts every aggregate a role touches on one
|
||||
desk page. Past a handful it has to tier: a hub that lists the
|
||||
aggregates with what is waiting in each, and a page per aggregate.
|
||||
2. **The front door offers 6 alternatives**, one over the page-load
|
||||
limit. It wants a first question ("a building of yours", "work with
|
||||
us", "a site of ours next door") and a second page under each.
|
||||
3. **Aggregates do not know about each other.** A bid names its job in
|
||||
a free-text field; a change request names its job by address.
|
||||
Nothing says "a bid belongs to a job request" or "a change order
|
||||
exists only while an enquiry is won". That is the tiering between
|
||||
state machines still to be designed: a need that arises when a
|
||||
record elsewhere reaches a state, and carries its id.
|
||||
4. **A shared button is walked by one role only.** Where two roles both
|
||||
hold `open -> surveyed`, the dry run presses it as the first of them.
|
||||
5. **Anyone in `clients` opens the change-request form**, and portal
|
||||
has no per-record ownership beyond the submitter's link, so a
|
||||
client group sees nothing of its own cases afterwards.
|
||||
@@ -0,0 +1,40 @@
|
||||
{"persona":"route","need":"survey-enquiry","run":0,"target":"won","record":{"note":"dry run"},"states":["open","surveyed","quoted","won"],"pressed":["open -> Surveyed","surveyed -> Quoted","quoted -> Won"],"moved_by":["project_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"route","need":"survey-enquiry","run":1,"target":"lost","record":{"note":"dry run"},"states":["open","surveyed","quoted","lost"],"pressed":["open -> Surveyed","surveyed -> Quoted","quoted -> Lost"],"moved_by":["project_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"survey-enquiry","run":2,"target":"lost","record":{"note":"dry run"},"states":["open","surveyed","lost"],"pressed":["open -> Surveyed","surveyed -> Lost"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"survey-enquiry","run":3,"target":"lost","record":{"note":"dry run"},"states":["open","lost"],"pressed":["open -> Lost"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"build-enquiry","run":0,"target":"won","record":{"note":"dry run"},"states":["open","surveyed","quoted","won"],"pressed":["open -> Surveyed","surveyed -> Quoted","quoted -> Won"],"moved_by":["project_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"route","need":"build-enquiry","run":1,"target":"lost","record":{"note":"dry run"},"states":["open","surveyed","quoted","lost"],"pressed":["open -> Surveyed","surveyed -> Quoted","quoted -> Lost"],"moved_by":["project_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"build-enquiry","run":2,"target":"lost","record":{"note":"dry run"},"states":["open","surveyed","lost"],"pressed":["open -> Surveyed","surveyed -> Lost"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"build-enquiry","run":3,"target":"lost","record":{"note":"dry run"},"states":["open","lost"],"pressed":["open -> Lost"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"warranty-claim","run":0,"target":"rejected","record":{"note":"dry run"},"states":["open","rejected"],"pressed":["open -> Rejected"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"rejected"}}
|
||||
{"persona":"route","need":"warranty-claim","run":1,"target":"rejected","record":{"note":"dry run"},"states":["open","inspected","accepted","rejected"],"pressed":["open -> Inspected","inspected -> Accepted","accepted -> Rejected"],"moved_by":["site_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"rejected"}}
|
||||
{"persona":"route","need":"warranty-claim","run":2,"target":"fixed","record":{"note":"dry run"},"states":["open","inspected","accepted","fixed"],"pressed":["open -> Inspected","inspected -> Accepted","accepted -> Fixed"],"moved_by":["site_managers","project_managers","site_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"fixed"}}
|
||||
{"persona":"route","need":"warranty-claim","run":3,"target":"rejected","record":{"note":"dry run"},"states":["open","inspected","rejected"],"pressed":["open -> Inspected","inspected -> Rejected"],"moved_by":["site_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"rejected"}}
|
||||
{"persona":"route","need":"neighbour-complaint","run":0,"target":"answered","record":{"note":"dry run"},"states":["open","answered"],"pressed":["open -> Answered"],"moved_by":["site_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"answered"}}
|
||||
{"persona":"route","need":"subcontractor-application","run":0,"target":"approved","record":{"note":"dry run"},"states":["open","awaiting_papers","approved"],"pressed":["open -> Awaiting papers","awaiting_papers -> Approved"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"route","need":"subcontractor-application","run":1,"target":"declined","record":{"note":"dry run"},"states":["open","awaiting_papers","declined"],"pressed":["open -> Awaiting papers","awaiting_papers -> Declined"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"subcontractor-application","run":2,"target":"approved","record":{"note":"dry run"},"states":["open","approved"],"pressed":["open -> Approved"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"approved"}}
|
||||
{"persona":"route","need":"subcontractor-application","run":3,"target":"declined","record":{"note":"dry run"},"states":["open","declined"],"pressed":["open -> Declined"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"job-application","run":0,"target":"hired","record":{"note":"dry run"},"states":["open","interviewing","offered","hired"],"pressed":["open -> Interviewing","interviewing -> Offered","offered -> Hired"],"moved_by":["project_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"hired"}}
|
||||
{"persona":"route","need":"job-application","run":1,"target":"declined","record":{"note":"dry run"},"states":["open","interviewing","offered","declined"],"pressed":["open -> Interviewing","interviewing -> Offered","offered -> Declined"],"moved_by":["project_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"job-application","run":2,"target":"declined","record":{"note":"dry run"},"states":["open","interviewing","declined"],"pressed":["open -> Interviewing","interviewing -> Declined"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"job-application","run":3,"target":"declined","record":{"note":"dry run"},"states":["open","declined"],"pressed":["open -> Declined"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"change-request","run":0,"target":"declined","record":{"note":"dry run"},"states":["open","priced","declined"],"pressed":["open -> Priced","priced -> Declined"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"change-request","run":1,"target":"declined","record":{"note":"dry run"},"states":["open","priced","approved","declined"],"pressed":["open -> Priced","priced -> their own link","approved -> Declined"],"moved_by":["project_managers","submitter","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"change-request","run":2,"target":"completed","record":{"note":"dry run"},"states":["open","priced","approved","completed"],"pressed":["open -> Priced","priced -> their own link","approved -> Completed"],"moved_by":["project_managers","submitter","site_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"completed"}}
|
||||
{"persona":"route","need":"change-request","run":3,"target":"declined","record":{"note":"dry run"},"states":["open","declined"],"pressed":["open -> Declined"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"log-phone-enquiry","run":0,"target":"won","record":{"note":"dry run"},"states":["open","surveyed","quoted","won"],"pressed":["open -> Surveyed","surveyed -> Quoted","quoted -> Won"],"moved_by":["project_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"won"}}
|
||||
{"persona":"route","need":"log-phone-enquiry","run":1,"target":"lost","record":{"note":"dry run"},"states":["open","surveyed","quoted","lost"],"pressed":["open -> Surveyed","surveyed -> Quoted","quoted -> Lost"],"moved_by":["project_managers","project_managers","project_managers"],"touches":3,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"log-phone-enquiry","run":2,"target":"lost","record":{"note":"dry run"},"states":["open","surveyed","lost"],"pressed":["open -> Surveyed","surveyed -> Lost"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"log-phone-enquiry","run":3,"target":"lost","record":{"note":"dry run"},"states":["open","lost"],"pressed":["open -> Lost"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"lost"}}
|
||||
{"persona":"route","need":"post-job-request","run":0,"target":"awarded","record":{"note":"dry run"},"states":["open","awarded"],"pressed":["open -> Awarded"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"awarded"}}
|
||||
{"persona":"route","need":"post-job-request","run":1,"target":"withdrawn","record":{"note":"dry run"},"states":["open","withdrawn"],"pressed":["open -> Withdrawn"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"withdrawn"}}
|
||||
{"persona":"route","need":"submit-bid","run":0,"target":"accepted","record":{"note":"dry run"},"states":["open","shortlisted","accepted"],"pressed":["open -> Shortlisted","shortlisted -> Accepted"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"accepted"}}
|
||||
{"persona":"route","need":"submit-bid","run":1,"target":"declined","record":{"note":"dry run"},"states":["open","shortlisted","declined"],"pressed":["open -> Shortlisted","shortlisted -> Declined"],"moved_by":["project_managers","project_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"submit-bid","run":2,"target":"accepted","record":{"note":"dry run"},"states":["open","accepted"],"pressed":["open -> Accepted"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"accepted"}}
|
||||
{"persona":"route","need":"submit-bid","run":3,"target":"declined","record":{"note":"dry run"},"states":["open","declined"],"pressed":["open -> Declined"],"moved_by":["project_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"declined"}}
|
||||
{"persona":"route","need":"report-site-issue","run":0,"target":"closed","record":{"note":"dry run"},"states":["open","in_hand","closed"],"pressed":["open -> In hand","in_hand -> Closed"],"moved_by":["safety_officer","safety_officer"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
{"persona":"route","need":"order-materials","run":0,"target":"delivered","record":{"note":"dry run"},"states":["open","ordered","delivered"],"pressed":["open -> Ordered","ordered -> Delivered"],"moved_by":["site_managers","crew"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"delivered"}}
|
||||
{"persona":"route","need":"order-materials","run":1,"target":"refused","record":{"note":"dry run"},"states":["open","ordered","refused"],"pressed":["open -> Ordered","ordered -> Refused"],"moved_by":["site_managers","site_managers"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"refused"}}
|
||||
{"persona":"route","need":"order-materials","run":2,"target":"refused","record":{"note":"dry run"},"states":["open","refused"],"pressed":["open -> Refused"],"moved_by":["site_managers"],"touches":1,"ask_backs":[],"outcome":{"outcome":"finished","detail":"refused"}}
|
||||
{"persona":"route","need":"safety-round-finding","run":0,"target":"closed","record":{"note":"dry run"},"states":["open","in_hand","closed"],"pressed":["open -> In hand","in_hand -> Closed"],"moved_by":["safety_officer","safety_officer"],"touches":2,"ask_backs":[],"outcome":{"outcome":"finished","detail":"closed"}}
|
||||
@@ -0,0 +1,43 @@
|
||||
# The whole contractor, tiered behind three doors, worded and scored
|
||||
|
||||
`plans/contractor-full.yaml` as restructured on 2026-09-22: the six
|
||||
public needs behind `your-building` (survey, build, warranty claim)
|
||||
and `work-with-us` (subcontractor, job), with the neighbour's
|
||||
complaint straight on the front door. Thirteen needs, six roles,
|
||||
thirty pages. Built with nemotron-3.5-lightning:30b-a3b writing the
|
||||
words, all pages worded, verifier green by construction (the earlier
|
||||
dry build of the same plan, before doors, is in
|
||||
`../contractor-full-2026-09-21/`). Visitor: qwen3:8b, one task per
|
||||
call. Twenty held-out personas, twenty-two tasks.
|
||||
|
||||
| Visitor could read | Routed right |
|
||||
|---|---|
|
||||
| Headings and descriptions | 18 of 22 |
|
||||
| Headings only | 15 of 22 |
|
||||
|
||||
- **One page, two headings that mean the same thing.** Behind
|
||||
`work-with-us` nemotron wrote "Apply to work with us" for the
|
||||
subcontractor form and "Find a job with us" for the job form. All
|
||||
four personas crossed over on headings alone: both firms chose
|
||||
"Find a job", both jobseekers chose "Apply to work with us". Two of
|
||||
the four still crossed with descriptions. This is the clearest case
|
||||
of the copy rule in the whole set: two alternatives separable only by
|
||||
a distinction the business makes (a firm on a contract, a person on
|
||||
the payroll) and the visitor does not. The heading has to say
|
||||
"firm" and "carpenter", not "apply" and "job".
|
||||
- **"Your building project" does not cover a problem.** On headings
|
||||
alone, the housing board with damp and the customer with a leaking
|
||||
bathroom both chose "Neighbour complaint" over "Your building
|
||||
project": neither has a project, both have a complaint about a
|
||||
building. The door's description rescues them; the heading fails.
|
||||
- **The electrical firm chose the building door** both times, from
|
||||
"Your building project" reading as the general door.
|
||||
- **A warranty claim and a building problem** are one thing to the
|
||||
customer with cracked render, and the page offers both.
|
||||
|
||||
The two doors did their job: nobody was lost on the front door for
|
||||
lack of a door. What went wrong is the wording on the pages behind
|
||||
them, and the plan's own split of warranty from survey, which the
|
||||
customer does not make.
|
||||
|
||||
`rate.txt` is the page-by-page rate; see `rate.json`.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user