A full-stack app for generating printable artist photo collages. Sources images from iTunes, Wikipedia, Discogs, and Openverse, scores and deduplicates them, then composes a layout optimized for print. Built with DDD & Hexagonal architecture using Turborepo, pnpm workspaces, and dependency-cruiser.
This monorepo follows the Hexagonal (Ports and Adapters) architecture. The dependency flow is strictly inward:
Web/API (Drivers) -> Application (Ports/Use Cases) -> Domain (Core)
Infrastructure (Driven) -> Application (Ports)
| Package | Responsibility | Restrictions |
|---|---|---|
@starter/domain |
Business Logic, Entities, Branded Types, Zod Schemas. | Pure Logic. Zero external dependencies (except Zod). |
@starter/application |
Ports (Interfaces), Use Cases (BuildCollageUseCase), Result types. |
No DB-specific logic. No Web/HTTP logic. |
@starter/infra |
Database implementation (Drizzle), External Clients. Env validation at startup. | Implements @starter/application ports. |
apps/api |
Hono Web Server. createApp(deps) factory for DI. Composition roots: dev.ts (local), vercel.ts (production). |
Routes requests to Application use cases via injected ports. |
apps/web |
Next.js Frontend, UI Components. | Consumes API via fetch client with Zod validation. |
- Frameworks: Next.js 16+, Hono (API)
- Runtime: Node.js (ESM Native)
- Monorepo: Turborepo + pnpm Workspaces
- ORM: Drizzle ORM + libSQL/SQLite
- Validation: Zod (Everywhere)
- Type Safety: Branded Types for IDs (
ImageUrl), Zod validation at all boundaries. - Verification: Dependency Cruiser (Boundaries), Knip (Dead Code), Vitest (Testing), ESLint (Strict).
-
Install dependencies:
pnpm install
-
Environment Variables:
cp .env.example .env # Optional: set DATABASE_URL (defaults to local file:quality.db) # Optional: set NEXT_PUBLIC_API_URL for split web/api deployments
-
Database Migration:
make db:generate make db:push
-
Development: Starts Next.js (port 3000 by default) and Hono (port 3002 by default) concurrently.
make dev
-
Verification: The single source of truth for architectural integrity.
make verify
-
Push Safety: This repo ships with a local pre-push hook in
.githooks/pre-pushand a GitHub Actions workflow in.github/workflows/verify.yml. For fresh clones, point Git at the shared hooks directory:git config core.hooksPath .githooks
This repository is optimized for AI-only maintenance:
- Strict Boundaries:
.dependency-cruiser.cjsensures an agent cannot accidentally import infra into domain. - Branded Types: All IDs use branded types (e.g.,
ImageUrl) to prevent primitive obsession and mixing up IDs. - Zod Boundaries: Data is validated at every boundary (API request, DB result, Domain logic).
- Dependency Injection:
createApp(deps)factory accepts ports, making the API fully testable with in-memory implementations (novi.mockneeded). - Env Validation:
DATABASE_URLis validated via Zod at startup with clear error messages. - Verification Script: Agents must run
make verifybefore submitting any change.
.
├── apps/
│ ├── api/
│ │ └── src/
│ │ ├── index.ts # createApp() factory (DI entry point)
│ │ ├── dev.ts # Composition root (local dev)
│ │ └── vercel.ts # Composition root (Vercel production)
│ └── web/ # Next.js frontend
├── packages/
│ ├── domain/ # Pure core logic (Branded Types, Zod Schemas)
│ ├── application/ # Ports (ImageRepository), Use Cases (BuildCollageUseCase)
│ └── infra/ # Driven adapters (Drizzle, libSQL/SQLite), env validation
├── scripts/
│ └── verify.sh # Architecture & logic verification
├── Makefile # Task runner
└── turbo.json # Build pipeline
This repository was fully architected, implemented, and verified by Gemini CLI on March 29, 2026.
- Tooling: Gemini CLI
- Model: Gemini 3 Flash Preview (orchestrated via autonomous mode)
- Architect: Howard Rhee (Principal Systems Architect)
- Goal: Create a zero-drift, strictly-bounded DDD monorepo for AI-native maintenance.