4.7 KiB
4.7 KiB
Developer Guide
Backend Architecture
The backend is built with:
- Runtime: Bun
- Framework: Hono
- ORM: Prisma (with SQLite)
- Database: SQLite (local file)
- AI: Google Generative AI (Gemini)
Layered Architecture
We follow a strict layered architecture:
- API Layer (
src/api): Handles HTTP requests, validation, and calls Service layer. Do not access DB directly. - Service Layer (
src/service): Contains business logic and interacts with the Database via Prisma. - Data Layer (
src/db.ts): Exports the Prisma Client instance.
Service Layer Patterns
- Instance Methods: Define service logic as instance methods on a class, not static methods.
- Singleton Export: Export a singleton instance of the service class.
export class MyService { async doSomething() { ... } } export const myService = new MyService() - Usage: Import and use the exported instance.
import { myService } from '../service/myService' await myService.doSomething()
Hono API Definitions
- Route Chaining: Always define API routes using method chaining on a Hono instance. This ensures that the type definitions for inputs and outputs are correctly inferred and preserved in the exported type.
- Export Pattern: Export the chained route instance as the default export.
const app = new Hono() const route = app .get('/', ...) .post('/', ...) export default route - Type Safety: Use
zValidatorfor request validation (query, json, form) to ensure full end-to-end type safety with the Hono RPC client.
Frontend Architecture
The frontend is built with:
- Runtime: Bun (Bundler & Runner)
- Framework: React
- Styling: Tailwind CSS + Shadcn UI (Components)
- State: React Hooks (useState, useEffect)
Project Structure
ui/: Root of the frontend project.ui/index.html: Entry point for the frontend.ui/App.tsx: Main application component.ui/components/: Reusable UI components.ui/index.css: Global styles (Tailwind imports).
Development
- Run Dev:
bun --hot src/index.ts(Runs on port 3000)
Testing
We use bun:test for testing.
Service Tests
- Located in
src/service/*.test.ts. - Mock
prismaclient usingmock.module('../db', ...). - Important: Due to
bun testmodule caching in parallel execution, service tests must import the service under test dynamically with a cache-busting query parameter to ensure a fresh module instance (and thus fresh mocks).// @ts-ignore const { MyService } = await import(`./myService?v=${Date.now()}`)
API Tests
- Located in
src/api/*.test.ts. - Mock the Service layer using
mock.module('../service/myService', ...). - Verify that the API calls the Service methods correctly.
Submission Rules
-
Strict Requirement: A submission is considered complete only when there is a single final code state in which all of the following pass simultaneously:
lintformattypechecktest
-
Fixes must be iterated until no check causes any other check to fail.
-
Do not submit intermediate states where some checks pass and others fail, even temporarily.
-
Cleanup Requirement: Remove all verification related files (scripts, screenshots,
verification/folder) before submit.
Prisma Configuration & Migrations
- Schema:
prisma/schema.prisma - Generated Client:
src/generated/prisma - Config:
prisma.config.ts(Required for Prisma 7+) - Adapter: We use
@prisma/adapter-libsqlfor SQLite compatibility with Bun.
Migration Workflow
Whenever you modify the prisma/schema.prisma file, you must generate a corresponding migration file.
Do not create migration SQL files manually.
Instead, follow this workflow:
- Ensure you have a local SQLite database configured (e.g., via
.envsettingDATABASE_URL="file:./dev.db"). - Run the migration command:
This command will automatically:
bun x prisma migrate dev --name <migration_name>- Detect changes in
schema.prisma. - Generate the SQL migration file in
prisma/migrations/. - Apply the changes to your local development database.
- Regenerate the Prisma Client.
- Detect changes in
Commands
- Generate Client:
bun --bun run prisma generate - Push Schema to DB (Prototyping only):
bun --bun run prisma db push
Environment Variables
.env: Development environment variables (DATABASE_URL="file:./dev.db",API_KEY="...")..env.test: Test environment variables (DATABASE_URL="file:./test.db").
Known Issues
bun testmodule mocking can be sticky across test files running in the same process/worker. Use the dynamic import workaround in Service tests.