# 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." }