Lonely Pine AIBuild documentation · v1.0
Halehaku Maui

The maker's portal, and the contract it writes to

Everything you need to write the RA and the system spec for Lane B, and the one interface where your half meets mine.

Prepared for
Amit
Your lane
B, the maker's portal
My lane
A, the public site
Date
11 October 2026
01 · The shop

A family art gallery at mile marker one

Halehaku Maui, Family Farm Shop. That is their own name for themselves, off the window decal. It sits at mile marker 1 on the road to Hana, which makes it the last real stop before a long winding stretch, so tour vans pull in by arrangement with the drivers.

Tourists come through daily, see something, and ask for a website. There has never been one. People go home and cannot buy. That is the whole reason this project exists, and it is worth keeping in front of you, because it tells you who the portal is really for: not the shop, the person who already left.

The room is white walls and pale floors, and every bit of colour comes from the work hanging on them. The shop is already a design system. Neutral container, work supplies the colour.

4
Makers under one roof
A family of three plus one local artist they host. It is a marketplace, not a single seller.
8
Categories so far
Silk, T-shirts, original art, oils, wall hangings, photography, woodwork, pottery.
3
Inputs she asked for
Price, photo, description. She named all three herself, unprompted.
02 · The client

Juliet runs this, and she is the user you are building for

She is an artist by default and by preference. In her own words, "I just want to paint a flower." She has built online stores before and quit, because the admin defeated her.

The single most useful line she said about the whole project:

"That's what I need is someone to make it simple because look how complicated I make it."

She also asked, three separate times and unprompted, to be taught to do it herself afterwards. That is not a nice to have. It is the deliverable she cares about most, and it is a hard design constraint on your lane: if it cannot be taught in one sitting, it is too complicated.

Her one stated condition on rebuilding at all is that it is secure. That is why payments and card data never touch what we build, and why that boundary is not negotiable and not a phase two thing. Checkout sits on a commerce backend behind us.

Felix is the contact, not the user

Juliet's son. Not a maker. He is organising this on his mother's behalf, and all client contact runs through me, so if you need something from the family, ask in Slack and I will ask.

03 · The two lanes

Where your half ends and mine begins

Yours

Lane B, the maker's portal

The internal surface Juliet uses. She takes a photo of a shirt she just painted and wants it live on the storefront without asking anyone.

  • Price, photo, description. The daily three
  • Add a new product, and probably a new category, one level deeper
  • Magic link email auth, so she holds no password
  • Writes the catalog
Mine

Lane A, the public site

The storefront a visitor sees. It renders the catalog and does not own it.

  • Phase 1 is live-ready now: an arrival site, no shop
  • Phase 2 reads your catalog and adds the shop
  • Square is linked server side by me, so no client credential reaches your portal

One interface between us: the catalog contract. You write it, the public site reads it. Nothing else crosses the line, which is why the contract is the thing to get right before either of us builds much on top of it.

04 · The catalog contract

Version 1, and the five things I changed

The first draft is in the requirements file. Below is that draft after reading it as the consumer, which is the only angle I can usefully add. Argue with it.

catalog
  version          contract version, not content version
  generated_at     ISO 8601
  makers[]
    slug           stable, internal, safe to ship today
    display_name   nullable until the family confirms
    credit_line    nullable
    bio            nullable
  products[]
    id
    maker          slug
    category       silk | tshirts | original-art | oils | wall-hangings |
                   photography | woodwork | pottery
    title
    description    editable by Juliet
    images[]       ordered, first is primary, uploadable by Juliet
      url
      width
      height
    status         draft | published
    acquire        buy | inquire
    custom         bool
    lead_time_days when custom. 12 for painted shirts, her own revision
    one_of_a_kind  bool
    variant_display list | primary_with_note
    variants[]
      label        "8.5x11 canvas", "2oz"
      price        nullable when acquire = inquire
      fulfilment   direct | dropship
      available    bool

1. maker is a record, not an enum

