oneie
Version:
Build apps, websites, and AI agents in English. Zero-interaction setup for AI agents (Claude Code, Cursor, Windsurf). Download to your computer, run in the cloud, deploy to the edge. Open source and free forever.
1,594 lines (1,375 loc) • 79 kB
Markdown
---
title: Implementation Examples
dimension: knowledge
category: implementation-examples.md
tags: agent, ai, architecture, auth, backend, connections, events, frontend, knowledge, ontology
related_dimensions: connections, events, people, things
scope: global
created: 2025-11-03
updated: 2025-11-03
version: 1.0.0
ai_context: |
This document is part of the knowledge dimension in the implementation-examples.md category.
Location: one/knowledge/implementation-examples.md
Purpose: Documents one platform - implementation examples
Related dimensions: connections, events, people, things
For AI agents: Read this to understand implementation examples.
---
# ONE Platform - Implementation Examples
**Complete Reference**: Ontology, DSL, Schema, and Implementation Patterns
---
## Overview
The 6-dimension ontology architecture (things, connections, events, knowledge, people, protocols) provides unprecedented flexibility, while Convex + Effect.ts delivers production-grade reliability.
**Tech Stack**: Astro + React + shadcn/ui frontend, Convex backend with comprehensive components (@convex-dev/agent, workflow, rag, rate-limiter), Effect.ts service layer, Stripe Connect for payments.
### Foundation Documents
This document integrates information from:
1. **Ontology** (`Ontology.md`) - The 6-dimension data model that defines ALL things, connections, events, knowledge, people, and protocols
2. **DSL** (`DSL.md`, `ONE DSL.md`, `ONE DSL English.md`) - Domain-specific language for feature definition
3. **Schema** (`convex/schema.ts`) - Current authentication-focused schema and target ontology-based schema
4. **Implementation Examples** - Real-world code patterns and feature implementations
### Complete Architecture Stack
```
┌─────────────────────────────────────────────────────────────┐
│ Plain English DSL (Creator/CEO writes features) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Technical DSL (JSON-like, validates against ontology) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Ontology (6 dimensions: things, connections, events, knowledge, people, protocols) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Schema Definition (Convex with validation) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Generated Types (TypeScript strict mode) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Provider Services (Effect.ts with dependency injection) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Compiled TypeScript (Production code with tests) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Deployed Feature (Live on ONE platform) │
└─────────────────────────────────────────────────────────────┘
```
### Why This Architecture Works
**Ontology-First Design:**
- Every feature maps to 6 dimensions (things, connections, events, knowledge, people, protocols)
- Simple test: "If you can't map it to these 6 dimensions, rethink it"
- AI agents can't generate invalid data models
**DSL Validation:**
- Plain English → Technical DSL → TypeScript
- Validates against ontology before compilation
- Generates type-safe code automatically
- Non-technical users can write features
**Schema Enforcement:**
- Convex schema validates all database operations
- Type-safe queries with full autocompletion
- Indexed for performance (< 100ms queries)
- Vector search for semantic operations
**Effect.ts Service Layer:**
- Typed error channels (no silent failures)
- Automatic dependency injection
- Testable with mocked services
- Composable business logic
---
## Ontology: The 6-Dimension Universe
**Purpose**: Complete data model for AI agents to understand how EVERYTHING in ONE platform is structured.
### Core Concept
Every single thing in ONE platform exists in one of these 6 dimensions:
```
┌──────────────────────────────────────────────────────────────┐
│ ENTITIES TABLE │
│ Every "thing" - users, agents, content, tokens, courses │
└──────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────┐
│ CONNECTIONS TABLE │
│ Every relationship - owns, follows, taught_by, powers │
└──────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────┐
│ EVENTS TABLE │
│ Every action - purchased, created, viewed, completed │
└──────────────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────────────┐
│ TAGS TABLE │
│ Every category - industry:fitness, skill:video, etc. │
└──────────────────────────────────────────────────────────────┘
```
**Golden Rule:** If you can't map your feature to these 6 dimensions, you're thinking about it wrong.
### Entity Types
```typescript
type EntityType =
// CORE
| "creator" // Human creator
| "ai_clone" // Digital twin of creator
| "audience_member" // Fan/user
// BUSINESS AGENTS (10 types)
| "strategy_agent" // Vision, planning, OKRs
| "research_agent" // Market, trends, competitors
| "marketing_agent" // Content strategy, SEO, distribution
| "sales_agent" // Funnels, conversion, follow-up
| "service_agent" // Support, onboarding, success
| "design_agent" // Brand, UI/UX, assets
| "engineering_agent" // Tech, integration, automation
| "finance_agent" // Revenue, costs, forecasting
| "legal_agent" // Compliance, contracts, IP
| "intelligence_agent" // Analytics, insights, predictions
// CONTENT
| "blog_post" // Written content
| "video" // Video content
| "podcast" // Audio content
| "social_post" // Social media post
| "email" // Email content
| "course" // Educational course
| "lesson" // Individual lesson
// PRODUCTS
| "digital_product" // Templates, tools, assets
| "membership" // Tiered membership
| "consultation" // 1-on-1 session
| "nft" // NFT collectible
// COMMUNITY
| "community" // Community space
| "conversation" // Thread/discussion
| "message" // Individual message
// TOKEN
| "token" // Actual token instance
| "token_contract" // Smart contract
// KNOWLEDGE
| "knowledge_item" // Piece of creator knowledge
| "embedding" // Vector embedding
```
### Connection Types (Optimized 24 Types)
**Design Philosophy**: Use metadata fields instead of proliferating connection types.
```typescript
type ConnectionType =
// OWNERSHIP (3 types)
| "owns" // Creator owns token/content (metadata.revenueShare)
| "created_by" // Content created by creator
| "authored" // User authored content (vs. generated_by for AI)
// AI RELATIONSHIPS (3 types)
| "clone_of" // AI is clone of creator
| "trained_on" // Clone trained on content (metadata.trainingDataType)
| "powers" // Agent powers clone/feature (metadata.capability)
// CONTENT RELATIONSHIPS (4 types)
| "published_to" // Content published to platform (metadata.visibility)
| "part_of" // Lesson part of course (metadata.order, metadata.section)
| "references" // Content references entity (metadata.referenceType)
| "derived_from" // Content derived from original (metadata.derivationType)
// COMMUNITY RELATIONSHIPS (3 types)
| "member_of" // User member of community (metadata.role, metadata.joinedAt)
| "following" // User follows creator (metadata.notificationsEnabled)
| "engaged_with" // User engaged with content (metadata.engagementType: "liked", "commented", "shared")
// BUSINESS RELATIONSHIPS (3 types)
| "manages" // Agent manages function (metadata.permissions)
| "collaborates_with" // Entities collaborate (metadata.collaborationType, metadata.revenueShare)
| "assigned_to" // Task assigned to entity (metadata.priority, metadata.deadline)
// TRANSACTIONAL RELATIONSHIPS (4 types - consolidated from 7)
| "transacted" // Generic transaction (metadata.transactionType: "purchase", "subscription", "invoice")
| "holds" // User holds asset (metadata.assetType: "tokens", "nft", "stake", metadata.amount)
| "enrolled_in" // User enrolled in course (metadata.progress, metadata.startedAt)
| "completed" // User completed course/task (metadata.completedAt, metadata.certificateId)
// REFERRAL/GROWTH (2 types)
| "referred_by" // User referred by another (metadata.referralCode, metadata.conversionStatus)
| "converted_from" // User converted from lead (metadata.conversionType, metadata.source)
// MEDIA/ANALYTICS (2 types)
| "featured_in" // Entity featured in content (metadata.startTime, metadata.endTime)
| "analyzed_by" // Entity analyzed by intelligence (metadata.analysisType, metadata.confidence)
```
**Key Improvements**:
- **Before**: 30+ connection types
- **After**: 24 optimized types
- **Strategy**: Use `metadata` for variants (e.g., "transacted" with metadata.transactionType instead of "paid_for", "subscribed_to", "invoiced_to")
- **Benefits**: Simpler schema, more flexible queries, easier to extend
### Event Types (Optimized 38 Types)
**Design Philosophy**: Consolidate status variants into metadata fields.
```typescript
type EventType =
// ENTITY LIFECYCLE (6 types)
| "entity_created" // Any entity created (metadata.entityType)
| "entity_updated" // Any entity updated (metadata.fields)
| "entity_deleted" // Soft delete (metadata.reason)
| "entity_restored" // Undelete (metadata.restoredBy)
| "entity_published" // Draft → Published (metadata.visibility)
| "entity_archived" // Active → Archived (metadata.archiveReason)
// AI/CLONE EVENTS (4 types)
| "clone_interaction" // Chat/interaction with clone (metadata.messageCount, metadata.duration)
| "clone_trained" // Training completed (metadata.dataPoints, metadata.model)
| "ai_generated" // AI generated content (metadata.contentType, metadata.prompt)
| "voice_cloned" // Voice clone created (metadata.provider, metadata.voiceId)
// AGENT EVENTS (3 types - consolidated from 4)
| "agent_executed" // Agent ran (metadata.status: "success", "failed", "partial")
| "workflow_started" // Workflow initiated (metadata.workflowType, metadata.steps)
| "workflow_completed" // Workflow finished (metadata.duration, metadata.status)
// CONTENT EVENTS (5 types)
| "content_viewed" // Content viewed (metadata.duration, metadata.completionRate)
| "content_interacted" // User interacted (metadata.interactionType: "liked", "shared", "commented")
| "content_downloaded" // Content downloaded (metadata.format)
| "content_embedded" // Embedding generated (metadata.model, metadata.dimensions)
| "content_moderated" // Moderation action (metadata.action, metadata.reason)
// LEARNING EVENTS (4 types - consolidated from 5)
| "course_enrolled" // User enrolled in course
| "progress_updated" // Progress on course/lesson (metadata.entityId, metadata.progress)
| "assessment_completed" // Test/quiz finished (metadata.score, metadata.passed)
| "certificate_earned" // Certificate issued (metadata.certificateId, metadata.skills)
// TOKEN/ASSET EVENTS (5 types - consolidated from 7)
| "token_deployed" // Contract deployed (metadata.contractAddress, metadata.chain)
| "token_transacted" // Token transaction (metadata.action: "purchased", "earned", "burned", metadata.amount)
| "token_staked" // Staking action (metadata.action: "staked", "unstaked", metadata.amount, metadata.duration)
| "governance_action" // Governance event (metadata.actionType: "vote", "proposal", "execution")
| "nft_minted" // NFT minted (metadata.tokenId, metadata.metadata)
// PAYMENT EVENTS (3 types - consolidated from 5)
| "payment_processed" // Payment event (metadata.status: "initiated", "completed", "failed", "refunded")
| "subscription_changed" // Subscription event (metadata.action: "started", "renewed", "cancelled", "upgraded")
| "invoice_generated" // Invoice created/sent (metadata.amount, metadata.dueDate, metadata.status)
// GROWTH/ENGAGEMENT (5 types)
| "referral_created" // Referral made (metadata.referralCode, metadata.channel)
| "referral_converted" // Referral converted (metadata.conversionValue)
| "achievement_unlocked" // Achievement earned (metadata.achievementId, metadata.points)
| "level_changed" // User level changed (metadata.oldLevel, metadata.newLevel, metadata.reason)
| "viral_shared" // Viral share occurred (metadata.platform, metadata.reach)
// ANALYTICS/INTELLIGENCE (3 types)
| "metric_calculated" // Metric computed (metadata.metricType, metadata.value)
| "insight_generated" // AI insight created (metadata.insightType, metadata.confidence)
| "report_generated" // Report created (metadata.reportType, metadata.period)
```
**Key Improvements**:
- **Before**: 50+ event types with status variants
- **After**: 38 consolidated types
- **Strategy**: Use `metadata.status` or `metadata.action` for state variants
- **Example**: "payment_initiated", "payment_completed", "payment_failed" → "payment_processed" with metadata.status
- **Benefits**: Easier analytics queries, consistent event structure, simpler event handlers
**For complete ontology details, see:** `Ontology.md`
---
## ONE DSL: Domain-Specific Language
**Purpose**: Declarative language for defining features that compiles to Effect.ts and TypeScript.
### DSL Architecture Stack
```
Plain English (CEO writes)
↓ [Parser]
Technical DSL (validated against ontology)
↓ [Compiler]
TypeScript with Effect.ts (production code)
↓ [Generated automatically]
Tests + Documentation
↓
Deployed Feature
```
### Plain English DSL
**For creators and non-technical users** - Natural language that compiles to working code.
**Example:**
```
FEATURE: Let fans chat with my AI clone
WHEN a fan sends a message
CHECK they own tokens
GET my AI personality
SEND message to AI with my personality
SAVE the conversation
GIVE fan 10 tokens as reward
SHOW AI response to fan
```
**Core Commands:**
- `CHECK` - Validate something
- `CREATE` - Make something new
- `CONNECT` - Link two things
- `RECORD` - Log that something happened
- `CALL` - Use external service
- `GET` - Retrieve something
- `IF/THEN/ELSE` - Conditional logic
- `DO TOGETHER` - Atomic operations
- `WAIT` - Pause execution
- `FOR EACH` - Loop through items
- `GIVE` - Return result
### Technical DSL
**For AI agents and developers** - JSON-like syntax that validates against ontology.
**Example:**
```typescript
const createAICloneDSL = {
feature: "CreateAIClone",
input: {
creatorId: "Id<entities>",
videoUrls: "string[]",
},
output: {
cloneId: "Id<entities>",
voiceId: "string",
},
flow: [
{
validate: {
creatorId: { exists: true, type: "creator" },
videoUrls: { minLength: 3 },
},
onError: { return: { error: "InsufficientContent" } },
},
{
service: {
provider: "elevenlabs",
method: "cloneVoice",
params: { samples: "$audioSamples" },
output: "voiceId",
retry: { times: 3, delay: "5s" },
},
},
{
entity: {
type: "ai_clone",
name: "$creator.name + ' AI Clone'",
properties: {
voiceId: "$voiceId",
systemPrompt: "$personality.systemPrompt",
temperature: 0.7,
},
status: "active",
},
output: "cloneId",
},
{
connect: {
from: "$input.creatorId",
to: "$cloneId",
type: "owns",
},
},
{
event: {
entity: "$cloneId",
type: "clone_created",
actor: "$input.creatorId",
},
},
{
return: {
cloneId: "$cloneId",
voiceId: "$voiceId",
},
},
],
};
```
**DSL Primitives:**
- `entity` - Create entity in ontology
- `connect` - Create relationship between entities
- `event` - Log an event
- `query` - Retrieve entities/connections/events
- `flow` - Multi-step workflow with branching
- `service` - Call external provider (OpenAI, ElevenLabs, Stripe, etc.)
- `validate` - Check conditions
- `atomic` - Group operations with rollback support
### DSL Validation & Compilation
**Validator** - Ensures DSL uses only valid ontology types:
```typescript
class ONEValidator {
validate(dsl: any): { valid: boolean; errors: string[] } {
// Validates all entity types exist in ontology
// Validates all connection types exist in ontology
// Validates all event types exist in ontology
return { valid: true, errors: [] };
}
}
```
**Compiler** - Generates type-safe TypeScript with Effect.ts:
```typescript
class ONECompiler {
compile(dsl: any): string {
// Compiles DSL to TypeScript
// Generates Effect.ts service calls
// Adds proper error handling
// Creates fully typed code
return generatedCode;
}
}
```
**Complete DSL examples and specifications in:** `DSL.md`, `ONE DSL.md`, `ONE DSL English.md`
---
## Schema Implementation
### Current Schema (Authentication Focus)
**File**: `convex/schema.ts` (Current - Authentication focused)
```typescript
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
users: defineTable({
email: v.string(),
passwordHash: v.string(),
name: v.optional(v.string()),
emailVerified: v.optional(v.boolean()),
createdAt: v.number(),
}).index("by_email", ["email"]),
sessions: defineTable({
userId: v.id("users"),
token: v.string(),
expiresAt: v.number(),
createdAt: v.number(),
}).index("by_token", ["token"])
.index("by_userId", ["userId"]),
passwordResets: defineTable({
userId: v.id("users"),
token: v.string(),
expiresAt: v.number(),
createdAt: v.number(),
used: v.boolean(),
}).index("by_token", ["token"])
.index("by_userId", ["userId"]),
emailVerifications: defineTable({
userId: v.id("users"),
email: v.string(),
token: v.string(),
expiresAt: v.number(),
createdAt: v.number(),
verified: v.boolean(),
}).index("by_token", ["token"])
.index("by_userId", ["userId"])
.index("by_email", ["email"]),
magicLinks: defineTable({
email: v.string(),
token: v.string(),
expiresAt: v.number(),
createdAt: v.number(),
used: v.boolean(),
}).index("by_token", ["token"])
.index("by_email", ["email"]),
twoFactorAuth: defineTable({
userId: v.id("users"),
secret: v.string(),
backupCodes: v.array(v.string()),
enabled: v.boolean(),
createdAt: v.number(),
}).index("by_userId", ["userId"]),
});
```
### Target Ontology-Based Schema (Plain Convex)
**Future implementation** - 6-dimension architecture with full ontology support:
```typescript
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
// ENTITIES TABLE - All "things"
entities: defineTable({
type: v.union(
// Core
v.literal("creator"),
v.literal("ai_clone"),
v.literal("audience_member"),
// Business Agents
v.literal("strategy_agent"),
v.literal("research_agent"),
v.literal("marketing_agent"),
v.literal("sales_agent"),
v.literal("service_agent"),
v.literal("design_agent"),
v.literal("engineering_agent"),
v.literal("finance_agent"),
v.literal("legal_agent"),
v.literal("intelligence_agent"),
// Content
v.literal("blog_post"),
v.literal("video"),
v.literal("podcast"),
v.literal("social_post"),
v.literal("email"),
v.literal("course"),
v.literal("lesson"),
// Products
v.literal("digital_product"),
v.literal("membership"),
v.literal("consultation"),
v.literal("nft"),
// Community
v.literal("community"),
v.literal("conversation"),
v.literal("message"),
// Token
v.literal("token"),
v.literal("token_contract"),
// Knowledge
v.literal("knowledge_item"),
v.literal("embedding"),
// Platform
v.literal("website"),
v.literal("landing_page"),
v.literal("template"),
v.literal("livestream"),
v.literal("recording"),
v.literal("media_asset"),
// Business
v.literal("payment"),
v.literal("subscription"),
v.literal("invoice"),
v.literal("metric"),
v.literal("insight"),
v.literal("prediction"),
v.literal("report"),
// Marketing
v.literal("notification"),
v.literal("email_campaign"),
v.literal("announcement"),
v.literal("referral"),
v.literal("campaign"),
v.literal("lead")
),
name: v.string(),
properties: v.any(), // Type-specific properties as JSON
status: v.optional(
v.union(
v.literal("active"),
v.literal("inactive"),
v.literal("draft"),
v.literal("published"),
v.literal("archived")
)
),
createdAt: v.number(),
updatedAt: v.number(),
deletedAt: v.optional(v.number()),
})
.index("by_type", ["type"])
.index("by_status", ["status"])
.index("by_createdAt", ["createdAt"])
.index("by_type_status", ["type", "status"])
.searchIndex("search_entities", {
searchField: "name",
filterFields: ["type", "status"],
}),
// CONNECTIONS TABLE - All relationships
connections: defineTable({
fromEntityId: v.id("entities"),
toEntityId: v.id("entities"),
relationshipType: v.union(
// Ownership (3 types)
v.literal("owns"),
v.literal("created_by"),
v.literal("authored"),
// AI relationships (3 types)
v.literal("clone_of"),
v.literal("trained_on"),
v.literal("powers"),
// Content relationships (4 types)
v.literal("published_to"),
v.literal("part_of"),
v.literal("references"),
v.literal("derived_from"),
// Community relationships (3 types)
v.literal("member_of"),
v.literal("following"),
v.literal("engaged_with"),
// Business relationships (3 types)
v.literal("manages"),
v.literal("collaborates_with"),
v.literal("assigned_to"),
// Transactional relationships (4 types)
v.literal("transacted"),
v.literal("holds"),
v.literal("enrolled_in"),
v.literal("completed"),
// Referral/growth (2 types)
v.literal("referred_by"),
v.literal("converted_from"),
// Media/analytics (2 types)
v.literal("featured_in"),
v.literal("analyzed_by")
),
metadata: v.optional(v.any()),
strength: v.optional(v.number()),
validFrom: v.optional(v.number()),
validTo: v.optional(v.number()),
createdAt: v.number(),
updatedAt: v.optional(v.number()),
})
.index("by_relationshipType", ["relationshipType"])
.index("by_fromEntity", ["fromEntityId"])
.index("by_toEntity", ["toEntityId"])
.index("by_from_type", ["fromEntityId", "relationshipType"])
.index("by_to_type", ["toEntityId", "relationshipType"])
.index("by_bidirectional", ["fromEntityId", "toEntityId"])
.index("by_type_from_to", ["relationshipType", "fromEntityId", "toEntityId"]),
// EVENTS TABLE - All actions
events: defineTable({
entityId: v.id("entities"),
eventType: v.union(
// Entity lifecycle (6 types)
v.literal("entity_created"),
v.literal("entity_updated"),
v.literal("entity_deleted"),
v.literal("entity_restored"),
v.literal("entity_published"),
v.literal("entity_archived"),
// AI/Clone events (4 types)
v.literal("clone_interaction"),
v.literal("clone_trained"),
v.literal("ai_generated"),
v.literal("voice_cloned"),
// Agent events (3 types)
v.literal("agent_executed"),
v.literal("workflow_started"),
v.literal("workflow_completed"),
// Content events (5 types)
v.literal("content_viewed"),
v.literal("content_interacted"),
v.literal("content_downloaded"),
v.literal("content_embedded"),
v.literal("content_moderated"),
// Learning events (4 types)
v.literal("course_enrolled"),
v.literal("progress_updated"),
v.literal("assessment_completed"),
v.literal("certificate_earned"),
// Token/asset events (5 types)
v.literal("token_deployed"),
v.literal("token_transacted"),
v.literal("token_staked"),
v.literal("governance_action"),
v.literal("nft_minted"),
// Payment events (3 types)
v.literal("payment_processed"),
v.literal("subscription_changed"),
v.literal("invoice_generated"),
// Growth/engagement (5 types)
v.literal("referral_created"),
v.literal("referral_converted"),
v.literal("achievement_unlocked"),
v.literal("level_changed"),
v.literal("viral_shared"),
// Analytics/intelligence (3 types)
v.literal("metric_calculated"),
v.literal("insight_generated"),
v.literal("report_generated")
),
timestamp: v.number(),
metadata: v.optional(v.any()),
actorType: v.optional(
v.union(
v.literal("user"),
v.literal("ai_agent"),
v.literal("system"),
v.literal("api")
)
),
actorId: v.optional(v.id("entities")),
source: v.optional(v.string()),
sessionId: v.optional(v.string()),
})
.index("by_entity", ["entityId"])
.index("by_timestamp", ["timestamp"])
.index("by_eventType", ["eventType"])
.index("by_entity_type", ["entityId", "eventType"])
.index("by_entity_type_time", ["entityId", "eventType", "timestamp"])
.index("by_type_time", ["eventType", "timestamp"])
.index("by_session", ["sessionId", "timestamp"])
.index("by_actor", ["actorId", "timestamp"]),
// TAGS TABLE - All categories
tags: defineTable({
name: v.string(),
category: v.optional(
v.union(
v.literal("skill"),
v.literal("industry"),
v.literal("topic"),
v.literal("format"),
v.literal("goal"),
v.literal("audience"),
v.literal("technology"),
v.literal("status")
)
),
description: v.optional(v.string()),
color: v.optional(v.string()),
icon: v.optional(v.string()),
usageCount: v.number(),
createdAt: v.number(),
})
.index("by_name", ["name"])
.index("by_category", ["category"])
.index("by_usageCount", ["usageCount"]),
// ENTITY-TAG JUNCTION TABLE
entityTags: defineTable({
entityId: v.id("entities"),
tagId: v.id("tags"),
createdAt: v.number(),
})
.index("by_entity", ["entityId"])
.index("by_tag", ["tagId"])
.index("by_entity_tag", ["entityId", "tagId"]),
// EMBEDDINGS TABLE - Vector search
embeddings: defineTable({
entityId: v.id("entities"),
embedding: v.array(v.float64()),
model: v.string(),
createdAt: v.number(),
})
.index("by_entity", ["entityId"])
.vectorIndex("by_embedding", {
vectorField: "embedding",
dimensions: 1536,
filterFields: ["entityId", "model"],
}),
});
```
**Migration Strategy**: Batched processing with dual-write pattern during transition period.
**Success Criteria**: ✅ Schema deploys without errors, ✅ All entity types creatable, ✅ Relationship queries work
### Metadata-Based Query Patterns
**Purpose**: Show how to query consolidated types using metadata filters instead of proliferating specific types.
#### Example 1: Query Payments by Status
```typescript
// OLD WAY: Multiple event types
// query("events").filter(q =>
// q.or(
// q.eq(q.field("eventType"), "payment_initiated"),
// q.eq(q.field("eventType"), "payment_completed"),
// q.eq(q.field("eventType"), "payment_failed")
// )
// )
// NEW WAY: Single event type with metadata filter
export const getPaymentsByStatus = query({
args: { status: v.union(v.literal("initiated"), v.literal("completed"), v.literal("failed"), v.literal("refunded")) },
handler: async (ctx, args) => {
const payments = await ctx.db
.query("events")
.withIndex("by_eventType", (q) => q.eq("eventType", "payment_processed"))
.filter((q) => q.eq(q.field("metadata.status"), args.status))
.order("desc")
.take(100);
return payments;
},
});
```
#### Example 2: Query Connections by Transaction Type
```typescript
// OLD WAY: Separate connection types for each transaction
// "paid_for", "subscribed_to", "invoiced_to"
// NEW WAY: Single "transacted" type with metadata
export const getTransactionsByType = query({
args: {
userId: v.id("entities"),
transactionType: v.union(v.literal("purchase"), v.literal("subscription"), v.literal("invoice"))
},
handler: async (ctx, args) => {
const transactions = await ctx.db
.query("connections")
.withIndex("by_from_type", (q) =>
q.eq("fromEntityId", args.userId).eq("relationshipType", "transacted")
)
.filter((q) => q.eq(q.field("metadata.transactionType"), args.transactionType))
.collect();
return transactions;
},
});
```
#### Example 3: Query User Engagement by Interaction Type
```typescript
// OLD WAY: Multiple connection types
// "content_liked", "content_shared", "content_commented"
// NEW WAY: Single "engaged_with" type with metadata
export const getUserEngagement = query({
args: {
contentId: v.id("entities"),
interactionType: v.optional(v.union(v.literal("liked"), v.literal("shared"), v.literal("commented")))
},
handler: async (ctx, args) => {
let engagements = ctx.db
.query("connections")
.withIndex("by_to_type", (q) =>
q.eq("toEntityId", args.contentId).eq("relationshipType", "engaged_with")
);
// Filter by interaction type if specified
if (args.interactionType) {
engagements = engagements.filter((q) =>
q.eq(q.field("metadata.engagementType"), args.interactionType)
);
}
return await engagements.collect();
},
});
```
#### Example 4: Query Agent Executions by Status
```typescript
// OLD WAY: Multiple event types
// "agent_executed", "agent_completed", "agent_failed"
// NEW WAY: Single event type with status in metadata
export const getAgentExecutions = query({
args: {
agentId: v.id("entities"),
status: v.optional(v.union(v.literal("success"), v.literal("failed"), v.literal("partial")))
},
handler: async (ctx, args) => {
let executions = ctx.db
.query("events")
.withIndex("by_entity_type", (q) =>
q.eq("entityId", args.agentId).eq("eventType", "agent_executed")
);
// Filter by status if specified
if (args.status) {
executions = executions.filter((q) =>
q.eq(q.field("metadata.status"), args.status)
);
}
return await executions.order("desc").take(50);
},
});
```
#### Example 5: Analytics Query Across Consolidated Types
```typescript
// Query all payment statuses for analytics
export const getPaymentAnalytics = query({
args: { startDate: v.number(), endDate: v.number() },
handler: async (ctx, args) => {
const payments = await ctx.db
.query("events")
.withIndex("by_type_time", (q) =>
q.eq("eventType", "payment_processed")
.gte("timestamp", args.startDate)
.lte("timestamp", args.endDate)
)
.collect();
// Aggregate by status
const analytics = {
initiated: 0,
completed: 0,
failed: 0,
refunded: 0,
totalAmount: 0,
};
payments.forEach((payment) => {
const status = payment.metadata?.status || "unknown";
if (status in analytics) {
analytics[status]++;
}
if (status === "completed") {
analytics.totalAmount += payment.metadata?.amount || 0;
}
});
return analytics;
},
});
```
**Benefits of Metadata-Based Queries**:
- **Simpler schema**: 25 connection types vs. 30+, 35 event types vs. 50+
- **Easier analytics**: Single event type aggregation vs. multiple OR conditions
- **More flexible**: Add new statuses without schema migrations
- **Better performance**: Index on single eventType, filter on metadata
- **Clearer intent**: `metadata.status` explicitly shows state variants
---
## Quick Reference Guide
### How to Build a Feature (Step-by-Step)
**1. Map to Ontology**
- What **entities** are involved? (creator, ai_clone, token, etc.)
- What **connections** link them? (owns, follows, enrolled_in, etc.)
- What **events** need logging? (clone_created, tokens_purchased, etc.)
- What **tags** categorize them? (industry:fitness, skill:video, etc.)
**2. Write in Plain English DSL**
```
FEATURE: [What this does]
INPUT:
- [what you need]
OUTPUT:
- [what you get back]
FLOW:
CHECK [validations]
CALL [external services]
CREATE [entities]
CONNECT [relationships]
RECORD [events]
GIVE [results]
```
**3. Validate Against Ontology**
```typescript
const validator = new ONEValidator(ontology);
const validation = validator.validate(myFeatureDSL);
if (!validation.valid) {
console.error(validation.errors);
}
```
**4. Compile to TypeScript**
```typescript
const compiler = new ONECompiler();
const code = compiler.compile(myFeatureDSL);
// Generates type-safe Effect.ts code
```
**5. Deploy**
```bash
# Code is automatically tested and deployed
```
### Common Patterns
**Pattern: Create Thing with Ownership**
```typescript
// DSL
{
thing: { type: "ai_clone", name: "My Clone", properties: {...} },
output: "cloneId"
}
{
connect: { from: "$creatorId", to: "$cloneId", type: "owns" }
}
{
event: { thing: "$cloneId", type: "clone_created", actor: "$creatorId" }
}
```
**Pattern: Token Purchase with Rollback**
```typescript
// DSL
{
atomic: [
{ service: { provider: "stripe", method: "charge", ... } },
{ service: { provider: "blockchain", method: "mint", ... } }
],
onError: {
rollback: [
{ service: { provider: "stripe", method: "refund", ... } },
{ service: { provider: "blockchain", method: "burn", ... } }
]
}
}
```
**Pattern: Query with Relationships**
```typescript
// Get creator's content
{
query: {
from: "connections",
where: [
{ field: "fromEntityId", operator: "eq", value: "$creatorId" },
{ field: "relationshipType", operator: "eq", value: "authored" }
]
},
output: "contentConnections"
}
```
### Validation Rules
**Thing Validation:**
- ✅ Type must be valid ThingType from ontology
- ✅ Name cannot be empty
- ✅ Properties structure must match type
- ✅ Status must be valid (active, inactive, draft, published, archived)
**Connection Validation:**
- ✅ fromThingId and toThingId must exist
- ✅ relationshipType must be valid ConnectionType
- ✅ Cannot connect thing to itself (usually)
- ✅ Relationship must make semantic sense
**Event Validation:**
- ✅ thingId must exist
- ✅ eventType must be valid EventType
- ✅ timestamp required
- ✅ actorId must exist if provided
**Knowledge Validation:**
- ✅ label must be unique or properly scoped
- ✅ category must be valid KnowledgeCategory
- ✅ usageCount must be >= 0
### Performance Guidelines
**Indexes:**
- Use indexes for all filter fields
- Compound indexes for multi-field queries
- Vector indexes for semantic search
**Query Optimization:**
- Always use indexes for filters
- Limit results with `.take(n)`
- Paginate large result sets
- Prefer streaming over `.collect()` for large datasets
**Caching:**
- Cache frequently accessed entities
- Invalidate cache on entity updates
- Use stale-while-revalidate pattern
### Reference Files
- **Ontology Spec**: `Ontology.md` - Complete 6-dimension data model
- **Technical DSL**: `DSL.md`, `ONE DSL.md` - JSON-like syntax and compiler
- **Plain English DSL**: `ONE DSL English.md` - Natural language syntax
- **Schema**: `convex/schema.ts` - Current and target schemas
- **Examples**: This file - Real-world implementation patterns
---
### Week 2: Payment Infrastructure
**Stripe Connect Integration - Direct Revenue Enabler**
#### Implementation: Token Purchase with Revenue Splits
**File**: `convex/payments/tokenPurchase.ts`
```typescript
import { v } from "convex/values";
import { mutation, query } from "./_generated/server";
import { internal } from "./_generated/api";
// Query to get token ownership for revenue splits
export const getTokenOwnership = query({
args: { tokenId: v.id("entities") },
handler: async (ctx, args) => {
// Get token entity
const token = await ctx.db.get(args.tokenId);
if (!token || token.type !== "token") {
throw new Error("Token not found");
}
// Get ownership connections using plain Convex query with index
const ownerships = await ctx.db
.query("connections")
.withIndex("by_to_type", (q) =>
q.eq("toEntityId", args.tokenId).eq("relationshipType", "owns")
)
.collect();
// Return owners with revenue split metadata
return Promise.all(
ownerships.map(async (conn) => {
const owner = await ctx.db.get(conn.fromEntityId);
return {
ownerId: conn.fromEntityId,
ownerName: owner?.name,
revenueShare: conn.metadata?.revenueShare || 0,
stripeAccountId: owner?.properties?.stripeAccountId,
};
})
);
},
});
// Mutation to process token purchase
export const purchaseTokens = mutation({
args: {
userId: v.id("entities"),
tokenId: v.id("entities"),
amount: v.number(),
usdAmount: v.number(),
},
handler: async (ctx, args) => {
// Validate entities exist
const user = await ctx.db.get(args.userId);
const token = await ctx.db.get(args.tokenId);
if (!user || user.type !== "audience_member") {
throw new Error("User not found");
}
if (!token || token.type !== "token") {
throw new Error("Token not found");
}
// Schedule payment processing (will be done in action)
await ctx.scheduler.runAfter(0, internal.payments.processTokenPayment, {
userId: args.userId,
tokenId: args.tokenId,
amount: args.amount,
usdAmount: args.usdAmount,
});
return { success: true, message: "Payment processing initiated" };
},
});
```
**File**: `convex/payments/processPayment.ts` (Action)
```typescript
"use node";
import { v } from "convex/values";
import { internalAction } from "./_generated/server";
import { internal } from "./_generated/api";
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export const processTokenPayment = internalAction({
args: {
userId: v.id("entities"),
tokenId: v.id("entities"),
amount: v.number(),
usdAmount: v.number(),
},
handler: async (ctx, args) => {
// Get ownership for revenue splits
const ownership = await ctx.runQuery(internal.payments.getTokenOwnership, {
tokenId: args.tokenId,
});
const platformFee = Math.floor(args.usdAmount * 0.15 * 100); // 15% platform fee
// Create Stripe checkout with revenue splits
const session = await stripe.checkout.sessions.create({
line_items: [
{
price_data: {
currency: "usd",
unit_amount: args.usdAmount * 100,
product_data: { name: `${args.amount} Tokens` },
},
quantity: 1,
},
],
mode: "payment",
payment_intent_data: {
application_fee_amount: platformFee,
transfer_data: {
destination: ownership[0].stripeAccountId, // Primary owner gets payment
},
},
metadata: {
userId: args.userId,
tokenId: args.tokenId,
amount: args.amount.toString(),
},
});
// Record payment event with metadata status
await ctx.runMutation(internal.events.create, {
entityId: args.tokenId,
eventType: "payment_processed",
actorType: "user",
actorId: args.userId,
metadata: {
status: "initiated",
paymentType: "token_purchase",
amount: args.amount,
usdAmount: args.usdAmount,
sessionId: session.id,
},
});
return { sessionId: session.id, url: session.url };
},
});
```
**Seller Onboarding**: 2-minute Stripe Express flow with automatic account creation.
**Success Criteria**: ✅ Transactions process correctly, ✅ Revenue splits accurate, ✅ Webhooks handled
---
## Phase 2: Content & Product Economy (Weeks 3-4)
### Week 3: Content Creation & Discovery
**Universal Content Creator - Multiple types following ontology (blog_post, video, podcast, social_post, course, digital_product)**
#### Content Creator Implementation
**File**: `convex/content/create.ts`
```typescript
import { v } from "convex/values";
import { mutation } from "./_generated/server";
export const createContent = mutation({
args: {
creatorId: v.id("entities"),
type: v.union(
v.literal("blog_post"),
v.literal("video"),
v.literal("podcast"),
v.literal("social_post"),
v.literal("course"),
v.literal("digital_product")
),
name: v.string(),
properties: v.any(), // Type-specific properties
tags: v.optional(v.array(v.string())),
collaborators: v.optional(
v.array(
v.object({
entityId: v.id("entities"),
revenueShare: v.number(), // 0.0 to 1.0
})
)
),
},
handler: async (ctx, args) => {
// Validate creator exists
const creator = await ctx.db.get(args.creatorId);
if (!creator || creator.type !== "creator") {
throw new Error("Creator not found");
}
// Create content entity
const contentId = await ctx.db.insert("entities", {
type: args.type,
name: args.name,
properties: args.properties,
status: "draft",
createdAt: Date.now(),
updatedAt: Date.now(),
});
// Create ownership connection (creator owns content)
await ctx.db.insert("connections", {
fromEntityId: args.creatorId,
toEntityId: contentId,
relationshipType: "owns",
metadata: { revenueShare: 1.0 }, // Creator gets 100% initially
createdAt: Date.now(),
});
// Create authored connection
await ctx.db.insert("connections", {
fromEntityId: args.creatorId,
toEntityId: contentId,
relationshipType: "authored",
createdAt: Date.now(),
});
// Add collaborators with revenue splits
if (args.collaborators) {
for (const collab of args.collaborators) {
await ctx.db.insert("connections", {
fromEntityId: collab.entityId,
toEntityId: contentId,
relationshipType: "owns",
metadata: { revenueShare: collab.revenueShare },
createdAt: Date.now(),
});
}
}
// Add tags
if (args.tags) {
for (const tagName of args.tags) {
// Get or create tag
let tag = await ctx.db
.query("tags")
.withIndex("by_name", (q) => q.eq("name", tagName))
.unique();
if (!tag) {
const tagId = await ctx.db.insert("tags", {
name: tagName,
category: "topic",
usageCount: 0,
createdAt: Date.now(),
});
tag = await ctx.db.get(tagId);
}
// Create entity-tag association
await ctx.db.insert("entityTags", {
entityId: contentId,
tagId: tag!._id,
createdAt: Date.now(),
});
// Increment tag usage count
await ctx.db.patch(tag!._id, {
usageCount: tag!.usageCount + 1,
});
}
}
// Log entity creation event with content-specific metadata
await ctx.db.insert("events", {
entityId: contentId,
eventType: "entity_created",
timestamp: Date.now(),
actorType: "user",
actorId: args.creatorId,
metadata: {
entityType: args.type,
collaboratorCount: args.collaborators?.length || 0,
tagCount: args.tags?.length || 0,
},
});
return { contentId, success: true };
},
});
```
**Frontend**: Multi-step wizard with file upload, collaborator management, tag selection, and license controls
---
### Week 4: Semantic Search Implementation
**Hybrid Search: Vector Similarity + Keyword Matching using ontology entities table**
#### Vector Embeddings
**File**: `convex/embeddings/generate.ts`
```typescript
"use node";
import { v } from "convex/values";
import { internalAction } from "./_generated/server";
import { internal } from "./_generated/api";
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export const generateEntityEmbedding = internalAction({
args: { entityId: v.id("entities") },
handler: async (ctx, args) => {
// Get entity
const entity = await ctx.runQuery(internal.entities.get, {
id: args.entityId,
});
if (!entity) {
throw new Error("Entity not found");
}
// Create searchable text from entity
const text = `${entity.name}\n${entity.properties?.description || ""}\n${
entity.properties?.content || ""
}`;
// Generate embedding
const response = await openai.embeddings.create({
model: "text-embedding-3-small",
input: text,
dimensions: 1536,
});
// Save embedding
await ctx.runMutation(internal.embeddings.save, {
entityId: args.entityId,
embedding: response.data[0].embedding,
model: "text-embedding-3-small",
});
return { success: true };
},
});
```
**File**: `convex/embeddings/save.ts`
```typescript
import { v } from "convex/values";
import { internalMutation } from "./_generated/server";
export const save = internalMutation({
args: {
entityId: v.id("entities"),
embedding: v.array(v.float64()),
model: v.string(),
},
handler: async (ctx, args) => {
// Check if embedding exists
const existing = await ctx.db
.query("embeddings")
.withIndex("by_entity", (q) => q.eq("entityId", args.entityId))
.unique();
if (existing) {
// Update existing
await ctx.db.patch(existing._id, {
embedding: args.embedding,
model: args.model,
createdAt: Date.now(),
});
} else {
// Create new
await ctx.db.insert("embeddings", {
entityId: args.entityId,
embedding: args.embedding,
model: args.model,
createdAt: Date.now(),
});
}
return { success: true };
},
});
```
#### Semantic Search Query
**File**: `convex/search/semantic.ts`
```typescript
"use node";
import { v } from "convex/values";
import { action } from "./_generated/server";
import { internal } from "./_generated/api";
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export const semanticSearch = action({
args: {
query: v.string(),
entityTypes: v.optional(v.array(v.string())),
limit: v.optional(v.number()),
},
handler: async (ctx, args) => {
// Generate query embedding
const response = await openai.embeddings.create({
model: "text-embedding-3-small",
input: args.query,
dimensions: 1536,
});
const queryEmbedding = response.data[0].embedding;
// Vector search on embeddings table
const results = await ctx.vectorSearch("embeddings", "by_embedding", {
vector: queryEmbedding,
limit: args.limit || 20,
});
// Hydrate entities and filter by type if specified
const entities = await Promise.all(
results.map(async (r) => {
const entity = await ctx.runQuery(internal.entities.get, {
id: r._id,
});
return { entity, score: r._score };
})
);
// Filter by entity type if specified
const filtered = args.entityTypes
? entities.filter((e) => args.entityTypes!.includes(e.entity?.type || ""))
: entities;
return filtered.map((e) => e.entity);
},
});
// Hybrid search combining vector similarity and keyword matching
export const hybridSearch = action({
args: {
query: v.string(),
entityTypes: v.optional(v.array(v.string())),
limit: v.optional(v.number()),
},
handler: async (ctx, args) => {
// Run semantic search
const semanticResults = await ctx.runAction(internal.search.semanticSearch, {
query: arg