Skip to main content

Overview

The packages/ directory contains shared libraries used across all apps. This enables code reuse, consistent patterns, and a single source of truth.
Monorepo Rule: Business logic lives in packages/. Apps contain only thin wrappers.

Package Registry

PackageNamePurpose
db@trendingsociety/dbSupabase client, types, query helpers
api@trendingsociety/apiResponse utilities, errors, logger
ui@trendingsociety/ui42 shadcn/ui components
auth@trendingsociety/authSupabase Auth utilities
integrations@trendingsociety/integrationsLinear, Shopify, Slack, Tavily clients
jarvis@trendingsociety/jarvisAI assistant (voice, chat, contexts)
orchestration@trendingsociety/orchestrationAgent routing, delegation
usage@trendingsociety/usageAI cost metering
content-engine@trendingsociety/content-enginePublishing pipeline
config@trendingsociety/configEnv variables, feature flags
validation@trendingsociety/validationSchema validation
error-boundary@trendingsociety/error-boundaryError handling

Architecture

packages/
├── api/                 # Shared API utilities
│   └── src/
│       ├── responses.ts # successResponse, errorResponse
│       ├── errors.ts    # ValidationError, NotFoundError
│       ├── logger.ts    # Structured logging
│       └── shopify/     # Shopify handler factories
├── db/                  # Database layer
│   └── src/
│       ├── client.ts    # createClient, getTenantClient
│       ├── types.ts     # Auto-generated from schema
│       └── queries/     # Shared query helpers
├── ui/                  # UI components
│   └── src/
│       └── components/  # 42 shadcn components
└── integrations/        # External service clients
    └── src/
        ├── linear.ts
        ├── shopify.ts
        ├── slack.ts
        └── tavily.ts

Using Packages

Installation

Packages are automatically linked in the monorepo. Just add to package.json:
{
  "dependencies": {
    "@trendingsociety/db": "workspace:*",
    "@trendingsociety/api": "workspace:*",
    "@trendingsociety/ui": "workspace:*"
  }
}
Then import:
import { createClient } from '@trendingsociety/db';
import { successResponse, errorResponse } from '@trendingsociety/api';
import { Button, Card, Dialog } from '@trendingsociety/ui';

Building

Packages are built before apps via Turborepo:
# Build all packages
pnpm build --filter="./packages/*"

# Build specific package
pnpm build --filter=@trendingsociety/db

Type Generation

For @trendingsociety/db, regenerate types after schema changes:
pnpm db:generate-types

Package Location Rules

These rules are enforced. Violations will be flagged in code review.
Code TypeMUST Go InNever In
Business logic (API calls)packages/integrations/apps/*/src/app/api/
Route handler factoriespackages/api/src/{feature}/apps/*/src/app/api/
Database queriespackages/db/src/queries/apps/*/lib/
Shared UI componentspackages/ui/apps/* (duplicated)
Thin API wrappers (10-15 lines)apps/{app}/src/app/api/N/A (correct location)

The 10-15 Line Rule

App-layer API routes should be thin wrappers that:
  1. Extract tenant context (from auth/headers)
  2. Call shared handler from packages/api/
  3. Return response
// apps/dashboard/src/app/api/shopify/kpis/route.ts
// ✅ GOOD: 10 lines, thin wrapper
import { createKPIsHandler } from '@trendingsociety/api/shopify';
import { getTenantId } from '@/lib/tenant/server';

export const GET = createKPIsHandler(getTenantId);
// ❌ BAD: 50+ lines of business logic in app
export async function GET() {
  const tenantId = await getTenantId();
  const credentials = await getShopifyCredentials(tenantId);
  const products = await fetch(`https://${credentials.domain}/admin/api/...`);
  // ... more logic ...
}

Creating New Packages

1

Create Directory

mkdir -p packages/my-package/src
2

Initialize package.json

{
  "name": "@trendingsociety/my-package",
  "version": "0.0.0",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts",
    "dev": "tsup src/index.ts --watch"
  }
}
3

Add to Root

The package is auto-discovered by pnpm workspaces.
4

Use in Apps

{
  "dependencies": {
    "@trendingsociety/my-package": "workspace:*"
  }
}