Hermes

Grails Guru & Self-Service Portal Advisor. Expert guidance on Grails/Groovy views (GSP), and self-service portal architecture.


A Quick Note On Working with Hermes

Hermes is your Grails Guru & Self-Service Portal Advisor — expert guidance on Grails/Groovy views (GSP), and self-service portal architecture. In practice, the work he handles is centered on data-driven admin interfaces and web portals. Think CRUD-heavy admin panels with tables, filters, status badges, and document/payment flows — Grails GSP views + layouts, GORM/Hibernate for domain modeling, daisyUI 5 + Tailwind 4 for the UI layer, and a built-in theme switcher.

The chat session below is a real-world example of how a conversation with Hermes might look — someone who saw the one-click Billing Portal in the Seed-Data video and wants the same thing with their own invoice data model and their own branding. Read it, pick up the rhythm.

But you don't have to follow any of it. You don't need a billing portal. Just open the chat with Hermes and tell him what you need — an admin dashboard, a self-service portal, a document viewer, whatever Grails web app you have in mind. He'll adapt.

Go chat with Hermes. Go build stuff.


Billing Portal — Make It Yours

How the crew works — in theory vs. in practice. In theory, you start with Athena: she gathers requirements, writes a PRD, and hands the spec to a specialist (see Athena → New Billing Portal). In practice, for a well-trodden ask like an invoice portal, people walk straight up to the specialist — "I saw the Seed-Data video, I want that, but mine." Both paths are fine. This page shows the direct one. If the model gets complex, Hermes loops Athena in.

The key idea: you don't rebuild — you re-skin. The Billing Portal in the video is a shipped example (_apps/flowkraft/99-custom/_examples/billing-portal-grails/_custom/). Making it yours is copying its _custom/ folder and changing two things: your data model and your brand. The app-seed.groovy does the rest — it scaffolds the app from the grails-playground blueprint, applies your overrides/, and writes the DataPallas push report that feeds invoices in over REST. No "build on a copy, then hand-delete the sample code" — that step is gone.

The Ask — "make it mine"

Hermes (Grails Guru & Self-Service Portal Advisor)
A
Admin10:57 AM
Hi Hermes. I saw the video where a Billing Portal appeared right from the Seed Data screen — one click and it was live. I need the same thing, but with my invoice data model and my branding — my company name, my colours. Can you help?
K
kraftbot10:57 AM

Absolutely — and here's the good news: you don't rebuild it. That portal in the video is a shipped example. You copy its _custom/ folder, change exactly two things — your data model and your brand — and run it from Seed Data, just like the video. Two-thirds of the work already exists.

One note on process: in theory, for a brand-new or complex model I'd send you to Athena first — she'd write a quick PRD and hand the spec back to me. In practice, an invoice portal is well-trodden ground, so let's go direct. If we hit anything gnarly, we loop Athena in.

A
Admin10:57 AM
Perfect — direct works for me. Where do I start?
Send a message...

The Shipped Example & the _custom Convention

Hermes (Grails Guru & Self-Service Portal Advisor)
K
kraftbot10:57 AM

Start from the shipped example. It lives at _apps/flowkraft/99-custom/_examples/billing-portal-grails/_custom/. A custom app is just four things — copy them to your own folder and edit in place:

1_apps/my-billing-portal/_custom/
2├── app.json # id, name, port, launch links, tablePrefix, apiKey
3├── app-seed.groovy # scaffolds the app + writes the DataPallas push report
4├── overrides/ # ONLY your changed files (domain, controllers, views, brand)
5└── README.md # the recipe

Copy the example's _custom/ to _apps/my-billing-portal/_custom/. Everything unchanged — the Grails build, Dockerfile, layouts, theme picker, payments — comes from the grails-playground blueprint at scaffold time. You never fork the whole app; overrides/ holds only the files you actually touch.

A
Admin10:57 AM
Got it — copy the folder, then two edits. Let's do the data model first.
Send a message...

Your Data Model

Hermes (Grails Guru & Self-Service Portal Advisor)
A
Admin10:57 AM
My invoices are simple: invoice number, issue and due dates, a status, a customer (name, email, company, VAT id), line items (description, qty, unit price), and a total.
K
kraftbot10:57 AM

That maps almost 1:1 onto the example's bp_* model. There are three touch-points, all in overrides/, all following the existing pattern:

  1. The domain overrides/grails-app/domain/com/flowkraft/Invoice.groovy (plus Customer/InvoiceLine). Add your fields.
  2. The REST ingest ApiInvoiceController at POST /api/invoices/ingest. It upserts the customer by email and the invoice by number; add your new fields to the payload it accepts.
  3. The push query — in app-seed.groovy's writePushReport, the SQL that reads your source rows and maps columns → the ingest payload.

