Bucket names describe content, not their relation to portal:
portal_applicants -> applicants, portal_subscribers -> subscribers,
portal_project_inquiries -> projects. ResourceSpec's `bucket:` field
becomes `source: {kind: kv, bucket: ...}` to match portal's new
generalized ResourceSource schema.
The project-inquiry alternative now also shows a live "what we've
built" showcase (a gitea_starred resource, jq-shaped) and asks who the
work is for (organization/contact fields) - b2b framing. Review desk's
"Inquiries" -> "Projects", transitions to accepted/declined instead of
a generic "handled".
Front page gets a `responsible` contact for the "report this question"
mechanism.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
portal-content
Question/alternative/feature content for the portal app,
kept in its own repo so content edits don't require a Rust rebuild or
touch app code at all.
Schema
Each file in questions/ is one Question (see portal's
src/content.rs for the exact struct). A question has one or more
alternatives; each alternative is a small form made of features,
each holding zero or more requirements (input fields).
id: /some-path # matches a route; "/" is the landing page; English slugs
name: Headline
description: >
Markdown body text.
alternatives:
- name: Alternative label
description: One line explaining this path.
action: /next-question # id of the question to advance to on submit
consequence: [Button label]
features:
- name: A feature/section heading
description: Optional supporting text.
requirements:
- name: email
label: Email
type: email
type on a requirement is one of: text, textarea, email, tel,
select. Omit for plain text. Mark a requirement optional: true if
it isn't required.
There is deliberately no color/icon styling here — the app has a
single brand accent variable, not per-alternative colors. And there's
no branching/criteria language yet: today a human reads submissions off
NATS and decides what happens next. If that grows into something an LLM
posts follow-up questions into later, it publishes into the same shape
these files already are — this repo's format doesn't need to change for
that, just its source.
Adding a question
Drop a new questions/<id>.yaml file and reference its id from an
existing alternative's action. No registration step - the app loads
every file in the directory at startup.