For AI Developers: This document is the core reference for the Funish Vertex project. Please read it thoroughly before starting development.
Funish Vertex is an enterprise-grade, multi-organization developer platform built on Better Auth. It leverages a plugin-based architecture to provide a complete infrastructure solution for modern applications. The platform features a dual-layer authentication architecture: a platform layer manages organizations and users, while each organization is provided with its own independent, configurable Better Auth instance and plugin ecosystem.
- Dual-Layer Authentication: Platform management + isolated Better Auth instances for each organization.
- Plugin-Powered Ecosystem: Functional extensions based on the Better Auth plugin system.
- Multi-Organization Isolation: Complete isolation of data, storage, and configuration between organizations.
- Flexible Configuration: Organizations can freely enable, disable, and configure the plugins they need.
- Unified API: Standardized RESTful API design.
- Authentication Framework: Better Auth (Core) + Custom Plugin Ecosystem
- Frontend: Nuxt 4 + Vue 3 + UnoCSS + PrimeVue
- Backend: Nitro (API Gateway) + Better Auth (Authentication)
- Database: Kysely (ORM) + PostgreSQL + Dynamic Schema Management
- Storage: Unstorage (Multi-Driver Abstraction) + Storage Server
- AI Integration: Vercel AI SDK + Provider Registry
┌──────────────────────────────────────────────────────────────┐
│ Platform Layer │
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
│ │ Platform │ │ Universal Plugin Registry │ │
│ │ Configuration │ │ ✓ Storage Plugin │ │
│ │ - Base Plugins │ │ ✓ Database Plugin │ │
│ │ - Global Rules │ │ ✓ AI Router Plugin │ │
│ │ - Rate Limits │ │ ✓ ...and other official plugins │ │
│ └─────────────────┘ └─────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
│ (Provides)
▼
┌──────────────────────────────────────────────────────────────┐
│ Organization Layer │
│ Organization A Organization B Organization C │
│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │
│ │ Org A Config │ │ Org B Config │ │ Org C Config │ │
│ │ ├ + Storage(S3) │ │ ├ + Storage(R2) │ │ ├ + Database │ │
│ │ └ + AI Router │ │ └ + Analytics │ │ └ + AI Router│ │
│ └─────────────────┘ └─────────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────────┘
│ (Configures)
▼
┌──────────────────────────────────────────────────────────────┐
│ Runtime Instances │
│ Better Auth Instance A Better Auth Instance B etc. │
│ (Platform + Org A Config) (Platform + Org B Config) │
└──────────────────────────────────────────────────────────────┘
Our platform is built around a powerful plugin system, managed by our Plugin Registry. This registry allows administrators to discover, enable, and configure plugins for each organization.
- Gateway Plugin: A comprehensive API gateway that provides routing, rate limiting, and API key authentication.
- Storage Plugin: Based on
unstorage
, providing multi-driver support (S3, R2, etc.) and tenant-isolated storage. - Database Plugin: Based on
Kysely
, allowing for dynamic, isolated database schemas per organization. - AI Router Plugin: Based on the
Vercel AI SDK
, enabling routing to multiple AI providers like OpenAI, Anthropic, and Groq. - ...and many more, including official Better Auth plugins for payments, analytics, etc.
- Platform-Level Data: Manages core tables for
user
,session
,organization
, andorganization_plugin_config
. - Organization-Level Data: Each organization gets its own database schema (e.g.,
org_123_schema
), ensuring complete data isolation. Plugin-specific tables are created within this schema when a plugin is enabled.
- Developer Quickstart Guide - Quick start guide for new developers
- Architecture Design - Detailed system architecture
- Plugin Registry Implementation - Plugin system details
- Multi-Tenant Plugin Development - Comprehensive development guidelines
- Better Auth Plugin Structure - Plugin structure guidelines
/api/v1/
├── platform/ # Platform Management API
│ ├── auth/ # Platform-level authentication
│ └── plugins/ # Plugin Registry discovery
└── {orgId}/ # Organization-specific API
├── auth/ # Organization-level authentication
└── ... # Plugin-specific routes (e.g., /storage/*)
- Project initialization and documentation design
- Better Auth platform-level setup
- Plugin Registry architecture design and implementation
- Multi-organization dynamic schema management
- Basic API framework
- Storage Plugin (Unstorage integration)
- Database Plugin (Kysely integration)
- AI Router Plugin (Vercel AI SDK integration)
- Gateway Plugin (Routing, Rate Limiting, API Keys)
- Tenant Plugin (Multi-organization support)
- Permission Plugin (Access control and role management)
- Better Auth Vue client setup
- Basic authentication middleware
- Authentication UI components (Login, Register, etc.)
- Organization management interface
- Plugin marketplace UI
- Dashboard and admin panels
- Align with Better Auth: All plugins must be compatible with the
BetterAuthPlugin
interface. - Type Safety: Use TypeScript strict mode and avoid
any
. - Organization Isolation: Ensure complete data and configuration isolation between organizations.
- API Versioning: Maintain stable and versioned APIs.
// Simplified example from server/utils/auth.ts
import { betterAuth } from "better-auth";
import { getEnabledPlugins } from "@funish/vertex/plugins/registry";
// Factory function to create a Better Auth instance for a specific organization
export const createAuthForOrganization = async (orgId: string) => {
const allPluginConfigs = await loadAllOrgPluginConfigsFromDB();
const { server: serverPlugins } = getEnabledPlugins(orgId, allPluginConfigs);
return betterAuth({
// ... base config
plugins: serverPlugins, // Pass the dynamically instantiated plugins
});
};
// Simplified example from packages/vertex/src/plugins/registry/register.ts
import { globalPluginRegistry } from "./registry";
import { storagePluginDefinition } from "../storage";
// Register all built-in plugins on startup
export function registerBuiltinPlugins() {
globalPluginRegistry.register(storagePluginDefinition);
// ... register other plugins
}