guinness-backend Directory Architecture
The guinness-backend monorepo is a Turborepo workspace using Bun. It contains 4 apps (user API, admin API, MCP-v2 server, PostgreSQL migrations) and 4 shared packages. For infrastructure topology, see Admin Infrastructure and User Infrastructure.
Repository Structure
guinness-backend/
apps/
app/ # @guinness-backend/app โ User-facing REST API (Hono + Bun)
admin/ # @guinness-backend/admin โ Admin REST API (Hono + Bun)
mcp-v2/ # @guinness-backend/mcp-v2 โ Model Context Protocol server
migration-pg/ # @guinness-backend/migration-pg โ PostgreSQL schema migrations (Drizzle Kit)
packages/
models/ # @guinness-backend/models โ PostgreSQL Drizzle ORM schemas
utils/ # @guinness-backend/utils โ Shared utilities (auth, errors, pagination, etc.)
guinness-backend-sdk/ # Shared backend and test helpers
typescript-config/ # @guinness-backend/typescript-config โ Shared tsconfig
docs/ # MkDocs documentation site
bin/ # Operational scripts (SSM sessions for RDS/DocDB)
api-collections/ # API collection files (Postman/Bruno)
App Structure Pattern
Each API app (app, admin, mcp-v2) follows a 4-layer architecture: routes โ services โ repositories โ models.
apps/app/src/
server.ts # Bun server entry point
app.ts # Hono app configuration
config/
env.ts # Environment variable validation (Zod)
database.ts # Database connection config
cognito.ts # AWS Cognito client config
middlewares/
protected-route.ts # JWT auth middleware
error-handler.ts # Global error handling
rate-limit.ts # Rate limiting
winston-logger.ts # Request logging
routes/v1/ # HTTP handlers (per-domain files)
services/ # Business logic (per-domain files)
repositories/ # Data access โ Drizzle queries (per-domain files)
schemas/
components/ # OpenAPI component schemas (Zod)
routes/ # Per-route request/response schemas (Zod)
types/
endpoint/ # Per-endpoint type definitions
lib/
database.ts # DB connection pool singleton
server.ts # Server setup helper
utils/
pagination.ts # Pagination helpers
security.ts # Security utilities
The admin app extends this pattern with additional authorization middlewares (require-admin-access, require-organization-access, require-project-access, require-user-access, resolve-actor-admin, access-level-rank).
Request Flow
Requests pass through the following layers in order.
Client Request
โ
Middlewares (auth, logging, error handling)
โ
Routes (request validation, response formatting)
โ
Services (business logic)
โ
Repositories (data access)
โ
Database / External Services (AWS Cognito, S3, SQS)
Middleware Pipeline
| Middleware | File | Role |
|---|---|---|
requestId() |
hono/request-id |
Attaches a unique request ID for tracing |
winstonLogger() |
middlewares/winston-logger.ts |
Structured request / response logging (including duration) |
cors() |
hono/cors |
Cross-origin resource sharing |
compress() |
hono/compress |
Gzip response compression |
rateLimit() |
middlewares/rate-limit.ts |
Request rate limiting |
protectedRoute |
middlewares/protected-route.ts |
JWT verification and Cognito sub extraction |
errorHandler |
middlewares/error-handler.ts |
Centralized error handling with unified response format |
Layer Implementation Patterns
Routes Layer
Handles HTTP, validation, and response formatting. Contains no business logic โ delegates to Services.
route.openapi(getUser, async (c) => {
const { user_id } = c.req.valid('param');
const { sub: requesterUsername } = c.get('auth');
try {
const user = await userService.findOneById(user_id, requesterUsername);
return c.json(formatOutput(user));
} catch (error) {
logger.error('Failed to fetch user', { error, user_id });
throw error;
}
});
Services Layer
Implements business rules, orchestrates multiple repositories, and integrates with external services (Cognito, S3, SQS).
export async function findOneById(
userId: string,
requesterUsername: string
): Promise<User> {
const user = await userRepository.findById(userId);
if (!user) throw new NotFoundError(`User ${userId} not found`);
if (!hasPermission(requesterUsername, user)) throw new ForbiddenError('Insufficient permissions');
return user;
}
Repositories Layer
Responsible only for database operations using Drizzle ORM. Contains no business logic.
export async function findById(userId: string): Promise<User | null> {
const result = await db
.select()
.from(users)
.where(and(eq(users.id, userId), isNull(users.deletedAt)))
.limit(1);
return result[0] ?? null;
}
Error Handling
Standard Error Response
All errors are returned in the following JSON format.
HTTP Status Codes
| Status | Usage |
|---|---|
400 Bad Request |
Invalid input data |
401 Unauthorized |
Missing or invalid authentication |
403 Forbidden |
Insufficient permissions |
404 Not Found |
Resource not found |
409 Conflict |
Resource conflict (e.g. duplicate) |
500 Internal Server Error |
Unexpected server error |
Shared Package Responsibilities
| Package | Key files | Responsibility |
|---|---|---|
packages/models |
postgresql/*.ts |
Drizzle ORM schema definitions for all tables, per-table files with relations |
packages/models |
postgresql/shared/audit-fields.ts |
Shared audit columns (created_at, updated_at) |
packages/models |
postgresql/shared/constants.ts |
Shared DB constants |
packages/utils |
src/cognito-jwt.ts |
JWT verification for Cognito tokens |
packages/utils |
src/error.ts |
Custom error classes (Validation, Unauthorized, Forbidden, NotFound, Conflict, InternalServer) |
packages/utils |
src/pagination.ts |
Pagination helpers |
packages/utils |
src/logger.ts |
Winston logger setup |
packages/utils |
src/encryption.ts |
Encryption/decryption utilities |
packages/utils |
src/response.ts |
API response formatting |
packages/utils |
src/retry.ts |
Retry logic with exponential backoff |
packages/utils |
src/request-validation.ts |
Request validation helpers |
packages/utils |
src/figma.ts |
Figma API helpers |
packages/guinness-backend-sdk |
src/test-utils/postgres-container.ts |
Testcontainers PostgreSQL setup |
packages/guinness-backend-sdk |
src/test-utils/vitest-global-setup.ts |
Vitest global setup for test DB |
packages/typescript-config |
base.json, app.json |
Shared tsconfig presets |
Shared Dependencies
| Package | Purpose |
|---|---|
hono |
Web framework (v4.12) โ routing, middleware, OpenAPI |
drizzle-orm |
Database ORM โ PostgreSQL query builder |
drizzle-kit |
Schema migration tool |
zod (v4) |
Schema validation โ request/response, env vars |
@aws-sdk/client-* |
AWS SDK โ S3, SQS, Cognito, DocumentDB |
winston |
Structured logging |
testcontainers |
PostgreSQL testcontainers for integration tests |
vitest |
Test runner |
biome |
Linting + formatting |
turbo |
Monorepo build orchestration |
lefthook |
Git hooks management |