Skip to main content

Getting started

git clone git@github.com:forgers-tech/appsterisk-svc.git
cd appsterisk-svc
npm ci
cp .env.example .env
docker compose up -d postgres
npm run prisma:migrate
npm run seed
npm run start:dev

.env.example documents every variable where it is defined. Two have no safe default and the service refuses to start without them in production; outside production both degrade rather than block, so working on the namespace domain does not require a payment credential:

ENCRYPTION_KEYS<version>:<base64-32-bytes>, comma-separated. openssl rand -base64 32
STRIPE_SECRET_KEYTest-mode key

The repositories

appsterisk-svcDomain, resolver, purchase, owner writes. The only one with code today.
appsterisk-bffApplication API (GraphQL). Empty.
appsterisk-webPublic profile and dashboard. Empty.
appsterisk-adminAdmin console — its own repo so a build flag cannot expose it. Empty.
appsterisk-appMobile (Expo). Empty.
appsterisk-infraTerraform.
appsterisk-gitopsArgoCD desired state.
appsterisk-artifactsDecision records.
appsterisk-docsThis site.

Two things that will catch you

Changing prisma/schema.prisma is not changing the migrations directory. Only the second runs against a database. prisma validate passing, the build passing and every test passing says nothing about whether a table exists — this shipped a missing table to production once.

The e2e suite boots the application. That is not ceremony: it is what catches wiring that compiles cleanly, such as a circular module dependency, which TypeScript will happily build.

Testing

npm test # unit
npm run test:e2e # integration; DB-backed suites skip without DATABASE_URL
npm run lint

Unit tests mock at the module boundary. One suite deliberately does not: the purchase-race test runs against a real Postgres, because the property under test — concurrent writers serializing on a unique index — belongs to Postgres. A mocked client would only assert that the code calls the method we wrote.