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.

861 lines (665 loc) 25.4 kB
--- title: Queries Reference dimension: connections category: api tags: backend, ontology related_dimensions: events, groups, knowledge, people, things scope: global created: 2025-11-03 updated: 2025-11-03 version: 1.0.0 ai_context: | This document is part of the connections dimension in the api category. Location: one/connections/api/queries-reference.md Purpose: Documents queries reference - 6-dimension ontology api Related dimensions: events, groups, knowledge, people, things For AI agents: Read this to understand queries reference. --- # Queries Reference - 6-Dimension Ontology API ## Executive Summary Complete reference documentation for all backend queries (`convex/queries/`) aligned with the ONE Platform's 6-dimension ontology. This consolidated guide covers overview, complete specifications, and practical examples. **Status**: Complete and Production-Ready **Total Queries**: 44 across 6 dimensions **Documentation Levels**: Overview Complete Reference Practical Examples --- ## Table of Contents 1. [Overview](#overview) 2. [The 6-Dimension Reality Model](#the-6-dimension-reality-model) 3. [Query Organization by Dimension](#query-organization-by-dimension) 4. [Complete Query Reference](#complete-query-reference) 5. [Query Naming Conventions](#query-naming-conventions) 6. [Multi-Tenancy Pattern](#multi-tenancy-pattern) 7. [Performance Optimization](#performance-optimization) 8. [Practical Examples](#practical-examples) 9. [Ontology Runtime Discovery](#ontology-runtime-discovery) 10. [Adding New Queries](#adding-new-queries) --- ## Overview ### The 6-Dimension Reality Model ``` GROUPS (1) owns/contains PEOPLE (2) authorize THINGS (3) are related via CONNECTIONS (4) trigger EVENTS (5) create KNOWLEDGE (6) ``` ### Query Organization All backend queries are organized by dimension into 6 files: ``` convex/queries/ ├── groups.ts DIMENSION 1 (Multi-tenant isolation) [12 queries] ├── people.ts DIMENSION 2 (Authorization & governance) [4 queries] ├── entities.ts DIMENSION 3 (66+ entity types) [9 queries] ├── connections.ts DIMENSION 4 (25+ relationship types) [4 queries] ├── events.ts DIMENSION 5 (67+ event types - audit) [7 queries] ├── knowledge.ts DIMENSION 6 (Vectors, embeddings, RAG) [8 queries] └── ontology.ts Runtime feature discovery [special] TOTAL: 44 production queries ``` --- ## The 6-Dimension Reality Model ``` GROUPS (1) ├─ Multi-tenant isolation boundary ├─ Hierarchical nesting (groups in groups) └─ Plans: starter, pro, enterprise PEOPLE (2) ├─ Authorization & governance ├─ 4 roles: platform_owner, org_owner, org_user, customer └─ Every action has an actor THINGS (3) ├─ 66+ entity types ├─ Users, agents, content, products, courses, tokens, etc. └─ Status: draft active published archived CONNECTIONS (4) ├─ 25+ relationship types ├─ Owns, follows, teaches, manages, etc. └─ Bidirectional with metadata EVENTS (5) ├─ 67+ event types (audit trail) ├─ Recorded: who did what, when └─ Complete history for compliance KNOWLEDGE (6) ├─ Embeddings & vectors ├─ Semantic search & RAG └─ AI understanding of relationships ``` --- ## Query Organization by Dimension ### Dimension 1: GROUPS (`convex/queries/groups.ts`) **Purpose**: Multi-tenant isolation with hierarchical nesting **Key Queries**: - `getBySlug(slug)` - URL-based routing - `getById(groupId)` - Direct lookup - `getSubgroups(parentGroupId)` - Direct children - `getHierarchy(rootGroupId)` - All descendants (recursive) - `getGroupPath(groupId)` - Breadcrumb trail to root - `isDescendantOf(groupId, ancestorGroupId)` - Permission checks - `getEntitiesInHierarchy()` - All things in group tree - `getConnectionsInHierarchy()` - All relationships in group tree - `getEventsInHierarchy()` - All actions in group tree - `getStats(groupId)` - Aggregate statistics - `search(groupId, query)` - Group search - `list(groupId)` - List all groups **Cross-Dimension Integration**: - Returns aggregate stats: entity count, connection count, event count, knowledge count - Supports hierarchical queries across organization structure ### Dimension 2: PEOPLE (`convex/queries/people.ts`) **Purpose**: Authorization and governance **Key Queries**: - `list(groupId)` - List members - `getById(personId)` - Get person details - `getRole(personId)` - Get authorization level - `listByRole(groupId, role)` - Filter by permission level **Cross-Dimension Integration**: - People are stored as entities with `type: "creator"` - Roles determine what operations they can perform - Referenced in events via `actorId` (who did what) ### Dimension 3: THINGS (`convex/queries/entities.ts`) **Purpose**: 66+ entity types (users, agents, content, tokens, courses, etc.) **Key Queries**: - `list(groupId, type?, status?, limit?)` - Flexible filtering - `getById(entityId)` - Direct lookup - `listByType(groupId, type)` - Filter by category - `listByStatus(groupId, status)` - Filter by workflow state - `search(groupId, query)` - Full-text search - `listRecent(groupId, limit)` - Timeline view - `getRelated(entityId)` - Connected entities - `getStats(groupId)` - Count statistics - `getProperties(entityId)` - Get entity properties **Cross-Dimension Integration**: - Things are the core nouns: every action affects a thing - Connected to people via relationships (owns, member_of, etc.) - Referenced in events via `targetId` - Linked to knowledge via `sourceThingId` ### Dimension 4: CONNECTIONS (`convex/queries/connections.ts`) **Purpose**: 25+ relationship types between entities **Key Queries**: - `listFrom(groupId, fromEntityId)` - Outgoing edges - `listTo(groupId, toEntityId)` - Incoming edges - `listBetween(groupId, fromEntityId, toEntityId)` - Bidirectional - `listByType(groupId, relationshipType)` - Filter by relationship **Supported Relationship Types**: - Ownership: `owns`, `member_of`, `part_of` - Authorship: `created_by`, `authored`, `generated_by`, `published_to` - Derivation: `clone_of`, `trained_on`, `references` - Social: `following`, `collaborates_with` - Financial: `holds_tokens`, `staked_in`, `earned_from`, `purchased`, `transacted` - Educational: `enrolled_in`, `teaching`, `completed` - Organizational: `manages`, `reports_to`, `moderates` - Communication: `communicated`, `notified`, `referred` - Governance: `delegated`, `approved`, `fulfilled` **Cross-Dimension Integration**: - Connect entities (things) to each other - Include metadata: timestamp, actor (person), strength, validity window - Used to compute: followers, collaborators, resource ownership, permissions ### Dimension 5: EVENTS (`convex/queries/events.ts`) **Purpose**: Complete audit trail (67+ event types) **Key Queries**: - `list(groupId, limit?)` - All events in group - `byActor(groupId, actorId)` - Events by person - `byTarget(groupId, targetId)` - Events affecting thing - `byTimeRange(groupId, startTime, endTime)` - Temporal filtering - `recent(groupId, limit)` - Most recent first - `stats(groupId)` - Count by event type - `getById(eventId)` - Get single event **Event Structure**: - `type`: Event category (entity_created, connection_established, purchase_completed, etc.) - `actorId`: Person who caused the event - `targetId`: Entity affected by the event - `timestamp`: When it happened - `metadata`: Event-specific data (amount, status transition, etc.) **Cross-Dimension Integration**: - Records when things change - Links people (who) to things (what) to time (when) - Powers activity feeds, notifications, analytics, compliance ### Dimension 6: KNOWLEDGE (`convex/queries/knowledge.ts`) **Purpose**: Vectors, embeddings, RAG, and semantic search **Key Queries**: - `list(groupId, limit?)` - All knowledge in group - `search(groupId, query, limit?)` - Semantic search by embedding - `bySourceThing(groupId, sourceThingId)` - Knowledge extracted from entity - `byThing(groupId, thingId)` - Knowledge linked to entity - `byLabel(groupId, label)` - Filter by tag/category - `listLabels(groupId)` - Available tags - `stats(groupId)` - Knowledge counts - `getById(knowledgeId)` - Get single knowledge item **Knowledge Structure**: - `content`: Text that's been vectorized - `embedding`: Numeric vector for similarity search - `labels`: Tags for categorization - `sourceThingId`: Where the knowledge came from - `metadata`: Custom fields (confidence score, model used, etc.) **Cross-Dimension Integration**: - Created from entities (content extraction) - Enables AI understanding of what exists and how it relates - Powers semantic search, recommendations, and RAG --- ## Complete Query Reference ### Summary Table: All 44 Queries | Dimension | Name | File | Count | |-----------|------|------|-------| | 1 | GROUPS | groups.ts | 12 | | 2 | PEOPLE | people.ts | 4 | | 3 | THINGS | entities.ts | 9 | | 4 | CONNECTIONS | connections.ts | 4 | | 5 | EVENTS | events.ts | 7 | | 6 | KNOWLEDGE | knowledge.ts | 8 | | - | ONTOLOGY | ontology.ts | - | ### DIMENSION 1: GROUPS (12) `getBySlug` | `getById` | `list` | `getSubgroups` | `getHierarchy` | `getGroupPath` | `isDescendantOf` | `getEntitiesInHierarchy` | `getConnectionsInHierarchy` | `getEventsInHierarchy` | `getStats` | `search` ### DIMENSION 2: PEOPLE (4) `list` | `getById` | `getRole` | `listByRole` ### DIMENSION 3: ENTITIES/THINGS (9) `list` | `getById` | `listByType` | `listByStatus` | `search` | `listRecent` | `getStats` | `getRelated` | `getProperties` ### DIMENSION 4: CONNECTIONS (4) `listFrom` | `listTo` | `listBetween` | `listByType` ### DIMENSION 5: EVENTS (7) `list` | `byActor` | `byTarget` | `byTimeRange` | `stats` | `recent` | `getById` ### DIMENSION 6: KNOWLEDGE (8) `list` | `search` | `bySourceThing` | `byThing` | `byLabel` | `listLabels` | `stats` | `getById` --- ## Query Naming Conventions All queries follow this consistent pattern: ``` get<Singular> - Single entity by ID getBy<Field> - Single entity by specific field list - Multiple entities with filters list<Plural> - Multiple entities of specific type by<Dimension> - Filter by dimension (byActor, byTarget, byType) <Verb> - Action queries (search, stats, isDescendantOf) ``` ### Examples - `getById()` - Get one entity by ID - `getBySlug()` - Get one entity by slug field - `list()` - Get multiple entities with optional filters - `listByType()` - Get entities filtered by type - `byActor()` - Get events filtered by actor - `search()` - Full-text or semantic search - `stats()` - Count aggregations --- ## Multi-Tenancy Pattern **CRITICAL**: Every query filters by `groupId` for data isolation. ### Standard Query Pattern ```typescript // All queries follow this pattern: export const list = query({ args: { groupId: v.id("groups"), // REQUIRED for isolation type: v.optional(v.string()), limit: v.optional(v.number()), }, handler: async (ctx, args) => { const results = await ctx.db .query("entities") .withIndex("group_type", (q) => q.eq("groupId", args.groupId) // Filter first ) .collect(); return results; } }); ``` ### Why This Matters - **Data Isolation**: Perfect separation between groups (organizations) - **Security**: No data leaks if pattern is followed - **Performance**: Indexes make queries fast even with millions of records - **Multi-Tenancy**: Same schema, different data per group --- ## Performance Optimization ### Indexes Used 1. **group_type**: Filter by group + type (entities, connections, events, knowledge) 2. **group_status**: Filter by group + status (entities, connections) 3. **from_entity**: Outgoing relationships (connections) 4. **to_entity**: Incoming relationships (connections) 5. **by_created**: Activity timelines (entities, events) 6. **by_updated**: Recent changes (entities, connections) 7. **by_actor**: Activity by person (events) 8. **by_target**: Activity affecting entity (events) ### Query Tips 1. **Always filter by groupId first** - Massive performance improvement 2. **Use indexes** - See `withIndex()` in queries for available indexes 3. **Limit large result sets** - Use `limit` parameter for pagination 4. **Recurse carefully** - Use `maxDepth`/`maxIterations` to prevent infinite loops 5. **Denormalize stats** - Pre-compute counts in mutations if possible ### Performance Checklist Before shipping a query: - [ ] Filters by `groupId` first - [ ] Uses an index (documented in comments) - [ ] Has reasonable result limits - [ ] Has JSDoc documentation - [ ] Tested with different group IDs - [ ] Performance acceptable (< 1s for most queries) --- ## Practical Examples ### Example 1: Show All Followers ```typescript // Query DIMENSION 4 (CONNECTIONS) const followers = await ctx.runQuery(api.queries.connections.listTo, { groupId: groupId, // CRITICAL: Filter by group toEntityId: creatorId, // Who we're finding followers of relationshipType: "following" }); // Returns: All entities that have "following" relationship TO this creator ``` ### Example 2: Get Recent Activity in a Group ```typescript // Query DIMENSION 5 (EVENTS) const recent = await ctx.runQuery(api.queries.events.recent, { groupId: groupId, // CRITICAL: Filter by group limit: 20 }); // Returns: Last 20 events ordered by timestamp DESC ``` ### Example 3: Find Similar Articles ```typescript // Query DIMENSION 6 (KNOWLEDGE) const similar = await ctx.runQuery(api.queries.knowledge.search, { groupId: groupId, // CRITICAL: Filter by group query: articleEmbedding, limit: 10 }); // Returns: 10 most similar articles by semantic similarity ``` ### Example 4: Show All Collaborators of a Creator ``` 1. Get creator (THINGS) entities query 2. Find all CONNECTIONS where relationshipType = "collaborates_with" 3. For each connection, get the other person (PEOPLE) 4. Return list of people ``` ### Example 5: Show Activity Feed for This User ``` 1. Get user (PEOPLE) 2. Query EVENTS where actorId = user._id 3. For each event, join THINGS (targetId) for context 4. Return timeline of what this user did ``` ### Example 6: Find Similar Articles via Knowledge ``` 1. Get article (THINGS) 2. Get article's knowledge/embeddings (KNOWLEDGE) 3. Search for similar embeddings (semantic search) 4. Return THINGS that match similar knowledge ``` ### React Component with Convex Hooks ```typescript // frontend/src/components/features/EntityList.tsx import { useQuery } from "convex/react"; import { api } from "@/convex/_generated/api"; export function EntityList({ groupId, type }: { groupId: string; type: string }) { const entities = useQuery(api.queries.entities.list, { groupId, type }); if (entities === undefined) return <div>Loading...</div>; return ( <div> {entities.map((entity) => ( <div key={entity._id}>{entity.name}</div> ))} </div> ); } ``` ### Astro Page with SSR ```astro --- // frontend/src/pages/groups/[groupId]/entities/[type].astro import { ConvexHttpClient } from "convex/browser"; import { api } from "@/convex/_generated/api"; import EntityList from "@/components/features/EntityList"; const convex = new ConvexHttpClient(import.meta.env.PUBLIC_CONVEX_URL); const entities = await convex.query(api.queries.entities.list, { groupId: Astro.params.groupId, type: Astro.params.type }); --- <Layout> <h1>{Astro.params.type} Entities</h1> <EntityList client:load groupId={Astro.params.groupId} type={Astro.params.type} /> </Layout> ``` --- ## Ontology Runtime Discovery ### Available Queries The `ontology.ts` file provides runtime feature discovery for dynamic UI composition: ```typescript // Get complete ontology information api.queries.ontology.getOntology() // Get ontology metadata (counts, generation time) api.queries.ontology.getMetadata() // Get specific dimension types api.queries.ontology.getThingTypes() api.queries.ontology.getConnectionTypes() api.queries.ontology.getEventTypes() // Get enabled features api.queries.ontology.getEnabledFeatures() // Check if specific feature is enabled api.queries.ontology.hasFeature({ feature: "blog" }) // Get detailed feature breakdown api.queries.ontology.getFeatureBreakdown() ``` ### Example Backend Usage ```typescript // In a Convex function import { query } from "./_generated/server"; import { api } from "./_generated/api"; export const listAvailableContent = query({ args: {}, handler: async (ctx) => { // Check if blog feature is enabled const hasBlog = await ctx.runQuery(api.queries.ontology.hasFeature, { feature: "blog" }); // Get all thing types const thingTypes = await ctx.runQuery(api.queries.ontology.getThingTypes); return { hasBlog, availableContentTypes: thingTypes.filter(type => ["blog_post", "page", "project", "product"].includes(type) ) }; } }); ``` ### Frontend Feature Detection ```tsx import { useOntology, useHasFeature } from "@/hooks/useOntology"; function NavigationMenu() { const { hasFeature, isLoading } = useOntology(); if (isLoading) return <div>Loading...</div>; return ( <nav> <a href="/">Home</a> {hasFeature('blog') && <a href="/blog">Blog</a>} {hasFeature('portfolio') && <a href="/portfolio">Portfolio</a>} {hasFeature('shop') && <a href="/shop">Shop</a>} </nav> ); } ``` ### Dynamic Type Selectors ```tsx import { useThingTypes } from "@/hooks/useOntology"; function CreateThingForm() { const thingTypes = useThingTypes(); const [selectedType, setSelectedType] = useState(""); return ( <form> <label>Thing Type</label> <select value={selectedType} onChange={(e) => setSelectedType(e.target.value)}> <option value="">Select type...</option> {thingTypes.map(type => ( <option key={type} value={type}> {type.replace('_', ' ').toUpperCase()} </option> ))} </select> </form> ); } ``` ### Astro Server-Side Usage ```astro --- // src/pages/admin/ontology.astro import { ConvexHttpClient } from "convex/browser"; import { api } from "@/convex/_generated/api"; const convex = new ConvexHttpClient(import.meta.env.PUBLIC_CONVEX_URL); const ontology = await convex.query(api.queries.ontology.getOntology); const breakdown = await convex.query(api.queries.ontology.getFeatureBreakdown); --- <Layout title="Ontology Configuration"> <h1>Ontology Composition</h1> <section> <h2>Enabled Features</h2> <ul> {ontology.features.map(feature => ( <li>{feature}</li> ))} </ul> </section> <section> <h2>Available Types</h2> <div> <h3>Things ({ontology.thingTypes.length})</h3> <p>{ontology.thingTypes.join(', ')}</p> </div> <div> <h3>Connections ({ontology.connectionTypes.length})</h3> <p>{ontology.connectionTypes.join(', ')}</p> </div> <div> <h3>Events ({ontology.eventTypes.length})</h3> <p>{ontology.eventTypes.join(', ')}</p> </div> </section> </Layout> ``` ### Advanced: Feature Breakdown ```tsx import { useFeatureBreakdown } from "@/hooks/useOntology"; function FeatureExplorer() { const breakdown = useFeatureBreakdown(); if (!breakdown) return <div>Loading...</div>; return ( <div className="feature-explorer"> {Object.entries(breakdown).map(([featureName, feature]) => { if (!feature) return null; return ( <div key={featureName} className="feature-card"> <h3>{featureName}</h3> <p>{feature.description}</p> <div className="feature-details"> <div> <h4>Thing Types ({feature.thingTypes.length})</h4> <ul> {feature.thingTypes.map(type => ( <li key={type}>{type}</li> ))} </ul> </div> <div> <h4>Connection Types ({feature.connectionTypes.length})</h4> <ul> {feature.connectionTypes.map(type => ( <li key={type}>{type}</li> ))} </ul> </div> <div> <h4>Event Types ({feature.eventTypes.length})</h4> <ul> {feature.eventTypes.map(type => ( <li key={type}>{type}</li> ))} </ul> </div> </div> </div> ); })} </div> ); } ``` --- ## Adding New Queries ### Step 1: Identify the Dimension Which of the 6 dimensions does this query serve? - Groups → `queries/groups.ts` - People → `queries/people.ts` - Things → `queries/entities.ts` - Relationships → `queries/connections.ts` - Audit/Timeline → `queries/events.ts` - AI/Search → `queries/knowledge.ts` ### Step 2: Follow the Pattern ```typescript /** * Description of what this query does * * Use case: when/why you'd use this * Performance: which index is used */ export const myQuery = query({ args: { groupId: v.id("groups"), // ALWAYS include myParam: v.string(), }, handler: async (ctx, args) => { // Filter by groupId first (performance + security) const results = await ctx.db .query("myTable") .withIndex("by_group", q => q.eq("groupId", args.groupId)) .collect(); return results; } }); ``` ### Step 3: Document It 1. Add JSDoc comment (see step 2 above) 2. Add to `queries/README.md` 3. Add to `convex/INDEX.md` ### Step 4: Test It 1. Verify groupId filtering works 2. Test index performance 3. Ensure isolation ### Step 5: Update This Reference Add your query to the appropriate dimension section in this document. --- ## Key Principles ### 🔒 Multi-Tenancy (CRITICAL) - Every query filters by `groupId` first - Perfect data isolation between groups - No data leaks possible if pattern is followed ### 🎯 Consistency - All queries follow same naming convention - All use same multi-tenancy pattern - All have JSDoc documentation ### 📊 Completeness - All 6 dimensions have full query coverage - Cross-dimension queries available - Aggregate queries for stats and search ### 🚀 Performance - Indexes documented in each query - Fast path identified for common queries - Tips for optimizing recursive queries ### 📚 Discoverability - Comprehensive documentation at multiple levels - Code examples for each pattern - Clear naming conventions --- ## File Locations - **Backend Queries**: `/Users/toc/Server/ONE/backend/convex/queries/` - **Groups**: `/Users/toc/Server/ONE/backend/convex/queries/groups.ts` - **People**: `/Users/toc/Server/ONE/backend/convex/queries/people.ts` - **Entities**: `/Users/toc/Server/ONE/backend/convex/queries/entities.ts` - **Connections**: `/Users/toc/Server/ONE/backend/convex/queries/connections.ts` - **Events**: `/Users/toc/Server/ONE/backend/convex/queries/events.ts` - **Knowledge**: `/Users/toc/Server/ONE/backend/convex/queries/knowledge.ts` - **Ontology Discovery**: `/Users/toc/Server/ONE/backend/convex/queries/ontology.ts` - **Frontend Hook**: `/Users/toc/Server/ONE/web/src/hooks/useOntology.ts` - **Ontology Types**: `/Users/toc/Server/ONE/backend/convex/types/ontology.ts` - **Schema**: `/Users/toc/Server/ONE/backend/convex/schema.ts` --- ## Quick Reference: Documentation Structure ### For New Developers **"I want to understand the system"** Start with: `convex/INDEX.md` (master reference) Then read: `ONTOLOGY_VISUAL_GUIDE.md` (visual flow) **"I want to add a new query"** Read: This document "Adding New Queries" section Copy pattern from existing query in the same dimension Update `queries/README.md` with new query **"I want to understand one dimension"** Open the dimension file: `queries/groups.ts` (etc.) Read the header documentation Check `convex/INDEX.md` for the complete reference table ### For Code Review **"Is this query following the pattern?"** - Does it filter by `groupId`? - Does it use an index? - Is the name following conventions? - Does it have JSDoc? - Is it in the right dimension file? --- ## Remember **Groups partition People authorize Things exist Connections relate Events record Knowledge understands.** Every query should cleanly fit into one of these 6 dimensions. If it doesn't, reconsider the approach. --- **See Also**: - `/one/knowledge/ontology.md` - Complete 6-dimension specification - `convex/mutations/` - Write operations following same structure - `convex/schema.ts` - Database schema matching this ontology - `convex/queries/README.md` - Quick reference lookup table - `convex/INDEX.md` - Master backend reference --- **Built with the 6-dimension ontology. Runtime feature discovery enables dynamic, composition-aware UIs.**