Skip to content

vayazka/xuemi

Repository files navigation

Xuemi

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

Stack

  • 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

Requirements

  • Bun 1.3 or newer
  • Docker and Docker Compose
  • PostgreSQL 18 when running without Docker Compose

Project Layout

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

Environment

Create a local .env file:

cp .env.example .env

Default 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=10000

DATABASE_URL is required. The application fails fast when it is missing.

Local Development

Install dependencies:

bun install

Start PostgreSQL:

docker compose up -d postgres

Generate the Prisma client and apply migrations:

bun run db:generate
bun run db:migrate

Start the API with reload:

bun run dev

The API listens on http://localhost:3000 by default.

Docker Compose

Run the API and PostgreSQL together:

docker compose up api

The Compose api service installs dependencies, generates the Prisma client, deploys migrations, and starts the development server with Bun watch mode.

Database Commands

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 migration

The current schema contains a User model with:

  • id
  • email
  • password
  • name
  • createdAt
  • updatedAt

API

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"
  }'

Response Contract

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"
  }
}

Logging

HTTP requests are logged as structured JSON with:

  • timestamp
  • level
  • event
  • service
  • env
  • trace_id
  • request_id
  • method
  • path
  • route
  • status
  • duration_ms
  • ip
  • user_agent
  • payload
  • response

Sensitive fields such as passwords, tokens, and API keys are masked in both request payloads and response bodies before logging.

Testing

Run all integration tests:

bun run test:integration

The integration test suite uses Testcontainers and starts PostgreSQL automatically.

Run integration tests inside Docker Compose:

docker compose --profile test run --rm integration-test

Run a focused test file:

bun test tests/integration/logger/logger-plugin.test.ts

Type Checking

bun x tsc --noEmit

Import Convention

Project-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.

Operational Notes

  • GET /health checks both the API process and database connectivity.
  • request_id is a UUID when generated by the service, or the incoming x-request-id header when provided.
  • trace_id uses traceparent when present, then x-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.

About

Xuemi is a Bun-first HTTP API built with Elysia, Prisma, and PostgreSQL

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors