Recursivity
All projects
Open source

Smashboard

A command center for everything going on in your life

View on GitHub
LanguageRuby on Rails
InterfaceWeb & PWA
DeployDocker Compose
LicenseMIT
  • The Smashboard dashboard with panels for meetings, mail, GitHub, todos, countdowns and breaking news

The board with seeded data and stub servers — it comes up end to end before anything real is connected.

Smashboard pulls the scattered surfaces of a day into one place. Unread mail, the meetings you have left, the countdown to the thing you are dreading, your todos and habits, your bookmarks, what is happening in your GitHub notifications and your Slack DMs, the weather, the news, and the camera on the porch — all on a single board you arrange yourself.

It is a multiuser Rails app, installable as a PWA, and API-first, so a native client can be layered on later without reimplementing any of it.

Arranging the board

The board is a four-column grid, and each panel's header carries a menu with four named widths — small, medium, large, full — rather than a free resize. Those are the four values that tile without leaving a ragged gap, so the constraint is the feature. Order is drag-and-drop by the header and persists per user; nothing about one person's layout is shared with anyone else's.

Hiding a panel sets enabled: false, which also drops it from /api/v1/dashboard and stops the refresh scheduler working on it. A hidden panel costs nothing — no polling, no payload.

What it connects to

Development mirrors production, deliberately

db:prepare creates three databases — the app's own plus Solid Queue's and Solid Cable's — because the interesting behaviour only exists when they are separate. Jobs run in their own worker process so recurring tasks actually fire, and Action Cable is database-backed so a Turbo Stream broadcast from that worker reaches the browser. A bare rails server gets you a dashboard that never refreshes itself and never notifies, which is not the app.

The test suite is hermetic. WebMock is on, the test environment sets fixed encryption keys, and stub servers in script/ stand in for every upstream, so the whole board can be brought up end to end on a fresh clone with no credentials at all.

Stack

FrameworkRuby 3.4 on Rails, Hotwire (Turbo + Stimulus), Tailwind
DataPostgreSQL 18, Active Record encryption for stored credentials
Background workSolid Queue in a separate worker process
RealtimeSolid Cable — database-backed Action Cable
AuthDevise, with password-challenged credential changes
NotificationsWeb Push (VAPID)
Testing & CIRSpec + WebMock, RuboCop, Brakeman, bundler-audit
DeployDocker Compose; one file, no Ruby needed on the host