feat: add typescript monorepo with pnpm workspaces and prisma database package

- root package.json + pnpm-workspace.yaml + tsconfig.base.json
- packages/types: canonical enums (TenantStatus, AgentState)
- packages/shared: re-exports types, base for future utilities
- packages/database: Prisma 7 schema with driver adapter (pg), initial
  tenants table matching agente.md section 29, first migration applied
This commit is contained in:
2026-08-27 23:22:38 -03:00
parent 2f130622d1
commit d1addb0a31
19 changed files with 1615 additions and 0 deletions

View File

@@ -1 +1,2 @@
FREESWITCH_PAT= FREESWITCH_PAT=
DATABASE_URL=postgresql://user:password@localhost:5432/b2bcall?schema=public

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
22

19
package.json Normal file
View File

@@ -0,0 +1,19 @@
{
"name": "b2bcall",
"private": true,
"version": "0.0.1",
"packageManager": "pnpm@11.24.0",
"engines": {
"node": ">=22"
},
"scripts": {
"build": "pnpm -r --if-present run build",
"dev": "pnpm -r --if-present --parallel run dev",
"lint": "pnpm -r --if-present run lint",
"typecheck": "pnpm -r --if-present run typecheck",
"test": "pnpm -r --if-present run test"
},
"devDependencies": {
"typescript": "^5.9.3"
}
}

View File

@@ -0,0 +1,22 @@
{
"name": "@b2bcall/database",
"version": "0.0.1",
"private": true,
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev",
"prisma:deploy": "prisma migrate deploy",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@prisma/adapter-pg": "^7.10.0",
"@prisma/client": "^7.10.0",
"pg": "^8.23.0"
},
"devDependencies": {
"@types/pg": "^8.23.1",
"prisma": "7.10.0"
}
}

View File

@@ -0,0 +1,8 @@
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
},
});

View File

@@ -0,0 +1,28 @@
-- CreateEnum
CREATE TYPE "tenant_status" AS ENUM ('TRIAL', 'ACTIVE', 'SUSPENDED', 'PAST_DUE', 'CANCELLED');
-- CreateTable
CREATE TABLE "tenants" (
"id" UUID NOT NULL,
"code" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"legal_name" TEXT NOT NULL,
"trade_name" TEXT,
"tax_id" TEXT,
"status" "tenant_status" NOT NULL DEFAULT 'TRIAL',
"timezone" TEXT NOT NULL DEFAULT 'America/Sao_Paulo',
"locale" TEXT NOT NULL DEFAULT 'pt-BR',
"billing_currency" TEXT NOT NULL DEFAULT 'BRL',
"telephony_domain" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"deleted_at" TIMESTAMP(3),
CONSTRAINT "tenants_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "tenants_code_key" ON "tenants"("code");
-- CreateIndex
CREATE UNIQUE INDEX "tenants_slug_key" ON "tenants"("slug");

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"

View File

@@ -0,0 +1,36 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
}
enum TenantStatus {
TRIAL
ACTIVE
SUSPENDED
PAST_DUE
CANCELLED
@@map("tenant_status")
}
model Tenant {
id String @id @default(uuid()) @db.Uuid
code String @unique
slug String @unique
legalName String @map("legal_name")
tradeName String? @map("trade_name")
taxId String? @map("tax_id")
status TenantStatus @default(TRIAL)
timezone String @default("America/Sao_Paulo")
locale String @default("pt-BR")
billingCurrency String @map("billing_currency") @default("BRL")
telephonyDomain String? @map("telephony_domain")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@map("tenants")
}

View File

@@ -0,0 +1,14 @@
import { PrismaClient } from "@prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
export * from "@prisma/client";
let prisma: PrismaClient | undefined;
export function getPrismaClient(): PrismaClient {
if (!prisma) {
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
prisma = new PrismaClient({ adapter });
}
return prisma;
}

View File

@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}

View File

@@ -0,0 +1,16 @@
{
"name": "@b2bcall/shared",
"version": "0.0.1",
"private": true,
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@b2bcall/types": "workspace:*"
},
"devDependencies": {
"typescript": "^5.7.0"
}
}

View File

@@ -0,0 +1 @@
export * from "@b2bcall/types";

View File

@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}

View File

@@ -0,0 +1,13 @@
{
"name": "@b2bcall/types",
"version": "0.0.1",
"private": true,
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"typescript": "^5.7.0"
}
}

View File

@@ -0,0 +1,18 @@
export enum TenantStatus {
TRIAL = "TRIAL",
ACTIVE = "ACTIVE",
SUSPENDED = "SUSPENDED",
PAST_DUE = "PAST_DUE",
CANCELLED = "CANCELLED",
}
export enum AgentState {
OFFLINE = "OFFLINE",
LOGGED_IN = "LOGGED_IN",
AVAILABLE = "AVAILABLE",
RESERVED = "RESERVED",
RINGING = "RINGING",
IN_CALL = "IN_CALL",
WRAP_UP = "WRAP_UP",
PAUSED = "PAUSED",
}

View File

@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}

1383
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

9
pnpm-workspace.yaml Normal file
View File

@@ -0,0 +1,9 @@
packages:
- "apps/*"
- "packages/*"
allowBuilds:
'@prisma/engines': true
esbuild: false
msgpackr-extract: false
prisma: true
workerd: false

19
tsconfig.base.json Normal file
View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"moduleResolution": "node",
"lib": ["ES2022"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"sourceMap": true,
"resolveJsonModule": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}