Scaffold Rails app with landing page, contact form, and Keycloak SSO dashboard #1

Open
opened 2026-05-09 02:37:10 +00:00 by forgejo_admin · 2 comments
Contributor

Type

Feature

Lineage

Standalone — greenfield project replacing pal-e-hub as the platform front door.

Repo

forgejo_admin/pal-enterprises

User Story

As a visitor, I want a landing page that explains Lucas Draney's services and lets me submit a contact form, so that I can inquire about DevOps consulting, IT support, or request an account.

As an authenticated user, I want to log in once via Keycloak and land on a dashboard showing all pal-e platform tools, so that I don't need to re-authenticate when navigating between services.

Context

The platform currently uses pal-e-hub (a SvelteKit app at pal-e.tail5b443a.ts.net) as the SSO entry point. It authenticates against the pal-e Keycloak realm and shows a hardcoded list of tool surfaces. This works but is a dead-end — it's a thin wrapper with no room to grow.

pal-enterprises replaces it with a Rails app that owns the full visitor-to-user flow:

  • Unauthenticated: Landing page with services overview + contact form
  • Authenticated: Dashboard with links to all platform tools (pal-e-docs, dictionary, kanban, westside-admin, grafana, forgejo, etc.)

The Keycloak integration uses the existing pal-e realm. The current pal-e-hub client credentials are: realm=pal-e, client=pal-e-hub. A new client pal-enterprises should be registered (SOP: sop-keycloak-client-creation).

File Targets

Files to create:

  • Gemfile — Rails 8.1, pg, tailwindcss-rails, omniauth-openid-connect, turbo-rails, stimulus-rails
  • config/database.yml — connect to CNPG cluster as ldraney
  • config/environments/development.rb — allow *.ts.net hosts
  • config/initializers/omniauth.rb — Keycloak OIDC provider config
  • config/routes.rb — root, contact, auth callback, dashboard
  • app/controllers/pages_controller.rb — landing page
  • app/controllers/contacts_controller.rb — contact form submission
  • app/controllers/sessions_controller.rb — Keycloak login/logout/callback
  • app/controllers/dashboard_controller.rb — authenticated tool dashboard
  • app/views/pages/home.html.erb — landing page with services + login CTA
  • app/views/contacts/new.html.erb — contact form
  • app/views/dashboard/index.html.erb — tool cards grid (mirrors pal-e-hub surfaces)
  • k8s/dev.yaml — dev deployment with hostPath mount, gem cache PVC, Tailscale ingress
  • app/mailers/contact_mailer.rb — delivers contact form submissions via email

Files NOT relevant:

  • db/migrate/ — no migrations needed. No local user table (Keycloak is auth source). Contact form is stateless (email delivery only).

Acceptance Criteria

  • Landing page renders at / with services overview and "Sign In" button
  • Contact form at /contact collects name, email, message type, and body
  • Contact form submission sends email to admin (no DB storage)
  • "Sign In" redirects to Keycloak pal-e realm login
  • Successful Keycloak callback establishes session and redirects to /dashboard
  • Dashboard shows grid of platform tool cards with live links
  • "Sign Out" destroys session and redirects to landing page
  • Dashboard is inaccessible without authentication (redirects to /)
  • App deploys on cluster via k8s/dev.yaml with hostPath mount
  • Health check at /up returns 200

Test Expectations

  • Unit test: contact form validates presence of name, email, and message
  • Unit test: dashboard controller redirects unauthenticated users
  • Integration test: Keycloak callback creates session with expected fields (sub, name, email)
  • Run command: bin/rails test

Constraints

  • Keycloak realm: pal-e (existing, at keycloak.tail5b443a.ts.net)
  • Register new OIDC client: pal-enterprises (follow sop-keycloak-client-creation)
  • Callback URL: https://pal-enterprises.tail5b443a.ts.net/auth/keycloak/callback
  • DB user: ldraney on CNPG cluster (pal-e-postgres-rw.postgres.svc.cluster.local)
  • Contact email delivery: use existing email infrastructure or Action Mailer with SMTP
  • No local password auth — Keycloak only
  • Match the k8s dev pattern from westside-ror (ruby:3.4-slim, gem cache PVC, startupProbe on /up)
  • Add pal-enterprises to postgres namespace NetworkPolicy allow list
  • Tailwind CSS for styling, Hotwire for interactivity

