Skip to content

Instantly share code, notes, and snippets.

@schpet
Created February 4, 2026 19:30
Show Gist options
  • Select an option

  • Save schpet/8ed1d355242c948422346404483df58c to your computer and use it in GitHub Desktop.

Select an option

Save schpet/8ed1d355242c948422346404483df58c to your computer and use it in GitHub Desktop.
Prefab Feb-2 database + guestbook notes

prefab-feb-2 Database Navigator + Guestbook GraphQL Issue

Last updated: 2026-02-04

Overview

  • Builder/target stack running on prefab-feb-2 host (current box, public IP 134.209.44.21).
  • Database Navigator tab in build session originally failed because app/services/database namespace wasn’t autoloaded. We fixed this locally on prefab-feb-2 by:
    • Adding app/services to autoload_paths and eager_load_paths in config/application.rb.
    • Creating app/services/database.rb and updating app/services/database/error_classes.rb to satisfy Zeitwerk naming.
    • Running docker-compose run --rm builder-web bundle exec rails zeitwerk:check (passed) and restarting builder containers.
  • Chrome MCP verification still fails when pointed at prefab-feb3 because that domain resides on a different host (159.89.44.171). Our changes only exist on prefab-feb-2.

Current State on prefab-feb-2

  • Builder UI (https://creator.prefab-feb-2.allspark.build) shows Database tab and lists tables successfully after fix.
  • Live Preview for guestbook project still errors when fetching guestbookEntries GraphQL query:
    • Request: POST https://prefab-feb-2.allspark.build/graphql
    • Response: 422 ActionController::InvalidAuthenticityToken coming from GraphqlController#execute.
    • Stack trace shows ActionController::RequestForgeryProtection raising InvalidAuthenticityToken.
    • Request headers (from Rails exception page):
      • Origin: https://prefab-feb-2.allspark.build
      • X-CSRF-Token: CzWNBO5y...
      • Session _csrf_token stored as _HRbwAaVh0Bav7sUKJaEG-1IFKSUC-zXq1hQbLPfwps.
    • The Apollo client (frontend) includes credentials: "same-origin" and pulls token from <meta name="csrf-token">.

Suspected Root Cause of GraphQL CSRF Failure

  • Build session Live Preview is embedded via iframe under creator.prefab-feb-2.allspark.build, but the guestbook app lives at https://prefab-feb-2.allspark.build/. Cross-origin navigation likely causes Rails session mismatch:
    • GraphQL controller requires valid Rails session (current_user or verified CSRF token). Non-authenticated visitors hitting guestbook site probably aren’t logged in, so session/cookie may not exist.
    • GraphqlController calls before_action :raise_on_invalid_token; if HTTP_AUTHORIZATION header present without current_user, it returns 401. Not the case here.
    • Instead, verify_authenticity_token fails. Could be because session cookie isn’t shared between builder (creator.) and target domain (prefab-feb-2.). CSRF tokens tied to session, so values mismatch.
    • Need to allow GraphQL to accept tokens from target domain even when session mismatch, probably by setting protect_from_forgery with: :null_session or skipping verification for API clients.

Potential Fix Approaches

  1. Allow GraphQL POSTs without CSRF check

    • In GraphqlController, add protect_from_forgery with: :null_session or skip_before_action :verify_authenticity_token so that stateless API requests succeed. Must ensure authentication handled elsewhere.
    • Many Rails GraphQL APIs disable CSRF because clients manage tokens differently. Since guestbook is public, null_session likely acceptable.
  2. Ensure Meta Tag Token Matches Session

    • Confirm csrf_meta_tags on guestbook layout emits token tied to visitor session. Already there (app/views/layouts/application.html.erb). If requests originate from same domain, should work.
    • However, Live Preview loads https://prefab-feb-2.allspark.build/ inside iframe but runs script from same origin, so browser should send cookies. Maybe GraphQL request originates before meta tag loads? Unlikely.
    • Another angle: GraphQL endpoint may be served from builder (creator) not target, but screenshot shows direct request to prefab-feb-2.allspark.build/graphql (same origin). So maybe session isn’t established before query because we haven’t visited page? But initial GET should set session.
  3. Double-check config/initializers/cors.rb or host configs

    • If Rails sees Origin header even on same origin? It should allow.

Given time, easiest is to skip CSRF check for GraphQL controller on prefab-feb-2 and apply same on prefab-feb3 later.

Files of Interest

  • config/application.rb (autoload path fix already applied)
  • app/services/database.rb, app/services/database/error_classes.rb
  • app/controllers/api/v2/database/build_sessions_controller.rb (CSRF skip already present via skip_before_action :verify_authenticity_token)
  • app/controllers/graphql_controller.rb (needs CSRF adjustment)
  • Frontend Apollo link: app/frontend/common/create-apollo-link.ts.
  • Layout with csrf meta: app/views/layouts/application.html.erb.

Next Steps (for prefab-feb-3 once accessible)

  1. Pull latest builder repo changes or copy modified files from prefab-feb-2 host.
  2. Run docker-compose run --rm builder-web bundle exec rails zeitwerk:check.
  3. Restart builder containers.
  4. Verify Database tab on prefab-feb3 domain via Chrome MCP.

Next Steps (Guestbook GraphQL on prefab-feb-2)

  1. Decide on CSRF strategy for GraphQL controller; likely skip_before_action :verify_authenticity_token or protect_from_forgery with: :null_session.
  2. Redeploy target or restart target-web container after change.
  3. Reload Live Preview to confirm guestbook entries load without 422.

This document lives at /tmp/prefab-feb2-database.md on prefab-feb-2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment