Xuemi is a Bun-first HTTP API built with Elysia, Prisma, and PostgreSQL. The service currently exposes health checks, user creation, user listing, and user detail endpoints with OpenAPI documentation, typed response envelopes, structured JSON logging, and integration tests backed by Testcontainers.
Maintainer: saefulloh@vayazka.com
- Runtime: Bun
- HTTP framework: Elysia
- API documentation:
@elysiajs/openapi - ORM: Prisma 7 with
@prisma/adapter-pg - Database: PostgreSQL 18
- Testing: Bun test and Testcontainers
- Container runtime: Docker and Docker Compose
- Bun 1.3 or newer
- Docker and Docker Compose
- PostgreSQL 18 when running without Docker Compose
src/
app.ts App factory and top-level routes
database.ts Prisma client and database plugin setup
index.ts Runtime entrypoint
interface/ Domain contracts
entity/ Domain entities and entity mappers
domain/auth/ Auth/user domain routes, handlers, services, repositories
lib/dtos/ Shared API response DTOs
lib/http/ Response helpers, error handling, request execution context
lib/logger/ JSON request logging, request context, masking
generated/prisma/ Generated Prisma client
prisma/
schema.prisma Database schema
migrations/ Database migrations
tests/integration/ Integration tests
Create a local .env file:
cp .env.example .envDefault development values:
DATABASE_URL="postgresql://xuemi:xuemi@localhost:5433/xuemi?schema=public"
DB_STATEMENT_TIMEOUT_MS=10000
DB_QUERY_TIMEOUT_MS=12000
DB_TRANSACTION_MAX_WAIT_MS=5000
DB_TRANSACTION_TIMEOUT_MS=10000DATABASE_URL is required. The application fails fast when it is missing.
Install dependencies:
bun installStart PostgreSQL:
docker compose up -d postgresGenerate the Prisma client and apply migrations:
bun run db:generate
bun run db:migrateStart the API with reload:
bun run devThe API listens on http://localhost:3000 by default.
Run the API and PostgreSQL together:
docker compose up apiThe Compose api service installs dependencies, generates the Prisma client, deploys migrations, and starts the development server with Bun watch mode.
bun run db:generate # Generate Prisma client into src/generated/prisma
bun run db:migrate # Create/apply a local development migration
bun run db:deploy # Apply existing migrations, suitable for containers/CI
bun run db:push # Push schema without creating a migrationThe current schema contains a User model with:
idemailpasswordnamecreatedAtupdatedAt
OpenAPI UI:
GET /openapi
OpenAPI JSON:
GET /openapi/json
Current endpoints:
GET /health
GET /users
GET /users/:id
POST /users
Create user example:
curl -X POST http://localhost:3000/users \
-H "content-type: application/json" \
-d '{
"email": "user@example.com",
"password": "super-secret-password",
"name": "Example User"
}'Successful responses follow one envelope:
{
"success": true,
"data": {},
"error": null,
"meta": {
"request_id": "123e4567-e89b-12d3-a456-426614174000",
"trace_id": "0af7651916cd43dd8448eb211c80319c",
"timestamp": "2026-05-14T00:00:00.000Z"
}
}Error responses use the same shape:
{
"success": false,
"data": null,
"error": {
"code": "EMAIL_ALREADY_EXISTS",
"message": "Email already exists",
"details": null
},
"meta": {
"request_id": "123e4567-e89b-12d3-a456-426614174000",
"trace_id": "0af7651916cd43dd8448eb211c80319c",
"timestamp": "2026-05-14T00:00:00.000Z"
}
}Validation errors return error.details as an array:
{
"success": false,
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [
{
"path": "/email",
"field": "email",
"rule": "format",
"message": "Expected email"
}
]
},
"meta": {
"request_id": "123e4567-e89b-12d3-a456-426614174000",
"trace_id": "0af7651916cd43dd8448eb211c80319c",
"timestamp": "2026-05-14T00:00:00.000Z"
}
}HTTP requests are logged as structured JSON with:
timestampleveleventserviceenvtrace_idrequest_idmethodpathroutestatusduration_msipuser_agentpayloadresponse
Sensitive fields such as passwords, tokens, and API keys are masked in both request payloads and response bodies before logging.
Run all integration tests:
bun run test:integrationThe integration test suite uses Testcontainers and starts PostgreSQL automatically.
Run integration tests inside Docker Compose:
docker compose --profile test run --rm integration-testRun a focused test file:
bun test tests/integration/logger/logger-plugin.test.tsbun x tsc --noEmitProject-local imports use absolute paths:
import { createApp } from "src/app";
import { setupIntegrationTest } from "tests/integration/helpers/test-app";Relative imports such as ./... or ../... are avoided in maintained source and test files. Generated Prisma files are excluded from this convention because they are overwritten by Prisma.
GET /healthchecks both the API process and database connectivity.request_idis a UUID when generated by the service, or the incomingx-request-idheader when provided.trace_idusestraceparentwhen present, thenx-trace-id, then a generated 32-character hexadecimal trace id.- Prisma query, statement, and transaction timeouts are configurable through environment variables.
- Request cancellation is supported at the application boundary; Prisma query cancellation is handled through database timeout configuration.