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_KEY | Test-mode key |
The repositories
appsterisk-svc | Domain, resolver, purchase, owner writes. The only one with code today. |
appsterisk-bff | Application API (GraphQL). Empty. |
appsterisk-web | Public profile and dashboard. Empty. |
appsterisk-admin | Admin console — its own repo so a build flag cannot expose it. Empty. |
appsterisk-app | Mobile (Expo). Empty. |
appsterisk-infra | Terraform. |
appsterisk-gitops | ArgoCD desired state. |
appsterisk-artifacts | Decision records. |
appsterisk-docs | This 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.