Checklist

  • Keycloak client pal-enterprises registered in pal-e realm
  • Rails app scaffolded and committed
  • PR opened
  • Tests pass
  • Deployed on cluster
  • Landing page accessible at https://pal-enterprises.tail5b443a.ts.net
  • Keycloak login flow works end-to-end
  • No unrelated changes
  • pal-e-platform — platform project this belongs to
  • pal-e-hub — the SvelteKit app this replaces
  • sop-keycloak-client-creation — SOP for registering the OIDC client
### Type Feature ### Lineage Standalone — greenfield project replacing pal-e-hub as the platform front door. ### Repo `forgejo_admin/pal-enterprises` ### User Story As a visitor, I want a landing page that explains Lucas Draney's services and lets me submit a contact form, so that I can inquire about DevOps consulting, IT support, or request an account. As an authenticated user, I want to log in once via Keycloak and land on a dashboard showing all pal-e platform tools, so that I don't need to re-authenticate when navigating between services. ### Context The platform currently uses `pal-e-hub` (a SvelteKit app at `pal-e.tail5b443a.ts.net`) as the SSO entry point. It authenticates against the `pal-e` Keycloak realm and shows a hardcoded list of tool surfaces. This works but is a dead-end — it's a thin wrapper with no room to grow. `pal-enterprises` replaces it with a Rails app that owns the full visitor-to-user flow: - **Unauthenticated**: Landing page with services overview + contact form - **Authenticated**: Dashboard with links to all platform tools (pal-e-docs, dictionary, kanban, westside-admin, grafana, forgejo, etc.) The Keycloak integration uses the existing `pal-e` realm. The current `pal-e-hub` client credentials are: realm=`pal-e`, client=`pal-e-hub`. A new client `pal-enterprises` should be registered (SOP: `sop-keycloak-client-creation`). ### File Targets Files to create: - `Gemfile` — Rails 8.1, pg, tailwindcss-rails, omniauth-openid-connect, turbo-rails, stimulus-rails - `config/database.yml` — connect to CNPG cluster as `ldraney` - `config/environments/development.rb` — allow `*.ts.net` hosts - `config/initializers/omniauth.rb` — Keycloak OIDC provider config - `config/routes.rb` — root, contact, auth callback, dashboard - `app/controllers/pages_controller.rb` — landing page - `app/controllers/contacts_controller.rb` — contact form submission - `app/controllers/sessions_controller.rb` — Keycloak login/logout/callback - `app/controllers/dashboard_controller.rb` — authenticated tool dashboard - `app/views/pages/home.html.erb` — landing page with services + login CTA - `app/views/contacts/new.html.erb` — contact form - `app/views/dashboard/index.html.erb` — tool cards grid (mirrors pal-e-hub surfaces) - `k8s/dev.yaml` — dev deployment with hostPath mount, gem cache PVC, Tailscale ingress - `app/mailers/contact_mailer.rb` — delivers contact form submissions via email Files NOT relevant: - `db/migrate/` — no migrations needed. No local user table (Keycloak is auth source). Contact form is stateless (email delivery only). ### Acceptance Criteria - [ ] Landing page renders at `/` with services overview and "Sign In" button - [ ] Contact form at `/contact` collects name, email, message type, and body - [ ] Contact form submission sends email to admin (no DB storage) - [ ] "Sign In" redirects to Keycloak `pal-e` realm login - [ ] Successful Keycloak callback establishes session and redirects to `/dashboard` - [ ] Dashboard shows grid of platform tool cards with live links - [ ] "Sign Out" destroys session and redirects to landing page - [ ] Dashboard is inaccessible without authentication (redirects to `/`) - [ ] App deploys on cluster via `k8s/dev.yaml` with hostPath mount - [ ] Health check at `/up` returns 200 ### Test Expectations - [ ] Unit test: contact form validates presence of name, email, and message - [ ] Unit test: dashboard controller redirects unauthenticated users - [ ] Integration test: Keycloak callback creates session with expected fields (sub, name, email) - Run command: `bin/rails test` ### Constraints - Keycloak realm: `pal-e` (existing, at `keycloak.tail5b443a.ts.net`) - Register new OIDC client: `pal-enterprises` (follow `sop-keycloak-client-creation`) - Callback URL: `https://pal-enterprises.tail5b443a.ts.net/auth/keycloak/callback` - DB user: `ldraney` on CNPG cluster (`pal-e-postgres-rw.postgres.svc.cluster.local`) - Contact email delivery: use existing email infrastructure or `Action Mailer` with SMTP - No local password auth — Keycloak only - Match the k8s dev pattern from `westside-ror` (ruby:3.4-slim, gem cache PVC, startupProbe on `/up`) - Add `pal-enterprises` to postgres namespace NetworkPolicy allow list - Tailwind CSS for styling, Hotwire for interactivity ### Checklist - [ ] Keycloak client `pal-enterprises` registered in `pal-e` realm - [ ] Rails app scaffolded and committed - [ ] PR opened - [ ] Tests pass - [ ] Deployed on cluster - [ ] Landing page accessible at `https://pal-enterprises.tail5b443a.ts.net` - [ ] Keycloak login flow works end-to-end - [ ] No unrelated changes ### Related - `pal-e-platform` — platform project this belongs to - `pal-e-hub` — the SvelteKit app this replaces - `sop-keycloak-client-creation` — SOP for registering the OIDC client
Author
Contributor

