Skip to content

Architecture

Repository layout

doto/
├── packages/
│   ├── web/                     # React web frontend (Vite)
│   ├── server/                  # Hono API server
│   │   ├── prisma/
│   │   │   ├── schema.prisma
│   │   │   └── migrations/
│   │   ├── prisma.config.ts     # Prisma v7 config
│   │   └── src/
│   │       ├── ai/              # AI provider abstraction
│   │       ├── auth/            # API key generation & middleware
│   │       ├── constants/       # Shared constants
│   │       ├── lib/             # Utilities (prisma, errors, pagination, response)
│   │       ├── plugins/         # Hono plugins
│   │       ├── routes/          # Route handlers
│   │       ├── tasks/           # Status machine
│   │       ├── types/           # TypeScript types
│   │       ├── app.ts           # App factory
│   │       └── index.ts         # Entry point
│   ├── cli/
│       └── src/
│           ├── commands/        # auth, task, team, inbox
│           ├── lib/             # config, http client, output formatting
│           └── types/
├── bun.lock
├── docker-compose.yml
└── tsconfig.json

Tech stack

LayerTechnology
RuntimeBun ≥ 1.3.12
LanguageTypeScript 5 (ESM)
Package managerBun workspaces
API frameworkHono
ORMPrisma 7 + @prisma/adapter-pg
DatabasePostgreSQL 16
ValidationZod
Web frontendReact 18 + Vite
CLI frameworkCommander.js
TestingVitest
ContainersDocker Compose

Request lifecycle

HTTP Request
  → Hono router
  → authMiddleware
      → extract Bearer token
      → hash → DB lookup
      → attach c.get('user')
  → Route handler
      → Zod validation
      → Business logic
      → Prisma query
  → Response envelope { data: T }
  → Error handler (on throw)
      → AppError → status + code
      → ZodError → 400
      → Prisma errors → 404 / 409
      → Unknown → 500

Database schema

User ──< ApiKey
User ──< TeamMember >── Team
User ──< Task (as creator)
User ──< Task (as assignee)
Team ──< Task
Task ──< Task  (self-relation: parent/children)

All main entities support soft delete via a deletedAt timestamp. Deleting a Task cascades to all descendants.

Module boundaries

packages/web/ — Standalone frontend source code for browser flows and the future task UI. In local development it runs with the Vite dev server; in production its built assets are served by the Hono server so the app ships as one service.

src/auth/ — Key generation (crypto), hashing, and the Hono middleware. Nothing else imports from here except routes.

src/tasks/status-machine.ts — Pure functions canTransition and validateTransition. No database access.

src/ai/ — Provider interface, AI SDK adapter, factory, and classifier. All errors are caught internally; callers always receive null on failure.

src/lib/ — Stateless utilities. prisma.ts exports the singleton client. pagination.ts is pure. errors.ts defines the error hierarchy. response.ts wraps data in the envelope.

Released under the MIT License.