Skip to content

Step 1: Project Setup

Step Outcome

After this step, you will have:

  • a running Minima.js app on port 6464
  • a generated Prisma client
  • the full initial database schema migrated to SQLite

Scaffold the project

bash
npx @minimajs/cli new task-board
cd task-board

This creates a fully configured project with TypeScript, minimajs.config.js, an ./app runner, and a starter module structure. Node.js version is pinned via .node-version and picked up automatically if you have fnm installed.

Install Prisma and additional dependencies

bash
./app i prisma @prisma/client zod jsonwebtoken bcryptjs @minimajs/auth @minimajs/cookie @minimajs/schema @minimajs/multipart @minimajs/openapi
./app i -D @types/jsonwebtoken @types/bcryptjs
npx prisma init --datasource-provider sqlite

Prisma Schema

Replace prisma/schema.prisma with:

prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

model User {
  id           Int         @id @default(autoincrement())
  email        String      @unique
  name         String
  passwordHash String
  createdAt    DateTime    @default(now())

  memberships  Member[]
  tasks        Task[]      @relation("AssignedTasks")
}

model Workspace {
  id        Int      @id @default(autoincrement())
  name      String
  createdAt DateTime @default(now())

  members   Member[]
  boards    Board[]
}

model Member {
  id          Int       @id @default(autoincrement())
  role        String    @default("member") // "owner" | "admin" | "member"
  userId      Int
  workspaceId Int

  user        User      @relation(fields: [userId], references: [id])
  workspace   Workspace @relation(fields: [workspaceId], references: [id])

  @@unique([userId, workspaceId])
}

model Board {
  id          Int       @id @default(autoincrement())
  name        String
  workspaceId Int
  createdAt   DateTime  @default(now())

  workspace   Workspace @relation(fields: [workspaceId], references: [id])
  tasks       Task[]
}

model Task {
  id          Int          @id @default(autoincrement())
  title       String
  description String?
  status      String       @default("todo") // "todo" | "in_progress" | "done"
  assigneeId  Int?
  boardId     Int
  createdAt   DateTime     @default(now())
  updatedAt   DateTime     @updatedAt

  board       Board        @relation(fields: [boardId], references: [id])
  assignee    User?        @relation("AssignedTasks", fields: [assigneeId], references: [id])
  attachments Attachment[]
}

model Attachment {
  id        Int      @id @default(autoincrement())
  filename  String
  savedAs   String
  size      Int
  mimeType  String
  taskId    Int
  createdAt DateTime @default(now())

  task      Task     @relation(fields: [taskId], references: [id])
}

Run the migration:

bash
npx prisma migrate dev --name init

Optional: open Prisma Studio to inspect your tables:

bash
npx prisma studio

Entry Point

The scaffold already created src/index.ts for you.

The createApp() call auto-discovers all module.ts files under src/ — we'll add those next.

Smoke Check

Run:

bash
./app dev

Expected output:

text
Task Board API running at http://localhost:6464

And in a second terminal:

bash
curl -i http://localhost:6464/

Any HTTP response here is fine for now. The important part is that the process boots cleanly.


Next: Database & Root Module