Scope Review: NEEDS_REFINEMENT

Review note: review-1176-2026-05-08

Well-structured feature issue with all template sections present. Traceability partially complete -- story labels verified on project page, but backing notes are missing.

Issues found:

  • arch-rails-app architecture note does not exist in pal-e-docs (label arch:rails-app is present but has no backing doc)
  • sop-keycloak-client-creation is referenced in Context/Constraints but does not exist in pal-e-docs
  • Ticket exceeds 5-minute rule: 14 file targets, 10 acceptance criteria -- needs decomposition into 3-4 sub-tickets (scaffold, contact form, Keycloak SSO, dashboard)

Next steps:

  • [SCOPE] Create arch-rails-app architecture note
  • [SCOPE] Create sop-keycloak-client-creation SOP
  • [DECOMPOSE] Route to skill-decompose-ticket for sub-ticket creation
## Scope Review: NEEDS_REFINEMENT Review note: `review-1176-2026-05-08` Well-structured feature issue with all template sections present. Traceability partially complete -- story labels verified on project page, but backing notes are missing. **Issues found:** - `arch-rails-app` architecture note does not exist in pal-e-docs (label `arch:rails-app` is present but has no backing doc) - `sop-keycloak-client-creation` is referenced in Context/Constraints but does not exist in pal-e-docs - **Ticket exceeds 5-minute rule**: 14 file targets, 10 acceptance criteria -- needs decomposition into 3-4 sub-tickets (scaffold, contact form, Keycloak SSO, dashboard) **Next steps:** - [SCOPE] Create `arch-rails-app` architecture note - [SCOPE] Create `sop-keycloak-client-creation` SOP - [DECOMPOSE] Route to `skill-decompose-ticket` for sub-ticket creation
Author
Contributor

Closing — this was an umbrella issue. Work is tracked through individual phase issues #2-5 and infra issues #7, pal-e-platform#357, pal-e-deployments#156.

Closing — this was an umbrella issue. Work is tracked through individual phase issues #2-5 and infra issues #7, pal-e-platform#357, pal-e-deployments#156.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/pal-enterprises#1
No description provided.