Members Portal & Marketplace¶
start.mdapi.ch is the human front door to the platform: a portal where members
see their services and a marketplace where they can request new ones. It is the
piece that turns a homelab into a small multi-tenant service provider.
flowchart LR
member["Member"] --> portal["Portal UI\nstart.mdapi.ch"]
portal --> resolve["Windmill f/portal\nresolve board / entitlements / health"]
portal --> req["Marketplace requests\nf/marketplace"]
guest["Prospective member"] --> door["Public request form\nstart.mdapi.ch/request/"]
door --> req
req -->|"approval (Pushover tap-links)"| owner["Operator"]
req --> prov["Provisioning flows\nmailbox · access (live)\nSFTP · subdomain · website (staged)"]
prov --> estate["LDAP · mail · DNS · web · storage"]
Portal¶
The portal renders a per-member board: which services they have, their health,
and entry links. It is backed by typed Windmill scripts (f/portal/* —
resolve_board, resolve_entitlement, resolve_health) called through scoped
tokens; the paths are frozen as a public API surface for the portal frontend.
Tiles are entitlement-driven — a member only sees what they hold.
The public door¶
Not every request comes from someone who already has an account. start.mdapi.ch/request/
is an unauthenticated form that feeds the same marketplace flows: it negotiates its
language from the browser (Italian, French, English) and is gated by a self-hosted
proof-of-work challenge rather than a third-party captcha, so the public entry point
sends no visitor data to anyone else. A submission raises the same operator approval as
an in-portal request; approval creates the LDAP identity, and the person sets their own
password through a time-limited link — no password is ever chosen on the form or mailed.
People the Plex library is already shared with can Continue with Plex on the request
form: a small sign-in bridge (plex-auth.mdapi.ch) confirms the share and prefills the
request. It only proves eligibility — Plex is not a login method, and the request still
waits for operator approval, where the username and the Family or Friends group are chosen.
Marketplace¶
Two request types are reachable end-to-end from the portal UI today: a
mailbox, and access to an existing service. Three more — an SFTP area, a
subdomain, a website — exist as f/marketplace/* provisioning flows but have
no wired entry point in the frontend yet, staged for a future portal release.
Every request type, live or staged, shares the same shape:
- Each request type has a provisioning flow that performs the real work end-to-end — LDAP identity, mailbox + autoconfig, DNS record, web vhost, storage quota — as one transaction.
- Sensitive request types carry an approval gate: the operator receives a Pushover message with tap-to-approve/deny links (the platform's standard human-in-the-loop pattern), and the flow resumes on the answer.
- Everything lands in the same estate planes documented elsewhere: mail, DNS, auth/LDAP.
Why it exists¶
Family-and-friends tenancy with real self-service: the operator approves intents, not tickets — and the provisioning itself is code-reviewed, versioned, and identical every time.