UNPKG

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