Artsy Order Management
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci service:exchange Jan 9, 2019
.vscode [WIP] Improves some tooling and gets us closer to the mutation technique Aug 6, 2018
app Fix spec Feb 12, 2019
config Code review comments Jan 3, 2019
db rename offer_note to note Jan 30, 2019
hokusai new way of doing events Jan 9, 2019
lib Solution II for fixing missing failed transactions Feb 12, 2019
public faviconned Oct 29, 2018
spec Add proper spacing Feb 12, 2019
tmp Initial 👋🏼 Jun 6, 2018
vendor Initial 👋🏼 Jun 6, 2018
.coveralls.yml Try .coveralls file Sep 28, 2018
.env.example add protections Oct 10, 2018
.gitignore More test Sep 28, 2018
.rubocop.yml Clean up some RuboCop config Jan 28, 2019
.rubocop_todo.yml Clean up some RuboCop config Jan 28, 2019
.ruby-version Upgrade Ruby version Oct 22, 2018
Dangerfile Update danger Sep 11, 2018
Dockerfile comment Jan 9, 2019
Gemfile Remove chromedriver-helper gem Nov 6, 2018
Gemfile.lock Upgrade to latest event-service to fix .to_json issue Jan 30, 2019
LICENSE Fixed typo Jun 13, 2018 Add to ease local development Nov 29, 2018 graduate Exchange to production Feb 12, 2019
Rakefile Add Rake task so that `bundle exec rake` fails when there's schema diff Nov 6, 2018
_schema.graphql rename offer_note to note Jan 30, 2019
dangerfile.ts Update Readme and new danger rule Oct 26, 2018

Exchange CircleCI Coverage Status

Exchange aspires to be responsible for the various types of e-commerce interactions available on the Artsy platform. It's currently a prototype, with legacy e-commerce still handled by Gravity. It uses Ruby, Rails, Postgresql, and exposes a GraphQL API.




PRs merged to master are automatically deployed to staging by CI.


Mention in #dev slack channel that you are going to deploy and then run:

hokusai pipeline promote --git-remote upstream

Assuming upstream points to Artsy's repository.


  • Fork the project to your GitHub account

  • Clone your fork:

    $ git clone
  • Install bundles:

    $ bundle install


Once setup, you can run the tests like this:

$ bundle exec rspec

Starting Server

If this is your first time starting the app, make sure your database is setup first by running:

rails db:create
rails db:setup

Then run via foreman to start the web (rails) and worker (sidekiq) services:

foreman start -f

Did You Change Models?

Papertrail Audit Logging

As Exchange persists important financial information, we use the PaperTrail gem to maintain a log of data changes to important models within the main relational database.

Exchange implements a slightly-customized, but supported, installation of PaperTrail. By default, PaperTrail writes audit log records to a single versions table. In Exchange, we write audit logs into model-namespaced tables. For example, the audit log for Order records are in the order_versions table and the audit log for Offer records are in the offer_versions table.

Why do we do this? It'll allow PostgreSQL to query across smaller sets of data when operating against the audit log for a particular model.

How to implement this pattern for future models:

  1. Include the versioned model shared example in the spec for your model:
  # spec/models/foo_spec.rb
  describe Foo, type: :model do
    it_behaves_like 'a papertrail versioned model', :foo
  1. Ensure that a Fabricator factory exists for your model:
  # spec/fabricators/foo_fabricator.rb
  Fabricator(:foo) do
    # define enough attributes to have a `valid?` instance of `Foo`
  1. Include the customized PaperTrail DSL in your model (provides #versions):
  # app/models/foo.rb
  class Foo < ApplicationRecord
    has_paper_trail class_name: 'PaperTrail::FooVersion'
  1. Define the model-specific version class:
  # app/models/paper_trail/foo_version.rb
  module PaperTrail
    class FooVersion < PaperTrail::Version
      self.table_name = :foo_versions
  1. Create the model-specific versions table:
  bundle exec rails generate migration add_foo_versions
  # db/migrate/timestamp_add_foo_versions.rb
  class AddFooVersions < ActiveRecord::Migration[5.2]
    def change
      create_table :foo_versions do |t|
        t.string   :item_type, null: false
        t.uuid     :item_id,   null: false
        t.string   :event,     null: false
        t.string   :whodunnit
        t.jsonb    :object
        t.jsonb    :object_changes
        t.datetime :created_at

      add_index :foo_versions, %i[item_type item_id]

N.B: If the model being versioned uses a different type of primary key (i.e. integer instead of UUID), feel free to change the t.uuid to t.#{another_type}


Analytics Notification

If you changed something in the /models make sure to inform #data (analytics) team about it in case it impacts their reports.

Did You Change GraphQL Schema?

Metaphysics is the current consumer of Exchange GraphQL schema and keeps a copy of latest schema in, if you have changed Exchange GraphQL schema, make sure you also update the copy of this schema in Metaphysics. In order to do so follow these steps:

  1. In exchange run
rake graphql:schema:idl
  1. rename schema.graphql file generated ☝🏼 to exchange.graphql
mv schema.graphql exchange.graphql
  1. copy file above to your local update Metaphysics under src/data and make a PR to Metaphysics with this change.

There is a guide on how to add exchange operations to Metaphysics here

Talking to Exchange 🤑

In order to talk to Exchange GraphQL endpoint:

  • Copy .env.example to .env
  • Update the REPLACE_ME values in the .env file. You can reference the values used on staging with hokusai staging env get.
  • Install dotenv by gem install dotenv
  • Start local server dotenv rails s
  • If you work at Artsy, get proper Gravity User Token following these instructions (the client application name is "Exchange Staging").
  • Install and run GraphiQL app brew cask install graphiql
  • In GraphiQL app, go to http://localhost:3000/api/graphql, you should ge unauthorized error
  • Edit HTTP Headers and add Authorization header and set it to Bearer <token> where <token> is your Gravity token generated few steps above.

Working at Artsy?

GraphQL Queries

We share our GraphQL sample queries using Insomnia shared workspace. You can import latest queries from environments_and_requests.json

Get Access To Exchange

Access to Exchange Admin is limited to users with the role "Sales Admin". Ask someone with Role Manager permissions to grant your user "Sales Admin" permissions.


Something went wrong? Ideally in the JSON response returned from Exchange there will be enough info to describe what went wrong. In case that was not useful, you can:

  1. Check Sentry (password in 1Pass) and look for Exchange (staging or production) and see the error.
  2. Follow exchange logs by doing
hokusai staging logs -f

If you think there is something we could improve in this error case, feel free to open an issue with details about what you did and what went wrong.