The domain — add vatId and you're done:

1class Invoice {
2 String invoiceNumber
3 Date invoiceDate
4 Date dueDate
5 String status // PAID / DUE / OVERDUE
6 String vatId // ← your new field
7 BigDecimal subtotal, tax, total
8
9 static belongsTo = [customer: Customer]
10 static hasMany = [lines: InvoiceLine]
11}

DataPallas bursts your source invoices and curls each one to /api/invoices/ingest — the portal renders them. So the model, the ingest, and the push SQL just have to agree on field names. Add vat_id to the ingest payload and to the writePushReport query, and every invoice carries your VAT id end to end.

Send a message...

Your Branding

Hermes (Grails Guru & Self-Service Portal Advisor)
A
Admin10:57 AM
Branding next. My company is Acme Freight, and I want a clean corporate look — not the DataPallas dark theme.
K
kraftbot10:57 AM

Three small edits, all in overrides/. It's daisyUI 5 + Tailwind 4, so a whole re-theme is one word:

  1. Theme views/common/_themeInit.gsp: set RB_DEFAULT_THEME = 'corporate'. daisyUI ships corporate, business, nord… — corporate is the clean light one.
  2. Logo / wordmark views/layouts/portal.gsp + admin.gsp: swap the DataPallas logo for your mark.
  3. Invoice biller views/_invoiceDocument.gsp: your company name + address.
1<!-- views/common/_themeInit.gsp -->
2window.RB_DEFAULT_THEME = 'corporate';
3
4<!-- views/layouts/portal.gsp — navbar brand -->
5<a href="${createLink(uri: '/portal')}" class="flex items-center gap-2 no-underline">
6 <span class="inline-flex items-center justify-center w-8 h-8 rounded-lg
7 bg-primary text-primary-content font-bold text-lg">A</span>
8 <span class="text-xl font-bold tracking-tight">Acme Freight</span>
9</a>

The badge uses theme colours (bg-primary text-primary-content), so it recolours with the theme automatically. That's the whole re-skin — one theme word, one badge letter, one company name. The DOM ids don't change, so it stays automation-friendly.

Send a message...

The Bundle

Hermes (Grails Guru & Self-Service Portal Advisor)
A
Admin10:57 AM
Great. Can you give me the full bundle to drop in?
K
kraftbot10:57 AM

Here's your _custom/ — drop it at _apps/my-billing-portal/_custom/. The identity lives in app.json:

1{
2 "id": "my-billing-portal",
3 "name": "Acme Freight — Billing Portal",
4 "type": "docker",
5 "url": "http://localhost:8600",
6 "tablePrefix": "bp_",
7 "apiKey": "acme-portal-key-CHANGE-ME",
8 "blueprint": "flowkraft/grails-playground",
9 "visible": false,
10 "tags": ["grails", "portal", "billing", "custom-app"]
11}

app-seed.groovy and overrides/ you carried from the example with your two edits (the vatId field and the Acme brand); the README.md is the recipe. Nothing else to write — the seed script does the scaffolding and writes the push report on its own.

Send a message...

Run It — one click from Seed Data

Hermes (Grails Guru & Self-Service Portal Advisor)
A
Admin10:57 AM
And then it's exactly like the video?
K
kraftbot10:57 AM

Exactly. Open DataPallas → any database connection → Seed Data tab → run Acme Freight — Billing Portal. The script scaffolds the app, writes the push report, and reveals the app card. Then:

  1. Apps Manager → your card appears → Start (Docker) → Launch/portal and /admin.
  2. Processing → Generate Reports → pick Billing Portal Push (Acme) Burst.
  3. Your source invoices flow over REST into the portal — customers log in and pay, admins do CRUD. Auto-created logins, correct statuses, no duplicates on re-run.

Same one-click feel as the video — but your data model, your brand.

Send a message...

Done

Hermes (Grails Guru & Self-Service Portal Advisor)
A
Admin10:57 AM
This is exactly what I wanted. Thank you, Hermes!
K
kraftbot10:57 AM

Anytime. Notice what you didn't do: you never left daisyUI/Tailwind, never touched the plumbing, never hand-deleted sample code. Two edits and a Seed-Data run.

If you later want the identical portal in React instead of Grails, my colleague Apollo ships the same thing on Next.js — same routes, same DOM ids, same seeded data. Go build.

Send a message...