File Structure

Overview

backend/bun/
├── apps/
│   └── monolith/                  ← Main Hono application
│       └── src/
│           ├── api-gateway/      ← Routes, middleware, error handling
│           │   ├── middleware/   ← Rate limit, idempotency, i18n, logging
│           │   ├── routes/       ← REST endpoints
│           │   └── errors/       ← Custom error classes
│           ├── config/           ← DI container, env schema
│           └── index.ts          ← App entry point
├── packages/
│   ├── domain/                   ← Business logic (no external deps)
│   │   ├── entities/            ← User, Session, Message
│   │   ├── value-objects/      ← Email, UserId
│   │   ├── events/             ← Domain events
│   │   └── index.ts
│   ├── application/             ← Use cases & ports
│   │   ├── use-cases/          ← Business workflows
│   │   ├── ports/              ← Interfaces (Repository, Cache)
│   │   └── index.ts
│   └── infrastructure/          ← External adapters
│       ├── database/            ← MongoDB repositories
│       ├── cache/               ← BunRedis + InMemory fallback
│       ├── i18n/               ← Translation service
│       ├── logging/             ← SmartLogger + transports
│       └── index.ts
├── config/
│   └── MONOLITH_CONFIG.md       ← Configuration reference
├── docs/                        ← Documentation
└── package.json

apps/monolith/

Main application entry point. Wires together:
  • Hono server setup
  • Middleware registration
  • Route mounting
  • DI container setup

packages/domain/

Pure TypeScript — no framework imports.
// Example: User entity
export class User {
  constructor(
    public readonly id: UserId,
    public readonly email: Email,
    public readonly role: UserRole,
    private readonly _createdAt: Date,
  ) {}

  isAdmin(): boolean {
    return this.role === UserRole.ADMIN;
  }
}

packages/application/

Use cases orchestrate domain logic. Each use case:
  1. Receives input
  2. Calls domain services
  3. Returns domain objects
  4. Emits domain events
// Example: CreateUserUseCase
export class CreateUserUseCase {
  constructor(
    private userRepo: UserRepositoryPort,
    private eventBus: EventBusPort,
  ) {}

  async execute(input: CreateUserInput): Promise<User> {
    const user = User.create(input);
    await this.userRepo.save(user);
    await this.eventBus.publish(new UserCreated(user));
    return user;
  }
}

packages/infrastructure/

Adapters implementing application ports.
AdapterPackageDescription
MongoDBdatabase/UserRepository, SessionRepository
Rediscache/BunRedisCache with InMemoryCache fallback
i18ni18n/JSON file-based translations
Loggerlogging/Console, File, MongoDB transports

Module Rules

  • domain/ has zero external dependencies
  • application/ only depends on domain/
  • infrastructure/ implements application/ ports
  • apps/monolith/ orchestrates everything

Key Files

PathPurpose
apps/monolith/src/index.tsApp bootstrap
apps/monolith/src/config/di-container.tsDependency injection
packages/application/ports/Interface definitions
packages/infrastructure/database/MongoDB implementations