Frontend Architecture: ISS

arch-frontend-iss Architecture

architecture active

Frontend Architecture: ISS

Rails view layer with Hotwire (Turbo + Stimulus) and Propshaft asset pipeline. Answers: how does the UI render and what conventions govern it?

Diagram




          
  

Components

Component Purpose Notes
<code>application.html.erb</code> Root layout — nav, tab bar, flash messages, content yield Wraps all authenticated views. Includes <code>_tab_bar.html.erb</code> partial for bottom navigation.
<code>_tab_bar.html.erb</code> Bottom tab bar navigation shared across all authenticated views Role-aware: shows different tabs for admin vs lead/client. Tabs: Catalog, Projects, Communications, Account (+ CRM for admin).
<code>pages/landing.html.erb</code> Public landing page — the sales pitch and App Store CTA Root route (<code>root "pages#landing"</code>). No auth required. Marketing-only — no login form.
Propshaft Asset fingerprinting and serving No Node.js build step. CSS files served directly with fingerprinted URLs.
importmap-rails ES module management without bundler Pins Turbo, Stimulus, and application JS via importmap. No webpack/esbuild.
Turbo Drive SPA-like page transitions without full reloads Default Hotwire behavior — intercepts link clicks and form submissions.
Turbo Frames Partial page updates scoped to a frame Used for inline editing, modal-like flows, tab content switching.
Turbo Streams Real-time DOM updates via WebSocket (Solid Cable) Used for live messaging updates. Backed by Solid Cable (PostgreSQL, no Redis).
Stimulus Modest JS framework for DOM behavior Controllers for interactive UI elements. No heavy client-side state.

CSS Conventions

Convention Detail
Design tokens CSS custom properties on <code>:root</code> in <code>application.css</code>. Brand colors: <code>--color-accent: #1b2a4a</code> (navy), <code>--color-gold: #996d13</code>.
Per-view stylesheets One CSS file per view area: <code>dashboard.css</code>, <code>catalog.css</code>, <code>messages.css</code>, <code>profile.css</code>, <code>tab_bar.css</code>, <code>forms.css</code>, <code>pages.css</code>, <code>admin_catalog.css</code>.
No utility-first Semantic class names, not Tailwind. Styles reference design tokens via <code>var(--color-*)</code>.
Mobile-first Base styles target mobile (Turbo Native shell). Desktop breakpoints added as needed.

Key Decisions

  • Propshaft + importmap over esbuild/webpack — No Node.js build step. Propshaft handles asset fingerprinting; importmap-rails pins ES modules directly. Simpler deploy, fewer moving parts.
  • Hotwire over React/Vue SPA — Server-rendered HTML with Turbo Drive for navigation, Turbo Frames for partial updates, Turbo Streams for real-time. One codebase serves both web and Turbo Native iOS.
  • Semantic CSS with design tokens — All colors, spacing, and typography flow from CSS custom properties defined once in application.css. No Tailwind. ISS brand palette (navy + gold) enforced via tokens.
  • Per-view CSS files — Each view area gets its own stylesheet. Avoids monolithic CSS. Propshaft serves them individually with fingerprinting.
  • Tab bar as shared partial_tab_bar.html.erb renders role-aware navigation. Admin sees CRM tab; leads/clients do not. Consistent bottom nav across the iOS shell.
  • Landing page outside authpages#landing is the root route, served without authentication. All other views require login via the authenticate_user! filter.
  • Solid Cable for WebSocket — Turbo Streams use Solid Cable backed by PostgreSQL. No Redis dependency for real-time features.

Key Directories

Path Contents
<code>app/views/layouts/</code> <code>application.html.erb</code> — root layout with tab bar
<code>app/views/shared/</code> <code>_tab_bar.html.erb</code> — role-aware bottom navigation
<code>app/views/pages/</code> <code>landing.html.erb</code> — public landing page
<code>app/views/dashboard/</code> Authenticated dashboard views
<code>app/views/catalog/</code> Public catalog browsing
<code>app/views/admin/catalog/</code> Admin CRUD for catalog entries
<code>app/views/messages/</code> Messaging thread views
<code>app/views/profile/</code> User profile display and edit
<code>app/assets/stylesheets/</code> Per-view CSS files with shared design tokens