This repository is a monorepo with two services:
The storefront is built using SvelteKit. All queries to the API are defined using GraphQL, but via an autogenerated SDK created by @graphql-codegen
. E.g.
query FeaturedProducts {
products(where: { isFeatured: { equals: true } }) {
...ProductSummary
}
}
const { products } = await sdk.FeaturedProducts();
The API is powered by Keystone, which is a CMS that provides a GraphQL API which the storefront consumes. Note that this API is not publicly available, and is restricted to requests coming from the storefront
service.
All of the data comes from Printful via their API.
npm install && npm run build
npm run start
You'll need the following environment variables:
ENVIRONMENT=/* staging | production */
BASE_URL=/* environment specific domain for store frontend (IMPORTANT: no trailing slash) */
PUBLIC_ASSETS_PATH=/* public URL to images S3 bucket e.g. https://cdn.store.brave.com */
API_URL=/* url (not including the path) where GraphQL api can be found */
PRINTFUL_API_TOKEN=/* api token from printful */
PRINTFUL_BASE_URL=https://api.printful.com
PRINTFUL_STORE_ID=/* store id from printful */
STRIPE_KEY=/* key for making requests to Stripe */
STRIPE_WEBHOOK_SECRET=/* key for making listening to Stripe webhooks */
SENTRY_DSN=/* DSN for Sentry alerts */
cd api && npm install && npm run build
npm run start
You'll need the following environment variables:
ENVIRONMENT=/* staging | production */
SESSION_SECRET=/* 32 character code */
DB_URL=/* db url, e.g. localhost:5432 */
S3_IMAGES_BUCKET=/* bucket name from s3 */
PUBLIC_ASSETS_PATH=/* public URL to images S3 bucket e.g. https://cdn.store.brave.com */
PRINTFUL_API_TOKEN=/* api token from printful */
PRINTFUL_BASE_URL=https://api.printful.com
PRINTFUL_STORE_ID=/* store id from printful */
SENTRY_DSN=/* DSN for Sentry alerts */
In order to develop locally, you must have PostgreSQL downloaded and running on your machine.
You'll also need to create two .env
files – one in the root of the repository, and the other in the api/
folder:
touch .env
touch api/.env
The files should be populated with the respective sets of variables as described in Production deployment, using the appropriate values for your local environment.
Ensure dependencies are installed for both the root director and the api/
directory.
npm install
cd api && npm install
cd ../ # return to root for subsequent commands
In order to start the API, open a new terminal window, cd
into api
, and start the service.
npm run dev
Running the above command will create the database if necessary and run the migrations to create the necessary tables.
You can populate the DB by going to http://localhost:3000/sync-store
and clicking the Sync now
button. Note that in our staging and production environments, images are synced to our own S3 bucket, and we do not request images directly from Printful's CDN on the storefront. However when running locally, these images will be requested from Printful's CDN unless you've authenticated with AWS with the appropriate role.
Leaving the terminal window open for the API, start the storefront from the root of the repository. In order to run this, you'll need to provide the PUBLIC_ASSETS_PATH
environment variable in order for it to be available during the initial build phase. The value should use the staging URL for the image CDN: https://cdn.store.bravesoftware.com
.
PUBLIC_ASSETS_PATH=https://cdn.store.bravesoftware.com npm run dev
The storefront uses an SDK to interact with the API which is automatically generated by @graphql-codegen
from GraphQL queries defined in src/lib/graphql/queries.graphql
.
In order to watch for changes to src/lib/graphql/queries.graphql
and trigger this generation process, you can run the following command in a new terminal (this would be the third necessary terminal).
npm run gen -- --watch "src/**/*.graphql"
Upon approval, PR branches are merged to staging
via Squash and merge
and the staging environment is rebuilt via CI/CD. Once functionality is confirmed on the staging site and the feature is ready to move to production, the staging
branch is merged into main
using the --ff-only
flag on a local machine and then pushed to the remote main
branch.
E.g.
git fetch
git merge --ff-only origin/staging
git push
Pushing to main
, like staging
, triggers CI/CD to rebuild the production environment.
flowchart LR
subgraph STAGING
direction TB
s1{{on push}} --> s2[CI/CD] --> s3([store.bravesoftware.com])
end
subgraph MAIN
direction TB
m1{{on push}} --> m2[CI/CD] --> m3([store.brave.com])
end
PR -->|Squash and merge| STAGING -->|merge --ff-only| MAIN