Everything after slug is nullable. The family has not confirmed how each maker wants to be credited, or even the spelling of one of their names, and nothing about them ships unconfirmed. This change is what lets the public site organise by medium today and take real names later as content, with no schema change on either side.

2. price is nullable, paired with acquire

Original art is one of a kind and never repeated. Her instinct was to mark those "please inquire" rather than sell them through checkout, and that is still undecided. A non nullable price field is an invitation to seed a placeholder, and a placeholder price has a way of shipping as the real one.

3. variant_display

On the oils she was specific: "I would only do the one ounce, and then underneath I'd say two ounce available at a different price. They just need one picture." The variants stay truthful with real prices. This hint tells the public site to render her way instead of printing a size table.

4. There is no alt field, on purpose

Alt text is generated on the public side from title, maker and category. She named three inputs. A fourth breaks the one thing she actually asked for.

5. status: draft | published

One toggle, so a half finished upload is not live the second she saves.

Open, and I did not want to quietly pick a model

Her T-shirt rule collides with variants. She said: "if you just put one thing for T-shirts, and then I'll just upload different pictures." One listing, many photos. But T-shirts also have sizes, and a buyer has to choose which design, which makes the photo an axis rather than a gallery. So either images carry variant identity, or there is a second axis, or her rule means something narrower than it reads. This is the first real question for your spec, and it is a good one.

Transport

Lane B publishes catalog.json. Lane A fetches it. Not a shared database. No credential crosses between us, you can ship a real file before you have a backend, and either side can be rebuilt without touching the other.

05 · Open questions

Do not invent answers to these

They are being chased with the family. If something is not written down somewhere, it is not decided, and a sensible guess ships as a fact.

#QuestionBlocksOwner
1The spelling of one maker's name. Two spellings appear in our own notesAnything user visibleNalu, with the family
2The name of the fourth artist, and what they makeCatalog completenessNalu
3Do the oils sell direct here at all? They sell wholesale through a third party todayWhether oils are a shop category or display onlyThe family
4Original art: inquire only, or real checkout?Whether price is ever null in practiceThe family
5Shipping carriers, costs and timelines per product typeFulfilment logicNalu
6Do the makers want bios, and how does each want to be credited?Public site copy, and whether maker needs a profile recordNalu, with the family
7Who controls the domainLaunch, not buildNalu

One data source is locked and may stay locked: a second existing listings account behind a two factor check that has never cleared. If it does not open, that category's copy gets written from scratch rather than migrated. Build as though it will not arrive.

06 · Ground rules

Four things that hold

Payments and card data never touch what we build

Checkout sits on a commerce backend. The portal manages catalog content only. This is the thing that lets us honestly tell her it is secure, so it is not a boundary to be revisited when something gets inconvenient.

Never invent a price

Only a handful are on record and they sit with me. Not in the portal, not in test fixtures that could be mistaken for real, not in a screenshot.

Nothing about the family ships unconfirmed

Our own notes disagreed with each other once already about who is related to whom. Names, credits and relationships get checked with them before they appear anywhere.

Build against test data

I hold every client credential and all client contact. You should never need a real client account to work, and if it looks like you do, that is a design problem to raise rather than a login to request.

07 · Where to start

If you have three days

  1. Mark up the contract. It is a draft written by its consumer, which means it is shaped by what the public site wants to render and not by what the portal needs to store. Expect it to be wrong somewhere useful.
  2. Answer the T-shirt question in your spec. It is the one modelling decision in here that has no obvious right answer, and whatever you choose will shape the upload flow.
  3. Then the upload and replace loop. One photo in, one photo swapped, visible on the other side. That proves the contract end to end and it is the thing she will actually do every week.

The hardest case in the catalog is the photographer: one source image fans out into originals plus prints across multiple sizes and multiple materials, and fulfilment splits by size, with large prints drop shipped and small ones shipped direct from the shop. That is a per variant property, not a per product one. If the schema handles him, it handles everyone, so it is worth modelling him first rather than last.