The add-integration Skill
Walkthrough of wiring up a new third-party service as an adapter+fake seam.
add-integration wires up a new external service, Slack, OpenAI, S3, any third-party API, using
the adapter+fake seam every existing integration in the kit already follows. The concept-level
explanation lives at
The Adapter+Fake Pattern; this page is the
skill's own steps.
The rule this skill enforces
Never call a third-party API directly from a controller or a model. Everything routes through
app/adapters/, copying either app/adapters/billing.rb (with its billing/local.rb and
billing/stripe.rb) or the simpler app/adapters/bot_check.rb as the template.
The steps
- Create
app/adapters/<service>.rbas a module with a.for(...),.client, or.enabled?entry point that returns the real client when its credential environment variable is present, and a deterministic fake with canned, sensible values otherwise. Credentials resolveENVfirst, then Rails encrypted credentials. - Put the real client and the fake in
app/adapters/<service>/. The fake has to be complete enough that the whole feature works offline against it, not just enough to avoid raising an error. - Honor a force-fake override for demos and CI, following the pattern in
Billing#stripe?. - Rescue and report failures through
ErrorReporter.report(e, context: {...}), and decide deliberately whether this integration should fail open or fail closed;BotCheck#verifyis the reference for failing closed. - Document the new credential in Bring Your Own Keys
and in
.env.example. - If the integration sends the user off-site (a hosted checkout, an OAuth consent screen, a hosted
onboarding page), add its host to
policy.form_actioninconfig/initializers/content_security_policy.rband pin it inspec/requests/content_security_policy_spec.rb. This step is the one most often missed, and the failure is completely silent: no exception, no flash, nothing in the network tab, just a button that appears dead. Adddata-turbo="false"to any form whose action redirects off-site, on the form or the submit button, or Turbo will submit it viafetchand have the cross-origin redirect blocked byconnect-srcinstead. - Write a spec covering both the fake path (works with zero credentials) and the enabled-but-invalid path (credentials present, service rejects them).
- Run
bin/check.
Next
See the equivalent walkthroughs for email and background jobs: The add-mailer and add-job Skills.