Skip to content

Phase 4: previews, development inbox, generators, allowlist - #4

Merged
timimsms merged 1 commit into
mainfrom
phase-4-devx
Oct 16, 2026
Merged

timimsms merged 1 commit into
mainfrom
phase-4-devx

Conversation

@timimsms

@timimsms timimsms commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Implements Phase 4 of docs/SPEC.md. Stacked on #3 (then #2 and #1). Merge in order.

What's included

  • Previews. Smswire::Preview classes in test/messengers/previews or spec/messengers/previews, served at <mount>/previews. Each message renders in a phone frame with sender, category, provider, encoding, segment count, and units remaining in the current segment. A warning names any characters that force UCS-2. Previews build the message without running interceptors or sending, and there's a raw-text view.
  • Development inbox. <mount>/inbox lists recent deliveries and inbound messages, with status, segments, and errors. A form simulates a reply such as STOP through the same handler the webhook uses, so the full opt-out loop can be tested locally.
  • Generators.
    • smswire:install copies migrations idempotently, writes a commented initializer and ApplicationMessenger, and mounts the engine.
    • smswire:messenger Order shipped delivered writes the class, one template per action, a preview, and a test.
    • smswire:provider Acme writes an adapter skeleton in app/sms_providers, a WebMock test, and a registration line.
  • Allowlist interceptor. For staging. It either suppresses messages to unlisted numbers or, with redirect_to:, reroutes them to one phone with the original recipient prefixed to the body.

Notes

  • Previews and the inbox are enabled with config.smswire.show_previews and config.smswire.show_inbox, both on in development only. As in Action Mailer, preview paths are registered for autoloading before Rails builds autoload paths, so these settings belong in config/application.rb or an environment file, not config/initializers.
  • The pages are self-contained, with inline CSS that follows the system light or dark setting. Tables scroll inside their panels on narrow screens.
  • The dummy app now uses a file-backed SQLite database. An in-memory one disappeared whenever Active Record opened a second connection, which made tests fail depending on order. Every test class now resets the Smswire tables through one shared helper.

Verification

  • 144 tests, 478 assertions, passing on Rails 7.1, 7.2, 8.0, and 8.1.
  • Ten consecutive randomized runs pass on Rails 8.1, and two runs pass on each older Rails line.
  • The acceptance test runs the messenger generator into a scratch directory, loads the output, and checks that the preview page lists it and renders the body with "GSM-7" and "1 segment". It also checks that development deliveries appear in the inbox.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L5SuBiSMN4r9qr5CXbKkHV

Smswire::Preview and a previews page that renders each message in a
phone frame with encoding, segment count, remaining characters, and the
characters that force UCS-2. A development inbox lists deliveries and
inbound messages and simulates replies through the shared inbound
handler. Both are enabled with config.smswire.show_previews and
show_inbox, default to development only, and register preview paths
for autoloading the way Action Mailer does.

Generators for install (migrations, initializer, ApplicationMessenger,
engine mount), messengers (class, templates, preview, test), and
provider adapters. An allowlist interceptor suppresses or redirects
messages to unlisted numbers for staging.

The dummy app now uses a file-backed SQLite database, since an
in-memory one is lost when a second connection opens, and every test
class resets the Smswire tables before running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L5SuBiSMN4r9qr5CXbKkHV
@timimsms
timimsms changed the base branch from phase-3-consent to main October 16, 2026 05:21
@timimsms
timimsms merged commit 6422bf0 into main Oct 16, 2026
13 checks passed
@timimsms
timimsms deleted the phase-4-devx branch October 16, 2026 05:22
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