Barber example app
The Barber examples put Simfinity's generated API into a booking application. Run either database backend with the same Next.js frontend, then explore customer booking, the owner dashboard, and shop administration.
Both apps consume released Simfinity runtime packages at exactly 3.2.0 from npm. Each backend and the shared frontend have independent manifests and lockfiles outside the library workspaces. The examples have a dedicated validation workflow and are not npm libraries.
For a smaller starting point, use the MongoDB quick start or PostgreSQL quick start.
Run an example
Install Docker with Compose v2, clone the repository, and enter the example directory:
git clone https://github.com/simtlix/simfinity.js.git
cd simfinity.js/examples/barber
cp .env.example .envChoose one stack:
docker compose -f compose.mongodb.yaml up --build -d --wait
docker compose -f compose.mongodb.yaml exec backend npm run seed:admin
docker compose -f compose.mongodb.yaml exec backend npm run seed:demodocker compose -f compose.postgres.yaml up --build -d --wait
docker compose -f compose.postgres.yaml exec backend npm run seed:admin
docker compose -f compose.postgres.yaml exec backend npm run seed:demo| MongoDB | PostgreSQL | |
|---|---|---|
| Open the app | http://localhost:4401 | http://localhost:4501 |
| GraphQL / GraphiQL | http://localhost:4400/graphql | http://localhost:4500/graphql |
| MCP HTTP endpoint | http://localhost:4400/mcp | http://localhost:4500/mcp |
| Database host port | 57417 | 55441 |
Compose waits for database and application health. MongoDB runs a single-node replica set; PostgreSQL runs version 18 and initializes the generated storage. The projects have separate ports and volumes, so both can run together. Their ports bind to loopback by default.
Explore the booking flow
The minimal seed creates an approved shop with slug barber-demo, a service named “Corte clásico”, and the professional “Alex Demo”. Sign in with one of these synthetic accounts; all use password demo1234:
| Account | Role | Example flow |
|---|---|---|
cliente@demo.com | Client | Browse the shop, select a service and professional, and create a booking. |
propietario@demo.com | Owner | Manage the shop's catalog and bookings in the dashboard. |
admin@demo.com | Platform administrator | Inspect users and shop approval. |
This is a local MVP with synthetic data. Payment is on site, and the reminder job is a stub. The example demonstrates application patterns rather than a production deployment configuration.
What the code demonstrates
GraphQL types describe shops, services, bundles, professionals, bookings, reviews, favorites, and notifications. Relationship metadata connects them; generated operations support the frontend's reads and writes. Controllers enforce domain checks and derive values such as booking totals. State machines implement shop approval and booking transitions.
Query scopes and JWT permission rules apply according to the current user. HTTP MCP calls use the same bearer-token context as GraphQL, and each backend also provides npm run mcp:stdio for an MCP process with a configured user context.
| Concern | MongoDB implementation | PostgreSQL implementation |
|---|---|---|
| Identity | ObjectId exposed as GraphQL ID | UUID exposed as GraphQL ID |
| Native access | Mongoose models, documents, and sessions | PostgreSQL models, plain records, and sessions |
| Relationships | References and embedded documents | UUID foreign keys, JSONB values, and private tables for embedded references |
| Initialization | Connect to the replica set and register types | Register types and await storage initialization |
The shared frontend treats IDs as opaque strings. The backends keep their native database operations separate while demonstrating the same domain concepts. The database guide and PostgreSQL reference explain the broader compatibility boundaries.
To inspect the PostgreSQL schema, run npm run schema:export from examples/barber/postgres with its database configured. It writes current GraphQL SDL, generated SQL, and foreign keys read from the real PostgreSQL catalog into ignored generated/ files. These are local inspection artifacts, not packaged downloads.
Development and validation
Use Node.js 24 for host development and install each app with its own npm ci. Backend .env.example files configure host database connections and API ports. The frontend uses .env.local; its NEXT_PUBLIC_GRAPHQL_URL must be browser-reachable and is embedded at build time.
The Barber workflow runs independently from library CI. It validates backend units, frontend checks, HTTP/MCP behavior, and browser flows against both databases. Both backends check real transactions, derived domain values, and dataset loading/deletion; PostgreSQL adds storage, foreign-key, and frontend-query checks. Root library lint and Vitest discovery exclude example applications.
The repository runbooks contain environment options, commands, and source provenance:
Stop or reset
From examples/barber, stop the selected project while keeping its data:
docker compose -f compose.mongodb.yaml down
# Or:
docker compose -f compose.postgres.yaml downAdd --volumes only to erase that example's database and uploaded demo files. Start and seed it again to restore a fresh demo. Each Compose file targets its own named project, so resetting one leaves the other stack's data intact.