---
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.**
