Skip to content

silvermind/meta_control_client

Repository files navigation

meta_control_client

A Rails engine that integrates a host app with a Meta Control server: contextual user-stories drawer + anonymous feedback channel.

Status: 0.1.0 — Spike A + Spike B. The client, the engine, the drawer flow (vanilla-JS fetch + server-rendered fragment from MC), and async feedback delivery are all wired up end-to-end. See CHANGELOG.md.

Why this exists

Replace the legacy <script src="…/app_script"> injection (jQuery + iframe + admin-cookie auth) with a proper gem: per-app Bearer token, server-to-server transport, server-rendered drawer, no end-user identity bridging. Background and decisions are in the host project's docs/plans/2026_04_app_integration/.

Install (target shape — 0.2)

# Gemfile
gem "meta_control_client"
bin/rails g meta_control_client:install

Then in config/routes.rb:

mount MetaControlClient::Engine, at: "/meta_control"

And in your layout:

<%= meta_control_drawer %>

Set MC_API_KEY (format mc_<env>_<hex>) and MC_URL in your env.

What works today

Spike A — server-to-server feedback POST

require "meta_control_client"

MetaControlClient.configure do |c|
  c.api_key  = ENV.fetch("MC_API_KEY")  # e.g. "mc_dev_3f8c…"
  c.app_slug = "my-app"
  c.mc_url   = "http://localhost:3000"
end

MetaControlClient::Client.new.post_feedback(
  {
    comment: "Refund button is hidden on mobile.",
    context: {
      schema:      "mc.context/v1",
      app_slug:    "my-app",
      environment: "development",
      request: {
        id: SecureRandom.uuid, method: "GET", path: "/orders/42",
        namespace: "", controller: "orders", action: "show",
        referrer: nil
      },
      client: { gem_version: MetaControlClient::VERSION,
                ruby: RUBY_VERSION, rails: nil }
    }
  }
)

This exercises:

  • Bearer-token authentication.
  • Idempotency-Key header (auto-generated UUID per call; pass idempotency_key: to override for retries).
  • HTTP error mapping → MetaControlClient::Errors::*.

The host-side Meta Control endpoint (POST /api/v1/feedbacks) is itself part of a separate work-stream; for the spike, point mc_url at a Webmock stub or a hand-rolled local server.

Spike B — drawer fetch flow inside a non-Turbo Rails host

The gem mounts at /meta_control and ships a vanilla-JS drawer that fetches the MC-rendered fragment on click. End-to-end exercised by the request specs under spec/requests/ against the dummy Rails 8 host app under spec/dummy/. Verified flows:

  • GET /meta_control/drawer builds the §8 context (app + route, no user data), proxies to MC, and returns the HTML fragment to the browser (200).
  • When MC is unreachable, the engine returns a minimal fallback fragment with just a feedback form — the drawer never appears broken to the user.
  • POST /meta_control/feedbacks (sync mode) proxies the submission to MC and forwards MC's response.
  • POST /meta_control/feedbacks (async mode, the production default) enqueues DeliverFeedbackJob and returns 202 immediately.
  • The meta_control_drawer view helper, when included in the host's layout, injects an offcanvas shell with a stable data-* API consumed by app/assets/javascripts/meta_control_client.js.

Architecture

Host Rails app                              Meta Control server
─────────────                                ───────────────────
                                            POST /api/v1/feedbacks
MetaControlClient::Client ─── HTTPS ─────►  GET  /api/v1/drawer
   (Bearer mc_<env>_<hex>,                  GET  /api/v1/health
    Idempotency-Key: <uuid>)

Full design: 01_design.md in the Meta Control repo.

Development

bundle install
bundle exec rspec

Spike A spec: spec/lib/meta_control_client/client_spec.rb. WebMock-based stubs live in spec/support/stub_meta_control.rb.

License

MIT — see LICENSE.

About

`meta_control_client` is an open-source Rails engine + Ruby library that integrates a host Rails app with a [Meta Control][mc] server.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors