OneApp Docs
PackagesCore

@repo/oneapp-shared

Shared code, types, and utilities specific to OneApp applications. Prisma schema, ORM functions, database utilities. Type-safe database operations with auto-completion. For OneApp apps only.

Quick Start

Add OneApp utilities in 5 minutes:

pnpm add @repo/oneapp-shared

Prisma schema, type-safe ORM, environment config included. Skip to Quick Start →

Why @repo/oneapp-shared?

OneApp applications duplicate database code. Prisma schemas scattered across apps. ORM functions written multiple times. Database types not shared. Environment validation inconsistent. Migration scripts duplicated.

@repo/oneapp-shared solves this with centralized Prisma schema, type-safe ORM functions, and shared utilities for all OneApp applications.

Production-ready with Prisma ORM, type-safe operations, soft delete support, pagination utilities, and environment validation.

Use cases

  • Database schema — Single Prisma schema for all OneApp models
  • Type-safe ORM — Auto-generated database operations with TypeScript
  • Environment config — Validated environment variables with t3-env
  • Shared types — User, Chat, Message, Document types
  • Utilities — Pagination, soft delete, common patterns

How it works

@repo/oneapp-shared provides Prisma schema and ORM functions:

import { orm } from "@repo/oneapp-shared/db";
import type { User, ChatWithMessages } from "@repo/oneapp-shared/types";

// Type-safe database operations
const user = await orm.user.findByEmail("user@example.com");

const chat = await orm.chat.create({
  userId: user.id,
  title: "New Chat"
});

await orm.chat.addMessage(chat.id, {
  role: "user",
  content: "Hello!"
});

const messages = await orm.chat.getMessages(chat.id);

Uses Prisma for type-safe database access, ORM functions for common operations, and t3-env for environment validation.

Key features

Prisma schema — Centralized database schema for OneApp models

Type-safe ORM — Auto-completion and type checking for all operations

Environment config — Validated DATABASE_URL with t3-env

Shared types — User, Chat, Message, Document, Session types

Utilities — Pagination, soft delete helpers

Migrations — Centralized database migration management

Quick Start

1. Install the package

pnpm add @repo/oneapp-shared

2. Use ORM functions for database access

app/api/users/route.ts
import { orm } from "@repo/oneapp-shared/db";

export async function GET() {
  const users = await orm.user.findMany();
  return Response.json(users);
}

export async function POST(request: Request) {
  const data = await request.json();

  const user = await orm.user.create({
    email: data.email,
    name: data.name
  });

  return Response.json(user, { status: 201 });
}

3. Use types for type safety

lib/chat.ts
import type { Chat, ChatWithMessages, Message } from "@repo/oneapp-shared/types";

export function formatChat(chat: ChatWithMessages): string {
  return `${chat.title} (${chat.messages.length} messages)`;
}

export function getLastMessage(chat: ChatWithMessages): Message | null {
  return chat.messages[chat.messages.length - 1] ?? null;
}

4. Run migrations

# Development
pnpm --filter @repo/oneapp-shared prisma:migrate:dev

# Production
pnpm --filter @repo/oneapp-shared prisma:migrate:deploy

# Generate Prisma client
pnpm --filter @repo/oneapp-shared prisma:generate

That's it! You now have type-safe database access and shared OneApp types across your app.

Use pagination utility

Paginate database queries easily:

import { paginate } from "@repo/oneapp-shared";

const { data, pagination } = await paginate(orm.chat.findByUserId, { userId: "user_123" }, { page: 1, pageSize: 10 });

Technical Details

For Developers: Technical implementation details

Overview

PropertyValue
Locationpackages/oneapp-shared
PurposeOneApp-specific shared code
DatabasePrisma schema and ORM functions

Export Paths

PathDescription
@repo/oneapp-sharedMain exports
@repo/oneapp-shared/dbDatabase utilities
@repo/oneapp-shared/typesOneApp types
@repo/oneapp-shared/envEnvironment config

Database Schema

Type-Safe ORM

All database operations are fully typed. The ORM functions provide auto-completion and type checking.

The package contains the Prisma schema for OneApp:

// Key models
// highlight-start
model User {
  id            String    @id @default(cuid())
  email         String    @unique
  name          String?
  image         String?
  sessions      Session[]
  chats         Chat[]
  documents     Document[]
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
}
// highlight-end

model Chat {
  id        String    @id @default(cuid())
  title     String?
  userId    String
  user      User      @relation(fields: [userId], references: [id])
  messages  Message[]
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
}

model Message {
  id        String   @id @default(cuid())
  role      String   // "user" | "assistant" | "system"
  content   String
  chatId    String
  chat      Chat     @relation(fields: [chatId], references: [id])
  createdAt DateTime @default(now())
}

model Document {
  id        String   @id @default(cuid())
  title     String
  content   String?
  userId    String
  user      User     @relation(fields: [userId], references: [id])
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

ORM Functions

User Operations

import { orm } from "@repo/oneapp-shared/db";

// Get user
const user = await orm.user.findById(userId);
const user = await orm.user.findByEmail(email);

// Create user
const newUser = await orm.user.create({
  email: "user@example.com",
  name: "John Doe"
});

// Update user
const updated = await orm.user.update(userId, {
  name: "Jane Doe"
});

Chat Operations

import { orm } from "@repo/oneapp-shared/db";

// Get chats
const chats = await orm.chat.findByUserId(userId);
const chat = await orm.chat.findById(chatId);

// Create chat
const newChat = await orm.chat.create({
  userId,
  title: "New Chat"
});

// Add message
await orm.chat.addMessage(chatId, {
  role: "user",
  content: "Hello!"
});

// Get messages
const messages = await orm.chat.getMessages(chatId);

Document Operations

import { orm } from "@repo/oneapp-shared/db";

// CRUD operations
const docs = await orm.document.findByUserId(userId);
const doc = await orm.document.findById(docId);

const newDoc = await orm.document.create({
  userId,
  title: "My Document",
  content: "..."
});

await orm.document.update(docId, {
  content: "Updated content"
});

await orm.document.delete(docId);

Types

import type {
  User,
  Chat,
  Message,
  Document,
  Session,
  ChatWithMessages,
  UserWithChats
} from "@repo/oneapp-shared/types";

// Use in your code
function processChat(chat: ChatWithMessages) {
  chat.messages.forEach((msg) => {
    console.log(msg.content);
  });
}

Environment

import { env } from "@repo/oneapp-shared/env";

// Type-safe environment access
env.DATABASE_URL;
env.DATABASE_URL_UNPOOLED;

Environment Schema

import { createEnv } from "@t3-oss/env-core";
import { z } from "zod";

export const env = createEnv({
  server: {
    DATABASE_URL: z.string().url(),
    DATABASE_URL_UNPOOLED: z.string().url().optional()
  },
  runtimeEnv: process.env
});

Utilities

Pagination

import { paginate } from "@repo/oneapp-shared";

const { data, pagination } = await paginate(orm.chat.findByUserId, { userId }, { page: 1, pageSize: 10 });

Soft Delete

import { softDelete } from "@repo/oneapp-shared";

// Marks as deleted without removing
await softDelete(orm.document, docId);

// Query excludes soft-deleted
const docs = await orm.document.findByUserId(userId); // Excludes deleted

Migrations

Production Migrations

Always test migrations locally before running on production. Use prisma:migrate:deploy for production.

# Generate migration
# highlight-next-line
pnpm --filter @repo/oneapp-shared prisma:migrate:dev

# Deploy migrations
pnpm --filter @repo/oneapp-shared prisma:migrate:deploy

# Generate client
pnpm --filter @repo/oneapp-shared prisma:generate

On this page