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.
883 lines (682 loc) • 22.5 kB
Markdown
title: Ontology Driven Strategy
dimension: things
category: plans
tags: 6-dimensions, ai, backend, connections, events, frontend, knowledge, ontology, people, things
related_dimensions: connections, events, groups, knowledge, people
scope: global
created: 2025-11-03
updated: 2025-11-03
version: 1.0.0
ai_context: |
This document is part of the things dimension in the plans category.
Location: one/things/plans/ontology-driven-strategy.md
Purpose: Documents ontology-driven strategy: build once, run anywhere
Related dimensions: connections, events, groups, knowledge, people
For AI agents: Read this to understand ontology driven strategy.
# Ontology-Driven Strategy: Build Once, Run Anywhere
**Strategic Analysis: Your Two Core Assets**
## Current State Assessment
### Asset #1: The Ontology (`/one`)
**What you have:**
- 6-dimension data model (organizations, people, things, connections, events, knowledge)
- 66 thing types (course, product, post, lesson, etc.)
- 25 connection types (owns, enrolled_in, purchased, etc.)
- 67 event types (complete audit trail)
- Universal, backend-agnostic specification
**Strengths:**
- ✅ Well-designed, comprehensive
- ✅ Works with ANY backend
- ✅ Real-world tested (working frontend uses it)
- ✅ Intellectual property (your design)
- ✅ Can become an industry standard
**Current Gap:**
- ⚠️ Missing frontend/UI metadata
- ⚠️ No component mapping guidance
- ⚠️ Doesn't tell developers HOW to render things
- ⚠️ Backend implementation varies
### Asset #2: The Frontend (`/frontend`)
**What you have:**
- Working Astro + React application
- Connected to Convex backend
- Auth system (Better Auth, 6 methods)
- Real-time updates
- Component library
**Strengths:**
- ✅ Proven, working implementation
- ✅ Fast (Astro Islands)
- ✅ Modern stack (React 19, TypeScript)
- ✅ Real auth tests passing
**Current Gap:**
- ⚠️ Tightly coupled to Convex
- ⚠️ Components hardcoded for specific types
- ⚠️ Not easily configurable/customizable
- ⚠️ Can't easily adapt to new thing types
## Strategic Insight: Ontology-Driven Architecture
**The Breakthrough:** Your ontology should be "frontend-complete" - it describes not just the data model, but also how to render it.
### Current Model (Separated)
```
┌─────────────────┐ ┌─────────────────┐
│ Ontology │ │ Frontend │
│ (Data Only) │ │ (UI Only) │
│ │ │ │
│ - thing types │ → │ - components │
│ - properties │ → │ - pages │
│ - connections │ → │ - layouts │
└─────────────────┘ └─────────────────┘
Problem: Frontend developer must figure out
how to render each thing type from scratch.
```
### Refined Model (Unified)
```
┌──────────────────────────────────────────┐
│ Ontology (Frontend-Complete) │
│ │
│ Data Model + UI Model = Complete Spec │
│ │
│ For each thing type: │
│ - Properties (data) │
│ - Component (how to render) │
│ - Layout (how to arrange) │
│ - Actions (what user can do) │
│ - Views (card/list/detail) │
└──────────────────────────────────────────┘
↓
┌──────────────────────────────────────────┐
│ Frontend (Generic Renderer) │
│ │
│ Reads ontology → Renders UI │
│ No hardcoded components │
│ Works with ANY backend │
└──────────────────────────────────────────┘
```
**Benefits:**
- ✅ Add new thing type → UI updates automatically
- ✅ Frontend is just a renderer (no business logic)
- ✅ Ontology is single source of truth
- ✅ Any backend that implements ontology works
- ✅ Consistency across all 66 types
## Refinement #1: Add UI Metadata to Ontology
### Current Thing Type Definition
```typescript
// one/knowledge/ontology.md
{
type: "course",
description: "Educational course or training program",
properties: {
title: "string",
description: "string",
price: "number",
duration: "string",
level: "beginner | intermediate | advanced",
category: "string",
tags: "string[]",
thumbnail: "string (URL)",
publishedAt: "timestamp"
}
}
```
**Problem:** No guidance on HOW to display this.
### Refined Thing Type Definition (Frontend-Complete)
```typescript
// one/knowledge/ontology-ui.md (NEW FILE)
{
type: "course",
description: "Educational course or training program",
// Data properties (existing)
properties: {
title: { type: "string", required: true },
description: { type: "string", required: true },
price: { type: "number", required: false },
duration: { type: "string", required: false },
level: { type: "enum", values: ["beginner", "intermediate", "advanced"] },
category: { type: "string", required: false },
tags: { type: "array", items: "string" },
thumbnail: { type: "url", required: false },
publishedAt: { type: "timestamp", required: false }
},
// UI metadata (NEW)
ui: {
// Primary component to use
component: "Card",
// Layout preferences
layouts: {
grid: { columns: 3, gap: "md" },
list: { orientation: "horizontal", gap: "sm" },
detail: { width: "prose", centered: true }
},
// Field rendering instructions
fields: {
title: {
component: "Heading",
size: "xl",
weight: "bold",
truncate: 2,
required: true
},
description: {
component: "Text",
lines: 3,
size: "base",
color: "muted"
},
price: {
component: "Price",
currency: "USD",
format: "compact",
badge: true
},
thumbnail: {
component: "Image",
aspect: "video",
lazy: true,
placeholder: "/defaults/course.jpg"
},
level: {
component: "Badge",
colors: {
beginner: "green",
intermediate: "yellow",
advanced: "red"
}
},
tags: {
component: "TagList",
max: 3,
color: "blue"
}
},
// Available views
views: {
card: { default: true, fields: ["thumbnail", "title", "description", "price", "level"] },
list: { fields: ["thumbnail", "title", "duration", "price"] },
detail: { fields: "*" } // All fields
},
// User actions
actions: {
primary: { action: "enroll", label: "Enroll Now", icon: "check" },
secondary: [
{ action: "preview", label: "Preview", icon: "eye" },
{ action: "share", label: "Share", icon: "share" },
{ action: "bookmark", label: "Save", icon: "bookmark" }
]
},
// Connection display
connections: {
enrolled_in: {
label: "{count} students enrolled",
icon: "users",
display: "badge"
},
contains: {
label: "{count} lessons",
icon: "list",
display: "inline"
},
created_by: {
label: "by {name}",
icon: "user",
display: "avatar"
}
},
// Empty states
empty: {
icon: "book",
title: "No courses yet",
description: "Create your first course to get started",
action: { label: "Create Course", route: "/courses/new" }
}
}
}
```
**Now frontend knows EXACTLY how to render any course!**
## Refinement #2: Generic Component System
### Current Frontend (Type-Specific Components)
```tsx
// frontend/src/components/CourseCard.tsx
// ❌ Hardcoded for courses only
export function CourseCard({ course }) {
return (
<div className="card">
<img src={course.properties.thumbnail} />
<h3>{course.name}</h3>
<p>{course.properties.description}</p>
<span>${course.properties.price}</span>
</div>
);
}
// frontend/src/components/ProductCard.tsx
// ❌ Duplicate code, slightly different
export function ProductCard({ product }) {
return (
<div className="card">
<img src={product.properties.image} />
<h3>{product.name}</h3>
<p>{product.properties.description}</p>
<span>${product.properties.price}</span>
</div>
);
}
// ... 64 more type-specific components 😱
```
**Problem:** Can't scale to 66 thing types. Too much duplication.
### Refined Frontend (Generic Components)
```tsx
// frontend/src/components/Card.tsx
// ✅ Works for ANY thing type
import { useThingConfig } from "@/ontology/hooks";
export function Card({ thing }) {
// Get UI config from ontology
const config = useThingConfig(thing.type);
return (
<Card layout={config.ui.layouts.grid}>
{config.ui.views.card.fields.map((fieldName) => (
<Field
key={fieldName}
name={fieldName}
value={thing.properties[fieldName]}
config={config.ui.fields[fieldName]}
/>
))}
<Actions
primary={config.ui.actions.primary}
secondary={config.ui.actions.secondary}
thingId={thing._id}
/>
</Card>
);
}
// ONE component renders all 66 types! 🎉
```
**Usage:**
```tsx
// frontend/src/pages/courses/[id].astro
<Card thing={course} /> // Renders as course card
// frontend/src/pages/products/[id].astro
<Card thing={product} /> // Renders as product card
// frontend/src/pages/posts/[id].astro
<Card thing={post} /> // Renders as post card
// Same component, different rendering based on ontology!
```
## Refinement #3: Ontology-Driven Routing
### Current Routing (Manual)
```typescript
// frontend/src/pages/courses/[id].astro ❌
// frontend/src/pages/products/[id].astro ❌
// frontend/src/pages/posts/[id].astro ❌
// frontend/src/pages/lessons/[id].astro ❌
// ... 62 more route files 😱
```
**Problem:** Must manually create routes for each type.
### Refined Routing (Generated from Ontology)
```typescript
// frontend/src/pages/[type]/[id].astro ✅
// Handles ALL 66 thing types!
import { getThingById } from '@/services/ThingService'
import { getThingConfig } from '@/ontology/config'
import ThingDetail from '@/components/ThingDetail.astro'
const { type, id } = Astro.params
const thing = await getThingById(id)
const config = getThingConfig(type)
<ThingDetail
thing={thing}
config={config}
/>
```
**Now:**
- `/courses/123` works ✅
- `/products/456` works ✅
- `/posts/789` works ✅
- `/lessons/321` works ✅
- ALL types work automatically!
## Refinement #4: Backend Connection Strategy
### Default to ONE Backend, Support Any Backend
```typescript
// frontend/astro.config.ts
const useOneBackend = import.meta.env.USE_ONE_BACKEND === "true";
export default defineConfig({
integrations: [
one({
// Option 1: ONE Backend (BaaS) - EASIEST
provider: useOneBackend
? oneBackendProvider({
apiKey: import.meta.env.PUBLIC_ONE_API_KEY,
organizationId: import.meta.env.PUBLIC_ONE_ORG_ID,
})
: // Option 2: Self-hosted (any backend)
convexProvider({
url: import.meta.env.PUBLIC_CONVEX_URL,
}),
}),
],
});
```
**User experience:**
**Path A: Use ONE Backend (Zero Config)**
```bash
# 1. Sign up at one.ie → Get API key
# 2. Configure
echo "USE_ONE_BACKEND=true" >> .env
echo "PUBLIC_ONE_API_KEY=ok_live_abc123" >> .env
echo "PUBLIC_ONE_ORG_ID=org_456" >> .env
# 3. Run
npm run dev
# ✅ Backend works immediately (managed by ONE)
# ✅ Auth, database, real-time all included
# ✅ Free tier: 10K API calls/month
```
**Path B: Self-Hosted Backend**
```bash
# 1. Choose backend (Convex, Supabase, etc.)
# 2. Configure
echo "USE_ONE_BACKEND=false" >> .env
echo "PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud" >> .env
# 3. Run
npm run dev
# ✅ Backend you control
# ✅ Full flexibility
```
**Key Insight:** ONE Backend is the default/recommended path, but not required.
## Refinement #5: Business Model
### Open Source + Managed Service (Like Stripe)
**What's Open Source (MIT License):**
1. **`@oneie/ontology`** - The 6-dimension specification
- Data model
- UI metadata
- TypeScript types
- Anyone can implement it
2. **`@oneie/frontend`** - Reference implementation
- Generic components
- Ontology-driven rendering
- Works with any backend
- Anyone can fork/customize
3. **`@oneie/providers`** - Backend adapters
- ConvexProvider
- SupabaseProvider
- WordPressProvider
- Community can add more
**What's Managed Service (Revenue):**
4. **ONE Backend (BaaS)** - Hosted backend service
- Implements ontology
- Managed infrastructure
- Auth, database, real-time included
- Pricing: Free → $29/mo → Enterprise
**Business Model:**
```
Open Source Ontology → Adoption → Ecosystem → BaaS Revenue
Just like:
- Stripe: Payment API (standard) + Managed service (revenue)
- Supabase: PostgreSQL (open) + Managed hosting (revenue)
- Vercel: Next.js (open) + Managed hosting (revenue)
```
**Revenue Streams:**
1. ONE Backend subscriptions ($0 → $29 → $99 → custom)
2. Enterprise support (SLAs, dedicated)
3. Premium providers (verified, optimized)
4. Consulting (implementation help)
**Why this works:**
- ✅ Open source → wide adoption
- ✅ BaaS → easy path for users
- ✅ Not forced → community trust
- ✅ Sustainable business
## Recommended Implementation Plan
### Phase 1: Refine Ontology (Week 1-2)
**Create: `one/knowledge/ontology-ui.md`**
For each of the 66 thing types, add:
```typescript
{
type: "thing_type",
properties: { /* existing */ },
ui: {
component: "Card|List|Table",
layouts: { grid, list, detail },
fields: { /* rendering config */ },
views: { card, list, detail },
actions: { primary, secondary },
connections: { /* display config */ },
empty: { icon, title, description, action }
}
}
```
**Start with top 10 most-used types:**
1. course
2. lesson
3. person (creator)
4. product
5. digital_product
6. post
7. page
8. organization
9. session
10. token
**Checklist:**
- [ ] Define UI schema structure
- [ ] Add UI metadata for top 10 types
- [ ] Document field component types
- [ ] Document layout options
- [ ] Create examples for each view type
### Phase 2: Build Generic Components (Week 3-4)
**Create: `frontend/src/components/generic/`**
```
frontend/src/components/generic/
├── Card.tsx # Card view for any thing
├── ThingList.tsx # List view for any thing
├── ThingDetail.tsx # Detail view for any thing
├── Field.tsx # Renders any field type
├── Actions.tsx # Renders action buttons
├── ConnectionBadge.tsx # Shows connections
└── EmptyState.tsx # Empty state for any type
```
**Generic Field Component:**
```tsx
// frontend/src/components/generic/Field.tsx
export function Field({ name, value, config }) {
switch (config.component) {
case "Heading":
return <Heading size={config.size}>{value}</Heading>;
case "Text":
return <Text lines={config.lines}>{value}</Text>;
case "Price":
return <Price value={value} currency={config.currency} />;
case "Image":
return <Image src={value} aspect={config.aspect} />;
case "Badge":
return <Badge color={config.colors[value]}>{value}</Badge>;
case "TagList":
return <TagList tags={value} max={config.max} />;
// ... all field types
}
}
```
**Checklist:**
- [ ] Build generic Card
- [ ] Build generic ThingList
- [ ] Build generic ThingDetail
- [ ] Build Field component with all types
- [ ] Build Actions component
- [ ] Test with 5 different thing types
- [ ] Refactor existing specific components
### Phase 3: Ontology-Driven Routing (Week 5)
**Update: `frontend/src/pages/[type]/[id].astro`**
```astro
import { getThingById, getThingConfig } from '@/services/ThingService'
import ThingLayout from '@/layouts/ThingLayout.astro'
import ThingDetail from '@/components/generic/ThingDetail.tsx'
const { type, id } = Astro.params
// Get thing from backend (any backend via DataProvider)
const thing = await getThingById(id)
// Get UI config from ontology
const config = getThingConfig(type)
<ThingLayout title={thing.name} config={config}>
<ThingDetail
thing={thing}
config={config}
client:load
/>
</ThingLayout>
```
**Checklist:**
- [ ] Create dynamic `[type]/[id].astro` route
- [ ] Add ontology config loader
- [ ] Test all thing types work
- [ ] Add SEO metadata from config
- [ ] Add social share cards
- [ ] Delete old type-specific routes
### Phase 4: Connect to ONE Backend (Week 6)
**Create: `@oneie/baas-sdk`**
```typescript
// packages/baas-sdk/src/OneBackendProvider.ts
import { DataProvider } from "@oneie/core";
export class OneBackendProvider implements DataProvider {
constructor(
private config: {
apiKey: string;
organizationId: string;
apiUrl?: string; // default: https://api.one.ie
},
) {}
things = {
get: (id) =>
fetch(`${this.apiUrl}/things/${id}`, {
headers: {
Authorization: `Bearer ${this.apiKey}`,
"X-Organization-ID": this.organizationId,
},
}),
list: (params) =>
fetch(`${this.apiUrl}/things?type=${params.type}`, {
headers: {
/* ... */
},
}),
// ... all DataProvider methods
};
// ... connections, events, knowledge
}
```
**Update: `frontend/astro.config.ts`**
```typescript
import { oneBackendProvider } from "@oneie/baas-sdk";
import { convexProvider } from "@oneie/provider-convex";
const useOneBackend = import.meta.env.USE_ONE_BACKEND === "true";
export default defineConfig({
integrations: [
one({
provider: useOneBackend
? oneBackendProvider({
apiKey: import.meta.env.PUBLIC_ONE_API_KEY,
organizationId: import.meta.env.PUBLIC_ONE_ORG_ID,
})
: convexProvider({
url: import.meta.env.PUBLIC_CONVEX_URL,
}),
}),
],
});
```
**Checklist:**
- [ ] Build OneBackendProvider
- [ ] Add API key validation
- [ ] Add rate limiting
- [ ] Add error handling
- [ ] Test with frontend
- [ ] Deploy ONE Backend API
- [ ] Create signup flow at one.ie
## Success Metrics
**Ontology Refinement:**
- [ ] All 66 thing types have UI metadata
- [ ] Generic components render all types correctly
- [ ] No type-specific components needed
- [ ] Adding new type takes < 5 minutes
**Frontend:**
- [ ] 90% code reduction (generic vs specific)
- [ ] Works with 3+ different backends
- [ ] All auth tests still pass
- [ ] Performance unchanged (Astro Islands)
**ONE Backend:**
- [ ] Signup flow works
- [ ] API key generation works
- [ ] 10 beta users signed up
- [ ] 3 live apps using ONE Backend
**Open Source:**
- [ ] Ontology published to npm
- [ ] Frontend reference implementation public
- [ ] Providers published (Convex, Supabase, WordPress)
- [ ] 100+ GitHub stars
- [ ] 10+ community discussions
## Strategic Positioning
### Your Unique Value Proposition
**You're not building:**
- ❌ Another backend (there are many)
- ❌ Another frontend framework (there are many)
- ❌ Another database (there are many)
**You're building:**
- ✅ **A universal ontology** (the standard for data + UI)
- ✅ **A reference frontend** (shows how to implement the standard)
- ✅ **A managed backend** (easiest way to use the standard)
**Analogies:**
- **Like HTML**: Standard for content, anyone can implement, works everywhere
- **Like Stripe**: Payment API standard, with managed service option
- **Like PostgreSQL**: Open database standard, with hosted options (Supabase, Neon)
### Market Position
**Primary Message:**
> "ONE is the universal standard for connecting frontends to backends. Use our ontology, build with any tech stack, deploy anywhere."
**Secondary Message:**
> "Can't build a backend? Use ONE Backend - managed service with auth, database, and real-time included. Free tier available."
**Target Audiences:**
1. **Frontend developers** → "Build apps without backend knowledge"
2. **Full-stack developers** → "Stop reinventing data models"
3. **Agencies** → "Deliver faster with reusable ontology"
4. **Enterprises** → "Standardize on ONE across projects"
## Next Steps (This Week)
### Day 1-2: Ontology Refinement
- [ ] Create `one/knowledge/ontology-ui.md`
- [ ] Define UI metadata schema
- [ ] Add UI metadata for top 5 types (course, lesson, product, post, person)
### Day 3-4: Generic Components
- [ ] Build `Card` component
- [ ] Build `Field` component
- [ ] Test with 3 different thing types
- [ ] Refactor one existing page to use generic components
### Day 5: Documentation
- [ ] Document ontology UI schema
- [ ] Write guide: "How to add UI metadata"
- [ ] Write guide: "Building with generic components"
- [ ] Update `separate.md` with ontology-driven approach
### Weekend: Publish Plan
- [ ] Share this document with team
- [ ] Get feedback on ontology refinement
- [ ] Prioritize which types to refine first
- [ ] Plan Week 2 work
## Key Insight
**Your strongest position:**
1. **Ontology = Standard** (like HTTP, HTML, SQL)
2. **Frontend = Reference** (like Chrome implements web standards)
3. **ONE Backend = Convenience** (like Netlify hosts websites)
This positions you as:
- ✅ **Standard-setter** (control the definition)
- ✅ **Ecosystem-builder** (others can implement)
- ✅ **Service-provider** (revenue without forcing)
**You win when:** Organizations say "We use the ONE ontology" (regardless of backend choice).
**The refined ontology is your moat. The frontend proves it works. ONE Backend makes it effortless.**