Skip to content

release: admin sidebar nav + provisioning pickers - #88

Merged
mahmutkaya merged 2 commits into
mainfrom
develop
Jul 26, 2026
Merged

mahmutkaya merged 2 commits into
mainfrom
develop

Conversation

@mahmutkaya

Copy link
Copy Markdown
Contributor

Summary

Two commits, no schema change.

Type

  • release

Money check (§6.4)

Display only — the quote is computed client-side from the catalog for the founder's benefit. Nothing reads it for a Mollie amount; plan amounts are still entered by hand at onboard time.

Migration check (§5.2)

None. prisma/migrations/ untouched — no migrate one-off before rolling the app.

Deploy notes

  • Merge builds the image; rollout is manual: docker compose -f docker-compose.prod.yml pull sofra && up -d sofra on the staging box.
  • Verify after: /admin shows the sidebar, and /admin/provision shows checkboxes with a price line instead of two text inputs.
  • Rollback: re-point SOFRA_TAG at the prior image and up -d sofra.

mahmutkaya and others added 2 commits July 26, 2026 06:43
…#87)

The generated entry butted directly against the previous tenant's trailing
comment, so the comment read as if it introduced the new tenant. Two newlines
instead of one; the ReDoS-safe trimEnd() approach is unchanged.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
#86)

* feat(admin): grouped sidebar nav + catalog-driven provisioning pickers

Three owner-reported navigation/entry problems, all versions of "the UI knows
less than the code does".

**Nav.** Ten equal-weight links in a header row is a list to scan, not a
structure to navigate. Admin now gets a grouped sidebar — pipeline (who wants to
buy) / tenants (who is running) / money / system — sticky beside the content on
desktop. Below `lg` it renders as one compact wrapped row instead of the
vertical column: a sidebar on a phone means scrolling past ten links to reach
the page, which is worse than what it replaced. Group labels are dropped there
because the grouping is a desktop scanning aid, not information. The partner
dashboard keeps the inline header nav — it has one to three destinations.

**Modules + languages were free-text comma lists.** They asked the founder to
remember eight module ids and ten locale codes, then rejected typos after the
fact. Both are now checkboxes generated from the ADR-010 catalog, submitting the
same values (the action reads `getAll` and joins, so the schema and the registry
entry are unchanged — a plain `get()` would have silently taken the first box).

Two things fell out of building it:
* The selection now shows its **monthly list price**, resolved through
  `quoteModules`, so the number the founder types into /admin/onboard comes from
  the catalog instead of a mental sum. Ticking kitchen-board + cashier +
  printing reads "€ 45,00 — as bundle «counter» (à la carte € 52,00)".
* Picking a third language priced `extra-languages` but did not record it, so
  the tenant would have been billed for a module their registry entry never
  claimed. The hidden input now follows the quote.

`en` is fixed (the tenant app's fallback locale) and `core` is fixed (every
instance runs it): both are stated rather than offered, and carried by hidden
inputs since a disabled checkbox submits nothing.

Verified in a browser against the real Tailwind build — desktop and mobile,
light and dark — and by reading the serialized FormData back out:
`core,kitchen-board,cashier,printing,extra-languages` / `en,nl,fr`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(provision): keep non-string form entries out of the registry (Sonar S6551/S7776)

getAll() is typed (string | File)[], so a crafted multipart POST could put a
File under `modules` and join() would stringify it to "[object Object]" —
straight into a registry proposal. Filtered to strings behind a named helper
that says what it is. Language lookup moves to a Set while nearby.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@sonarqubecloud

Copy link
Copy Markdown

@mahmutkaya
mahmutkaya merged commit 3448920 into main Jul 26, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant