npm package: @otherdev-software/canvas
Description: OtherDev Canvas - A powerful multi-tenant headless CMS with role-based access control, custom branding, and subdomain routing for agencies and SaaS platforms
Author: OtherDev
Latest version: 1.0.0

# OtherDev Canvas

A powerful **multi-tenant headless CMS** with enterprise-grade features for agencies and SaaS platforms.

## Features

- **Multi-Tenancy** - Built-in tenant isolation with subdomain routing
- **Role-Based Access Control** - Super-admin, Tenant-admin, and User roles
- **Whitelabel Ready** - Custom branding, logos, and admin panel customization
- **Rich Content Management** - Blog posts, categories, media library with folders
- **PostgreSQL by Default** - Production-ready database adapter
- **Next.js 15 App Router** - Modern React 19 with server components
- **Lexical Rich Text Editor** - Advanced content editing with custom features
- **Type-Safe** - Full TypeScript support with auto-generated types
- **Shadcn/UI Components** - Beautiful, accessible UI components
- **Multi-Database Support** - PostgreSQL and MongoDB adapters included

## Installation

### Quick Start

```bash
# Install the package
npm install @otherdev/canvas

# Or download and extract
npx degit otherdev/canvas my-project
cd my-project
```

### Manual Installation

```bash
# Clone or install
pnpm add @otherdev/canvas

# Setup environment
cp .env.example .env

# Install dependencies
pnpm install

# Generate TypeScript types
pnpm generate:types

# Start development server
pnpm dev
```

Visit `http://localhost:3000/admin` to access the admin panel.

## Environment Variables

Create a `.env` file in your project root:

```env
# Database - PostgreSQL (recommended)
DATABASE_URI=postgresql://user:password@localhost:5432/canvas_db

# Application Secret (min 32 characters)
PAYLOAD_SECRET=your-super-secret-32-char-minimum-key-here

# App Configuration
NEXT_PUBLIC_APP_URL=http://localhost:3000
MASTER_DOMAIN=localhost:3000
```

### Database Setup

**PostgreSQL (Recommended):**
```bash
# Create database
createdb canvas_db

# Or use a managed service (Supabase, Neon, Railway)
DATABASE_URI=postgresql://user:pass@host:5432/db
```

**MongoDB (Alternative):**
```bash
# Update payload.config.ts to use mongodbAdapter
DATABASE_URI=mongodb://127.0.0.1:27017/canvas_db
```

## Multi-Tenant Architecture

### How It Works

OtherDev Canvas provides complete tenant isolation:

1. **Tenants Collection** - Each customer/organization is a tenant
2. **Subdomain Routing** - `tenant-name.yoursite.com` automatically routes to tenant
3. **Scoped Content** - Blog posts, media, and categories are tenant-specific
4. **User Assignments** - Users can belong to multiple tenants with different roles

### Subdomain Setup (Development)

For local development with subdomains, add to your `/etc/hosts` (Mac/Linux) or `C:\Windows\System32\drivers\etc\hosts` (Windows):

```
127.0.0.1 tenant-a.localhost
127.0.0.1 tenant-b.localhost
127.0.0.1 client1.localhost
```

Access admin panel at: `http://localhost:3000/admin`
Access tenant frontend: `http://tenant-a.localhost:3000`

### Production Subdomain Setup

Update `next.config.mjs`:

```javascript
has: [{
  type: 'host',
  value: '(?<tenant>[^.]+)\\.yourdomain\\.com'
}]
```

## User Roles

### Super Admin
- Full access to all tenants and settings
- Can create/edit/delete any content
- Manage all users and tenants

### Tenant Admin
- Access only to assigned tenant(s)
- Manage content within their tenant
- Can manage users within their tenant

### User
- Basic read/write access within assigned tenant
- Limited administrative capabilities

## Collections

### Tenants (`tenants`)
Manage customer organizations with custom settings.

### Users (`users`)
Authentication-enabled with role-based permissions.

### Blog Posts (`blog-posts`)
Rich content with Lexical editor, tenant-scoped.

### Categories (`categories`)
Organize content, tenant-scoped.

### Media (`media`)
File uploads with image resizing, folders enabled, tenant-scoped.

## Customization

### Branding

Update `src/graphics/` with your logo:
- `Logo/logo.svg` - Login page logo
- `Icon/icon.svg` - Admin panel icon

Update `src/payload.config.ts`:

```typescript
admin: {
  meta: {
    titleSuffix: ' - Your Company Name',
    description: 'Your custom description',
  }
}
```

### Custom Collections

Add new collections in `src/collections/`:

```typescript
// src/collections/Products.ts
import { CollectionConfig } from 'payload'

export const Products: CollectionConfig = {
  slug: 'products',
  fields: [
    { name: 'name', type: 'text', required: true },
    { name: 'price', type: 'number', required: true },
  ],
}
```

Register in `src/payload.config.ts`:

```typescript
import { Products } from './collections/Products'

export default buildConfig({
  collections: [Users, Tenants, BlogPosts, Categories, Media, Products],
})
```

## Development

```bash
# Start dev server
pnpm dev

# Generate TypeScript types
pnpm generate:types

# Generate import map (after adding admin components)
pnpm generate:importmap

# Run linter
pnpm lint

# Format code
pnpm format

# Run tests
pnpm test
```

## Production

### Build

```bash
pnpm build
```

### Start

```bash
pnpm start
```

### Deployment

**Vercel (Recommended):**
1. Connect your GitHub repo
2. Add environment variables
3. Deploy

**Self-Hosted:**
- Ensure PostgreSQL is accessible
- Set `DATABASE_URI` and `PAYLOAD_SECRET`
- Run `pnpm build && pnpm start`

**Docker:**
```bash
docker-compose up -d
```

## API Access

### REST API

```bash
# Get all blog posts for a tenant
GET /api/blog-posts?where[tenant][equals]=<tenant-id>

# Create a blog post
POST /api/blog-posts
```

### GraphQL

```bash
# GraphQL Playground
http://localhost:3000/api/graphql-playground

# GraphQL Endpoint
http://localhost:3000/api/graphql
```

## Project Structure

```
otherdev-canvas/
├── src/
│   ├── app/                    # Next.js App Router
│   │   ├── (payload)/         # Payload admin & API routes
│   │   └── (frontend)/        # Your frontend routes
│   ├── collections/           # Payload collections
│   ├── components/            # React components
│   │   ├── ui/               # Shadcn components
│   │   └── admin/            # Admin customizations
│   ├── graphics/             # Logos and branding
│   └── payload.config.ts     # Payload configuration
├── public/                    # Static assets
└── package.json
```

## Troubleshooting

### Database Connection Issues

```bash
# Test PostgreSQL connection
psql $DATABASE_URI

# Check if database exists
psql -l
```

### Admin Panel Not Loading

```bash
# Regenerate import map
pnpm generate:importmap

# Clear Next.js cache
rm -rf .next
pnpm dev
```

### Type Errors

```bash
# Regenerate types
pnpm generate:types
```

## Documentation

- [Next.js 15 Docs](https://nextjs.org/docs)
- [PostgreSQL Docs](https://www.postgresql.org/docs/)
- [TypeScript Docs](https://www.typescriptlang.org/docs/)

## Support

- GitHub Issues: https://github.com/otherdev/canvas/issues
- Documentation: https://github.com/otherdev/canvas/wiki

## License

MIT License - see [LICENSE](LICENSE) file for details.