# DevOS Data / Query / Search / Index Runtime > Document: 14 > Status: Required > Audience: Zcode / DevOS Core Team > Depends On: > - 03_RESOURCE_ACTION_MODEL.md > - 06_MCP_SKILL_AGENT_RUNTIME.md > - 09_TASK_JOB_QUEUE_RUNTIME.md > - 12_MIGRATION_VERSIONING_COMPATIBILITY.md > - 13_DEPLOYMENT_ENVIRONMENT_CONFIG_RUNTIME.md --- # 1. Goals DevOS 已经拥有: - Resource - Action - Event - Agent - Skill - MCP - Task - Job - Queue - Worker - Configuration - Environment - Deployment 下一步必须解决: > DevOS 中的数据应该如何被统一访问、查询、过滤、排序、搜索、聚合和索引? 否则最终会出现: ```text UI → Prisma Plugin → Prisma Agent → Prisma MCP → Prisma Action → Prisma Search → Elasticsearch Plugin Search → 自己实现 ```` 最终形成多个数据访问体系。 本 Document 要建立: ```text Data Runtime Query Runtime Repository Runtime Search Runtime Index Runtime Filter Runtime Pagination Runtime Relation Runtime ``` 最终原则: ```text Resource ↓ Data Definition ↓ Repository / Query ↓ Data Runtime ↓ Database / Search Index ``` --- # 2. Core Principle DevOS 必须区分: ```text Resource Data Query Search Index Action ``` 它们不是同一个东西。 --- # 3. Resource Resource 表示: > 系统中的业务对象。 例如: ```text core.user core.organization core.project core.task seo.website seo.article devops.server devops.deployment ``` --- # 4. Data Data 表示: > Resource 当前保存的数据。 例如: ```json { "id": "website_123", "domain": "example.com", "status": "active" } ``` --- # 5. Query Query 表示: > 从结构化数据中获取数据。 例如: ```text 所有 active website 最近创建的 20 个 Task 某个 Organization 的 Users ``` --- # 6. Search Search 表示: > 根据文本、语义、字段权重等进行相关性检索。 例如: ```text 搜索: "关于 AI SEO 的文章" 返回: Article 1 Article 2 Website 3 Task 4 ``` --- # 7. Index Index 表示: > 为 Query / Search 提供高效读取结构。 数据库 Index: ```text B-Tree GIN GiST ``` 搜索 Index: ```text Full Text Vector Hybrid ``` --- # 8. Architecture ```text Resource │ Resource Schema │ ┌────────────┴────────────┐ │ │ Data Runtime Search Runtime │ │ Repository Runtime Index Runtime │ │ ┌─────┴──────┐ ┌───────┴───────┐ │ │ │ │ PostgreSQL Cache Full Text Vector Index Index ``` --- # 9. Data Runtime 统一入口: ```ts export interface DataRuntime { repository( resource: string, context: DataContext ): Repository query( resource: string, query: QueryInput, context: DataContext ): Promise> count( resource: string, query: QueryInput, context: DataContext ): Promise exists( resource: string, query: QueryInput, context: DataContext ): Promise } ``` --- # 10. DataContext 所有数据访问必须携带 Context。 ```ts export interface DataContext { requestId: string actor: Actor organizationId?: string projectId?: string environmentId?: string permissions: string[] metadata?: Record } ``` 禁止: ```ts repository.findMany() ``` 在没有: ```text actor organization scope ``` 的情况下访问业务数据。 --- # 11. Repository Repository 是 Resource 的结构化数据访问接口。 ```ts export interface Repository { findById( id: string ): Promise findMany( query: QueryInput ): Promise> count( query: QueryInput ): Promise exists( query: QueryInput ): Promise } ``` 注意: Repository 默认只负责: ```text 读取 ``` 写入仍然应该通过: ```text Action Runtime ``` --- # 12. Important Rule 禁止: ```text UI ↓ Repository ↓ UPDATE database ``` 应该: ```text UI ↓ Action ↓ Action Runtime ↓ Repository / Domain Service ↓ Database ``` --- # 13. Read vs Write DevOS 可以采用: ```text CQRS-lite ``` 即: ```text Read ↓ Query / Repository Write ↓ Action Runtime ``` 不需要一开始实现完整 CQRS/Event Sourcing。 --- # 14. Query Input ```ts export interface QueryInput { select?: string[] filter?: FilterNode sort?: SortRule[] pagination?: PaginationInput include?: IncludeRule[] search?: SearchInput groupBy?: string[] aggregates?: AggregateRule[] distinct?: boolean } ``` --- # 15. Filter Filter 是 DevOS 非常重要的统一抽象。 例如: ```text status = active ``` ```ts { field: 'status', operator: 'eq', value: 'active' } ``` --- # 16. Filter Operators 至少支持: ```text eq neq gt gte lt lte in notIn contains startsWith endsWith isNull isNotNull between exists ``` --- # 17. Filter Tree 复杂查询: ```text status = active AND ( score > 80 OR backlinks > 100 ) ``` 表示: ```ts { and: [ { field: 'status', operator: 'eq', value: 'active' }, { or: [ { field: 'score', operator: 'gt', value: 80 }, { field: 'backlinks', operator: 'gt', value: 100 } ] } ] } ``` --- # 18. Filter Schema ```ts export type FilterNode = | FilterCondition | FilterGroup export interface FilterCondition { field: string operator: | 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'notIn' | 'contains' | 'startsWith' | 'endsWith' | 'isNull' | 'isNotNull' | 'between' value?: unknown } export interface FilterGroup { and?: FilterNode[] or?: FilterNode[] not?: FilterNode } ``` --- # 19. Security: Filter Fields 用户不能任意查询数据库字段。 Resource 必须声明: ```ts export interface FieldDefinition { name: string type: FieldType readable?: boolean writable?: boolean searchable?: boolean sortable?: boolean filterable?: boolean sensitive?: boolean } ``` 例如: ```text passwordHash ``` 必须: ```text readable = false searchable = false filterable = false ``` --- # 20. Field Types 至少: ```text string text integer float decimal boolean date datetime json uuid enum relation array ``` 未来: ```text vector geometry binary ``` --- # 21. Resource Schema Resource 应定义 Schema: ```ts export interface ResourceSchema { resource: string version: string fields: FieldDefinition[] relations?: RelationDefinition[] indexes?: IndexDefinition[] search?: SearchDefinition validation?: unknown } ``` --- # 22. Resource Schema Example ```ts const websiteSchema: ResourceSchema = { resource: 'seo.website', version: '1.0', fields: [ { name: 'id', type: 'uuid', readable: true }, { name: 'domain', type: 'string', readable: true, searchable: true, sortable: true, filterable: true }, { name: 'status', type: 'enum', readable: true, filterable: true, sortable: true } ] } ``` --- # 23. Pagination 统一支持: ```text offset pagination cursor pagination ``` --- # 24. Offset Pagination ```ts export interface OffsetPagination { type: 'offset' page: number pageSize: number } ``` 返回: ```ts { items: [], page: 1, pageSize: 20, total: 1234 } ``` 适合: ```text Admin UI Reports Tables ``` --- # 25. Cursor Pagination ```ts export interface CursorPagination { type: 'cursor' cursor?: string limit: number direction?: 'forward' | 'backward' } ``` 返回: ```ts { items: [], nextCursor: '...', hasMore: true } ``` 适合: ```text Agent Activity Feed Events Logs Large datasets ``` --- # 26. Pagination Limits 系统必须限制: ```text maxPageSize maxOffset maxQueryCost ``` 默认: ```text pageSize <= 100 ``` Agent / MCP: ```text 更严格 ``` 禁止: ```text pageSize = 1000000 ``` --- # 27. Sort ```ts export interface SortRule { field: string direction: 'asc' | 'desc' } ``` 例如: ```text createdAt desc score desc domain asc ``` --- # 28. Sort Security 只有: ```text sortable = true ``` 的字段才能排序。 禁止用户: ```text ORDER BY arbitrary SQL ``` --- # 29. Include 支持 Resource Relation: ```text Task └── Jobs ``` 查询: ```ts { include: [ { relation: 'jobs' } ] } ``` 但是必须防止: ```text N+1 query ``` --- # 30. Relations 统一: ```ts export interface RelationDefinition { name: string target: string type: | 'one' | 'many' foreignKey?: string targetKey?: string readable?: boolean } ``` --- # 31. Relation Examples ```text core.organization └── users core.task └── jobs core.job └── executions seo.website └── articles ``` --- # 32. Relation Permission Relation 也需要权限。 例如: ```text User ``` 可以看到: ```text Organization ``` 但不能自动: ```text Organization ↓ all users ``` 除非: ```text relation.read ``` 允许。 --- # 33. Query Authorization Query Runtime 必须执行: ```text Actor Permission + Resource Permission + Field Permission + Scope Policy + Filter Policy ``` 最终才生成: ```text Database Query ``` --- # 34. Row-Level Security 某些 Resource 需要 Row Scope。 例如: ```text organizationId = currentOrganization ``` 必须由 Runtime 自动注入。 不能依赖前端: ```text ?organizationId=xxx ``` --- # 35. Scope Provider ```ts export interface ScopeProvider { resolve( resource: string, context: DataContext ): Promise } ``` 例如: ```text core.task ``` 自动添加: ```text organizationId = currentOrganization ``` --- # 36. Scope Composition 最终: ```text User Filter AND Organization Scope AND Project Scope AND Environment Scope AND Policy Scope ``` 例如: ```text User: status = failed System: organizationId = org_1 Project: projectId = project_2 ``` 最终: ```text status = failed AND organizationId = org_1 AND projectId = project_2 ``` --- # 37. Query Compilation Query Runtime: ```text QueryInput ↓ Validate ↓ Authorize ↓ Inject Scope ↓ Resolve Relations ↓ Optimize ↓ Compile ↓ Database Query ``` --- # 38. SQL Boundary 禁止: ```text Agent Plugin MCP UI ``` 直接发送: ```text raw SQL ``` 只有: ```text Data Runtime ``` 可以执行 SQL。 --- # 39. Raw SQL Core 可以在极少数 Infrastructure 场景使用: ```ts data.rawQuery(...) ``` 但必须: ```text internal only ``` 不能暴露: ```text MCP REST Agent Plugin public API ``` --- # 40. Query Cost 每一个 Query 应估算成本: ```ts export interface QueryCost { estimatedRows: number joins: number sortCost: number searchCost: number totalScore: number } ``` 高成本 Query: ```text reject ``` 或: ```text require async Task ``` --- # 41. Large Query 例如: ```text 导出 100 万条数据 ``` 不能: ```text HTTP Request ↓ Query ↓ return 1M rows ``` 应该: ```text Export Action ↓ Task ↓ Job ↓ Worker ↓ Cursor Query ↓ Artifact ``` --- # 42. Data Export 统一 Resource: ```text core.export ``` Action: ```text core.export.create core.export.cancel core.export.download ``` 支持: ```text CSV JSON JSONL Excel ``` --- # 43. Export Security Export 必须使用: ```text same permission same scope same field security ``` 不能: ```text UI Query ``` 没有权限: ```text passwordHash ``` 但: ```text Export ``` 却把它导出来。 --- # 44. Search Runtime 统一: ```ts export interface SearchRuntime { search( resource: string, input: SearchInput, context: DataContext ): Promise> suggest( resource: string, input: SuggestInput, context: DataContext ): Promise } ``` --- # 45. Search Input ```ts export interface SearchInput { query: string fields?: string[] filter?: FilterNode sort?: SortRule[] pagination?: PaginationInput mode?: | 'fulltext' | 'semantic' | 'hybrid' minScore?: number } ``` --- # 46. Search Modes ## Full Text ```text keyword token phrase field weight ``` ## Semantic ```text embedding vector similarity ``` ## Hybrid ```text Full Text + Vector + Ranking ``` DevOS 推荐最终: ```text hybrid ``` --- # 47. Search Provider 抽象: ```ts export interface SearchProvider { index( document: SearchDocument ): Promise delete( id: string ): Promise search( input: SearchProviderInput ): Promise health(): Promise } ``` --- # 48. Search Provider Implementations 第一阶段: ```text PostgreSQL Full Text ``` 可选: ```text OpenSearch Elasticsearch Meilisearch Typesense ``` Vector: ```text pgvector ``` 优先使用: ```text PostgreSQL + pgvector ``` 减少基础设施复杂度。 --- # 49. Search Index Resource 可以声明: ```ts export interface SearchDefinition { enabled: boolean fields: SearchField[] provider?: string vector?: { enabled: boolean dimensions: number model?: string } } ``` --- # 50. Search Field ```ts export interface SearchField { field: string weight?: number searchable?: boolean vectorizable?: boolean stored?: boolean } ``` 例如: ```text title weight=10 description weight=5 content weight=2 ``` --- # 51. Search Document ```ts export interface SearchDocument { id: string resource: string resourceId: string fields: Record text?: string vector?: number[] metadata?: Record version: string indexedAt: Date } ``` --- # 52. Index Isolation Index 必须包含: ```text organizationId projectId environmentId resource ``` 防止: ```text Org A ``` 搜索到: ```text Org B ``` 的数据。 --- # 53. Search Permission 搜索结果必须再次执行: ```text Permission + Scope ``` 不能认为: ```text Index = authorized data ``` 因为权限可能发生变化。 --- # 54. Search Flow ```text User ↓ Search Action ↓ Search Runtime ↓ Permission ↓ Scope ↓ Search Provider ↓ Result ↓ Permission Recheck ↓ Return ``` --- # 55. Search Ranking 基础: ```text text relevance field weight freshness exact match ``` 未来: ```text business score authority quality user preference ``` --- # 56. Hybrid Ranking 例如: ```text finalScore = textScore * 0.4 + vectorScore * 0.4 + businessScore * 0.2 ``` 权重必须由: ```text Search Definition ``` 定义。 --- # 57. Semantic Search Agent 可以: ```text 搜索: “寻找高质量 AI SEO 文章” ``` 转换: ```text embedding ↓ vector search ↓ metadata filter ↓ ranking ``` --- # 58. Agent Search Agent 不应该获取: ```text 10000 records ``` 而应该: ```text Search Runtime ↓ topK ``` 例如: ```text topK = 10 ``` --- # 59. Capability Discovery Search 结合: ```text 06_MCP_SKILL_AGENT_RUNTIME.md ``` Capability Registry 也可以使用: ```text Search Runtime ``` 搜索: ```text Capability Skill Plugin MCP Action ``` --- # 60. Search as Capability Search 本身也是: ```text Capability ``` 例如: ```text core.search ``` 但 Agent 获取搜索能力时: ```text Search ``` 必须根据: ```text Permission Scope Budget ``` 限制。 --- # 61. Index Lifecycle Index 状态: ```text pending building ready degraded rebuilding failed ``` --- # 62. Index Resource ```text core.searchIndex ``` ```ts export interface SearchIndex { id: string resource: string provider: string status: | 'pending' | 'building' | 'ready' | 'degraded' | 'rebuilding' | 'failed' documentCount: number version: string lastIndexedAt?: Date error?: string } ``` --- # 63. Index Actions ```text core.searchIndex.create core.searchIndex.rebuild core.searchIndex.pause core.searchIndex.resume core.searchIndex.delete core.searchIndex.health ``` --- # 64. Rebuild Index 重建必须: ```text Task ↓ Job ↓ Worker ↓ Cursor Query ↓ Batch Index ``` 不能: ```text HTTP Request ↓ 全部读取 ↓ 全部 Index ``` --- # 65. Incremental Index Resource 数据变化时: ```text Resource Changed ↓ Event ↓ Index Job ↓ Update Index ``` 例如: ```text seo.website.updated ``` 触发: ```text search.index.update ``` --- # 66. Outbox 数据库写入: ```text Transaction ├── Update Resource └── Insert Outbox Event ``` 然后: ```text Outbox ↓ Worker ↓ Search Index ``` 防止: ```text DB updated but index not updated ``` --- # 67. Index Consistency DevOS 默认: ```text Database = Source of Truth Search Index = Derived State ``` 因此: ```text Index corrupted ``` 可以: ```text Rebuild ``` 而不会丢失业务数据。 --- # 68. Cache Runtime Data Runtime 可以使用: ```text Cache Runtime ``` ```ts export interface CacheRuntime { get(key: string): Promise set( key: string, value: T, options?: CacheOptions ): Promise delete(key: string): Promise invalidate(prefix: string): Promise } ``` --- # 69. Cache Rules 缓存只能是: ```text derived data ``` 不能作为: ```text source of truth ``` --- # 70. Cache Key 必须包含: ```text resource query scope configuration version ``` 例如: ```text devos: query: seo.website: org_1: hash(...) ``` 避免: ```text Org A cache ``` 被: ```text Org B ``` 使用。 --- # 71. Query Cache Invalidation Resource 更新: ```text Action ↓ Event ↓ Cache Invalidation ``` 例如: ```text seo.website.updated ``` 触发: ```text invalidate seo.website ``` --- # 72. Data Loader 防止 N+1: ```ts export interface DataLoader { load(key: K): Promise loadMany(keys: K[]): Promise } ``` Relation Runtime 应使用: ```text batch loading ``` --- # 73. Query Observability 每个 Query 记录: ```text requestId resource operation duration rows queryCost cacheHit provider ``` 不能记录: ```text Secret Sensitive values ``` --- # 74. Slow Query Detection 配置: ```text query.slowThresholdMs ``` 例如: ```text > 500ms ``` 产生: ```text core.query.slow ``` Event / Metric。 --- # 75. Query Timeout 每个 Query 必须有: ```text timeout ``` 例如: ```ts { timeoutMs: 5000 } ``` 超时: ```text cancel ``` 而不是无限等待。 --- # 76. Query Cancellation Data Runtime 必须支持: ```ts interface QueryOptions { signal?: AbortSignal } ``` Agent / Task 取消时: ```text Agent ↓ Task Cancel ↓ Job Cancel ↓ Query Abort ``` --- # 77. Query Transactions 复杂 Action: ```text Action ↓ Transaction ├── read ├── validate ├── write └── event ``` Transaction 生命周期不能跨: ```text HTTP request Task Worker Agent iteration ``` 过长时间。 --- # 78. Optimistic Lock 需要支持: ```ts version updatedAt ``` 例如: ```text Update Website where id=123 and version=4 ``` 成功: ```text version=5 ``` 失败: ```text Conflict ``` --- # 79. Data Conflict 返回: ```ts export interface DataConflictError { type: 'conflict' resource: string resourceId: string expectedVersion: number actualVersion: number } ``` UI: ```text 数据已被其他用户修改。 ``` Agent: ```text re-read → re-plan ``` --- # 80. Soft Delete Resource 可以定义: ```ts deletion: { strategy: | 'hard' | 'soft' } ``` Soft delete: ```text deletedAt ``` 默认 Query: ```text deletedAt IS NULL ``` --- # 81. Restore Soft Delete Resource: ```text restore ``` Action: ```text resource.restore ``` 必须重新经过: ```text Authorization Scope Validation ``` --- # 82. Archive Archive 和 Delete 必须区分: ```text active archived deleted ``` Archive: ```text 仍然存在 但默认不出现在普通 Query ``` --- # 83. Data Lifecycle Resource 可以定义: ```ts export interface DataLifecycle { retentionDays?: number archiveAfterDays?: number deleteAfterDays?: number } ``` 例如: ```text Execution ├── 30 days → archive └── 180 days → delete ``` --- # 84. Lifecycle Worker 数据生命周期由: ```text Scheduler ↓ Task ↓ Job ↓ Worker ``` 执行。 禁止: ```text API startup ↓ delete old records ``` --- # 85. Data Retention Policy Production 必须支持: ```text Audit retention Execution retention Log retention Artifact retention Event retention ``` 不同类型可以独立配置。 --- # 86. Privacy 未来如果系统保存用户个人数据: Resource 必须声明: ```ts privacy?: { pii: boolean fields?: string[] retentionDays?: number } ``` PII 字段: ```text redaction access policy export policy ``` 必须更严格。 --- # 87. Data Masking 支持: ```text email phone address token credential ``` 显示: ```text u***@example.com ``` 而不是: ```text full value ``` --- # 88. Generic CRUD 对于简单 Resource: ```text list get create update delete ``` 可以自动生成。 但是: ```text Generic CRUD ``` 只能作为: ```text Resource Action Generator ``` 不能绕过: ```text Action Runtime ``` --- # 89. Resource Query API 推荐: ```text GET /api/resources/:resource GET /api/resources/:resource/:id POST /api/resources/:resource/query ``` 但必须: ```text Resource Registry ↓ Schema ↓ Permission ↓ Query Runtime ``` --- # 90. Generic Query Example ```json { "filter": { "and": [ { "field": "status", "operator": "eq", "value": "active" } ] }, "sort": [ { "field": "createdAt", "direction": "desc" } ], "pagination": { "type": "cursor", "limit": 20 } } ``` --- # 91. Generic Search API ```text POST /api/search ``` 请求: ```json { "resource": "seo.website", "query": "AI SEO", "mode": "hybrid", "limit": 10 } ``` 返回: ```json { "items": [], "nextCursor": "...", "totalApproximate": 100 } ``` --- # 92. Search Across Resources 支持: ```text POST /api/search/global ``` 例如: ```text query: "Cloudflare production" ``` 搜索: ```text Website Server Deployment Task Plugin Document ``` 但是必须: ```text permission filtered ``` --- # 93. Global Search Registry ```ts export interface GlobalSearchSource { resource: string priority: number searchableFields: string[] transform( item: unknown ): SearchDocument } ``` Plugin 可以注册: ```text global search source ``` --- # 94. Plugin Search Plugin 可以声明: ```ts search?: { enabled: boolean fields: SearchField[] } ``` 安装后: ```text Plugin ↓ Search Registry ↓ Global Search ``` 自动可搜索。 --- # 95. MCP Search MCP 可以调用: ```text core.search ``` 而不是: ```text MCP → Database ``` MCP 搜索: ```text permission + scope + budget ``` 必须全部有效。 --- # 96. Agent Query vs Search Agent 应优先: ```text Search ``` 而不是: ```text Query all ``` 例如: ```text 找 10 个最相关网站 ``` 使用: ```text Search topK=10 ``` 而不是: ```text Query all websites ``` --- # 97. Agent Structured Query 如果目标明确: ```text 查找 status=failed 的任务 ``` 使用: ```text Query ``` 而不是: ```text LLM semantic search ``` 规则: ```text Structured requirement → Query Natural language requirement → Search ``` --- # 98. Search Progressive Disclosure Agent Search Tool Schema: ```text Level 1: search(resource, query) Level 2: filters fields ranking Level 3: advanced search ``` 不要一次把: ```text 所有 Search Schema ``` 发送给模型。 --- # 99. Data Capability Data Runtime 暴露: ```text Query Search Count Exists Aggregate Export ``` 作为: ```text Capabilities ``` 例如: ```text core.resource.query core.resource.search core.resource.aggregate core.resource.export ``` --- # 100. Aggregate 支持: ```text count sum avg min max ``` 例如: ```text 统计: 过去 7 天失败 Task 数量 ``` 不要读取所有 Task: ```text Query all ↓ Agent count ``` 而应该: ```text Aggregate ``` --- # 101. Aggregate Definition ```ts export interface AggregateRule { field?: string function: | 'count' | 'sum' | 'avg' | 'min' | 'max' alias: string } ``` --- # 102. Group By 例如: ```text 按 status 统计 Task ``` ```ts { groupBy: ['status'], aggregates: [ { function: 'count', alias: 'count' } ] } ``` --- # 103. Aggregate Security Aggregate 也必须: ```text permission scope field policy ``` 例如: ```text salary ``` 不能因为: ```text AVG(salary) ``` 就绕过: ```text salary field permission ``` --- # 104. Query Builder UI 可以提供: ```text Filter Builder Sort Builder Group Builder Search ``` 例如: ```text Status [is] Failed AND Created At [after] 2026-09-01 ``` 最终生成: ```text QueryInput ``` --- # 105. Saved Query 用户可以保存: ```text Saved Query ``` Resource: ```text core.savedQuery ``` ```ts interface SavedQuery { id: string resource: string name: string query: QueryInput ownerId: string scope: 'private' | 'organization' | 'project' createdAt: Date } ``` --- # 106. Saved Search 类似: ```text core.savedSearch ``` 可以保存: ```text query filters sort columns ``` UI: ```text My Searches Team Searches ``` --- # 107. Query Preset Plugin 可以提供: ```text preset ``` 例如 SEO: ```text High Value Websites Broken Backlinks Low DR Websites Recently Scanned ``` 这些都是: ```text Saved Query / Query Preset ``` 而不是每个页面重新写 SQL。 --- # 108. Data Table DevOS UI 应提供: ```text Generic Resource Table ``` 支持: ```text columns filter sort pagination search selection bulk actions saved views export ``` --- # 109. Generic Resource Detail Resource Detail 页面可以自动生成: ```text Overview Fields Relations Activity Events Tasks Executions Artifacts ``` Plugin 可以扩展: ```text Custom Tabs Widgets Actions ``` --- # 110. Bulk Operations 大量操作: ```text Select 100 websites ↓ Bulk Action ``` 不能: ```text HTTP request ↓ for each ↓ execute synchronously ``` 必须: ```text Bulk Action ↓ Task ↓ Jobs ``` --- # 111. Bulk Job Expansion 例如: ```text 100 websites ``` 创建: ```text 1 Task + 100 Jobs ``` 而不是: ```text 100 Tasks ``` 符合: ```text 09_TASK_JOB_QUEUE_RUNTIME.md ``` --- # 112. Data Change Events Resource 数据发生变化: ```text created updated deleted restored archived ``` 事件: ```text core.resource.created core.resource.updated core.resource.deleted ``` Plugin 可以订阅。 --- # 113. Event Payload Event 不应该发送完整 Resource: ```text 巨大 Payload ``` 默认: ```ts interface ResourceChangedEvent { resource: string resourceId: string operation: 'created' | 'updated' | 'deleted' version: number changedFields?: string[] actorId: string timestamp: Date } ``` Consumer 如果需要: ```text Query Resource ``` 重新读取。 --- # 114. Search Index Event ```text Resource Updated ↓ Outbox ↓ Event ↓ Index Worker ↓ Search Index ``` 这样: ```text Database ``` 始终是: ```text Source of Truth ``` --- # 115. Reindex Safety Reindex 必须支持: ```text checkpoint resume retry pause cancel ``` 因此: ```text Task ``` 必须保存: ```text cursor processedCount failedCount ``` --- # 116. Search Provider Failure 如果: ```text OpenSearch ``` 挂了: 业务数据: ```text 仍然正常 ``` Search: ```text degraded ``` 可以: ```text fallback PostgreSQL search ``` 如果配置允许。 --- # 117. Search Fallback ```ts interface SearchPolicy { primary: string fallback?: string[] failMode: | 'fail' | 'fallback' } ``` --- # 118. Data Provider Data Runtime 也应该抽象: ```ts interface DataProvider { query(...) transaction(...) health(...) } ``` 默认: ```text PostgreSQL ``` 未来: ```text MySQL SQLite External API ``` 但 DevOS Core 推荐: ```text PostgreSQL first ``` --- # 119. External Resource 不是所有 Resource 都必须存在数据库。 例如: ```text GitHub Repository Cloudflare Zone AWS Server ``` 可以: ```text External Resource Provider ``` ```ts interface ExternalResourceProvider { get(id: string): Promise list(query: QueryInput): Promise> } ``` --- # 120. External Resource Cache 外部 Resource: ```text GitHub Repository ``` 可以缓存: ```text Database + Cache ``` 但: ```text External API ``` 仍然是真实来源。 --- # 121. Sync Runtime 外部 Resource 同步: ```text External API ↓ Sync Task ↓ Job ↓ Worker ↓ Resource ↓ Database ↓ Index ``` --- # 122. Sync Cursor 支持: ```text cursor etag updatedAt lastSyncAt ``` 减少: ```text API calls ``` --- # 123. Rate Limit Data Provider 必须支持: ```text rate limit retry backoff concurrency ``` 特别是: ```text GitHub Cloudflare AWS External APIs ``` --- # 124. Provider Resource Boundary Provider 不应该: ```text 直接修改核心数据库 ``` 应该: ```text Provider ↓ External Data ↓ Action ↓ Resource Repository ``` --- # 125. Search Embedding Provider Embedding 也作为: ```text Provider ``` 例如: ```text embedding.openai embedding.local ``` 接口: ```ts interface EmbeddingProvider { embed( input: string ): Promise embedBatch( inputs: string[] ): Promise dimensions(): number } ``` --- # 126. Embedding Task 大量数据 embedding: ```text Resource ↓ Index Task ↓ Batch Jobs ↓ Embedding Provider ↓ Vector Index ``` 不能: ```text API request ↓ 10000 embeddings ``` --- # 127. Token Budget Embedding / Search / LLM 查询也要计入: ```text Agent Budget ``` 尤其: ```text embedding calls external search calls ``` --- # 128. Search Budget Agent Search: ```ts interface SearchBudget { maxQueries: number maxResults: number maxExternalCalls: number maxEstimatedCost?: number } ``` --- # 129. Data Access Audit 敏感 Resource Query: ```text User ↓ Query ↓ Audit ``` 尤其: ```text User Credential Secret Metadata Billing Audit Organization ``` --- # 130. Query Audit Policy Resource Schema 可以定义: ```ts audit?: { read: boolean sensitiveRead: boolean export: boolean } ``` --- # 131. Data Access Observability Metrics: ```text devos_query_total devos_query_duration devos_query_errors devos_query_rows devos_query_cache_hit devos_search_total devos_search_duration devos_search_errors devos_index_documents devos_index_failures ``` --- # 132. Database Index Definition Resource Schema: ```ts interface IndexDefinition { name: string fields: string[] unique?: boolean type?: | 'btree' | 'gin' | 'gist' | 'hash' where?: string } ``` 禁止 Plugin 在 Runtime: ```text CREATE INDEX ``` Schema Migration 才能修改数据库结构。 --- # 133. Migration Integration 结合: ```text 12_MIGRATION_VERSIONING_COMPATIBILITY.md ``` 新增 Index: ```text Migration ``` 删除 Index: ```text Migration ``` 修改 Schema: ```text Migration ``` --- # 134. Schema Registry 统一: ```ts interface SchemaRegistry { register( schema: ResourceSchema ): void get( resource: string, version?: string ): ResourceSchema list(): ResourceSchema[] validate( resource: string, data: unknown ): ValidationResult } ``` --- # 135. Schema Versioning Resource: ```text seo.website ``` Schema: ```text 1.0 1.1 2.0 ``` 结合: ```text 12_MIGRATION_VERSIONING_COMPATIBILITY.md ``` 数据迁移必须可追踪。 --- # 136. API Schema Resource Schema 应自动生成: ```text REST schema OpenAPI schema MCP schema Agent tool schema UI schema TypeScript types ``` 减少重复定义。 --- # 137. Single Source of Truth 最终: ```text Resource Schema │ ┌─────┼─────┬─────┬─────┐ │ │ │ │ │ API UI MCP Agent DB ``` 不要: ```text API schema UI schema MCP schema Agent schema DB schema ``` 分别维护。 --- # 138. Query Schema Generation Resource Schema 自动生成: ```text Filter Fields Sort Fields Search Fields Selectable Fields Relation Fields ``` 这样 Generic UI 可以直接使用。 --- # 139. Plugin Example Plugin: ```text seo ``` 注册: ```text seo.website seo.article seo.backlink ``` 每个 Resource: ```text Schema Actions Relations Search Indexes UI metadata ``` 安装后自动进入: ```text Resource Registry Query Runtime Search Runtime Action Runtime UI Agent Capability Registry ``` --- # 140. SEO Example 用户: ```text 找出 DR > 50 且最近 30 天没有发布文章的网站 ``` Agent: ```text Goal ↓ Capability Discovery ↓ seo.website.search ↓ Query ↓ Filter ``` 最终: ```text DR > 50 AND lastArticleAt < now - 30d ``` 而不是: ```text Agent ↓ 读取所有网站 ↓ 自己计算 ``` --- # 141. Natural Language Query 未来支持: ```text “找出过去一周失败最多的 Worker” ``` 转换: ```text Natural Language ↓ Query Planner ↓ Resource ↓ Fields ↓ Filters ↓ Aggregates ↓ Query Runtime ``` 但是: ```text LLM generated query ``` 必须经过: ```text Schema Validation Permission Scope Cost Check ``` --- # 142. Query Planner 可以定义: ```ts interface QueryPlan { resource: string query: QueryInput explanation?: string estimatedCost?: QueryCost } ``` Agent 生成: ```text QueryPlan ``` Runtime 验证后执行。 --- # 143. Query Planner Safety LLM 不能生成: ```sql DROP TABLE ``` 也不能: ```text raw SQL ``` 只能生成: ```text QueryInput ``` --- # 144. Search Planner 同样: ```ts interface SearchPlan { resource: string input: SearchInput estimatedCost?: number } ``` --- # 145. Query Result 统一: ```ts interface QueryResult { items: T[] pagination?: PaginationResult total?: number aggregates?: Record metadata?: Record } ``` --- # 146. Search Result ```ts interface SearchResult { items: SearchItem[] nextCursor?: string total?: number tookMs: number } ``` ```ts interface SearchItem { item: T score?: number highlights?: Record } ``` --- # 147. Query Errors 统一错误: ```text invalid_filter invalid_field invalid_sort forbidden_field forbidden_resource scope_violation query_timeout query_too_expensive provider_unavailable ``` --- # 148. Search Errors ```text invalid_query unsupported_mode index_unavailable provider_unavailable search_timeout search_budget_exceeded ``` --- # 149. CLI 增加: ```bash devos data resources devos data schema seo.website devos data query seo.website devos data count seo.website devos data export seo.website devos search "AI SEO" devos search "AI SEO" --resource seo.website devos index list devos index rebuild seo.website devos index health ``` --- # 150. UI DevOS 应提供: ```text Resource Explorer ``` 例如: ```text Resources ├── Core │ ├── Users │ ├── Organizations │ ├── Tasks │ ├── Jobs │ └── Executions │ └── Plugins └── SEO ├── Websites ├── Articles └── Backlinks ``` --- # 151. Resource Explorer 统一页面: ```text List ├── Search ├── Filter ├── Sort ├── Columns ├── Saved Views ├── Bulk Actions └── Export ``` --- # 152. Resource Detail 统一: ```text Overview Relations Activity Events Tasks Executions Artifacts ``` Plugin 可以增加: ```text SEO Analysis Backlinks AI Recommendations ``` --- # 153. Search UI 全局: ```text ⌘K / Ctrl+K ``` 输入: ```text AI SEO ``` 返回: ```text Websites Articles Tasks Plugins Skills Actions ``` 按照: ```text relevance ``` 排序。 --- # 154. Saved View 用户可以: ```text 保存当前: filter sort columns search ``` 例如: ```text Failed Tasks High DR Websites Production Deployments ``` --- # 155. Data Table Performance 必须支持: ```text server-side pagination server-side sorting server-side filtering virtualization ``` 禁止: ```text GET 100000 records ↓ browser filter ``` --- # 156. Bulk UI Bulk Action: ```text Select ↓ Action ↓ Confirmation ↓ Task created ↓ Task Detail ``` 不能长时间阻塞页面。 --- # 157. Import 未来提供: ```text core.import ``` 支持: ```text CSV JSON JSONL Excel ``` 流程: ```text Upload Artifact ↓ Import Task ↓ Validate ↓ Preview ↓ Confirm ↓ Batch Jobs ↓ Actions ``` --- # 158. Import Validation 必须先: ```text dry-run ``` 显示: ```text 1000 rows 980 valid 15 warnings 5 errors ``` 用户确认后: ```text execute ``` --- # 159. Import Security Import 必须: ```text schema validation field permission scope validation file size limit row limit rate limit ``` --- # 160. Data Runtime Package 目录: ```text packages/data/ ├── data-runtime.ts ├── data-context.ts ├── repository.ts ├── data-provider.ts ├── query/ │ ├── query-runtime.ts │ ├── query-schema.ts │ ├── query-validator.ts │ ├── query-planner.ts │ ├── query-cost.ts │ └── query-compiler.ts ├── filter/ ├── pagination/ ├── relation/ ├── aggregate/ ├── cache/ └── index.ts ``` --- # 161. Search Package ```text packages/search/ ├── search-runtime.ts ├── search-provider.ts ├── search-schema.ts ├── search-planner.ts ├── ranking.ts ├── index-runtime.ts ├── index-registry.ts ├── embedding/ ├── providers/ └── index.ts ``` --- # 162. Schema Package ```text packages/schema/ ├── schema-registry.ts ├── resource-schema.ts ├── field-definition.ts ├── relation-definition.ts ├── index-definition.ts ├── validation.ts └── index.ts ``` --- # 163. Cache Package ```text packages/cache/ ├── cache-runtime.ts ├── cache-provider.ts ├── cache-key.ts ├── invalidation.ts └── index.ts ``` --- # 164. Export Package ```text packages/export/ ├── export-service.ts ├── csv.ts ├── json.ts ├── jsonl.ts ├── excel.ts └── index.ts ``` --- # 165. Import Package ```text packages/import/ ├── import-service.ts ├── parser.ts ├── validator.ts ├── preview.ts ├── importer.ts └── index.ts ``` --- # 166. Database 第一阶段: ```text PostgreSQL ``` 推荐: ```text PostgreSQL + pgvector ``` 用于: ```text transactional data full text JSON vector ``` 减少: ```text Elasticsearch RedisSearch Vector DB ``` 等额外基础设施。 --- # 167. When To Add Search Engine 只有出现: ```text 数据规模 搜索复杂度 性能要求 ``` 明确超过 PostgreSQL 能力时,再接: ```text OpenSearch Elasticsearch Meilisearch ``` Search Runtime 必须让切换 Provider 不影响上层。 --- # 168. Database Is Source of Truth 绝对原则: ```text PostgreSQL = Source of Truth Search Index = Derived State Cache = Derived State ``` --- # 169. Data Runtime Integration 完整链: ```text Resource ↓ Schema ↓ Permission ↓ Scope ↓ Query Runtime ↓ Repository ↓ Data Provider ↓ PostgreSQL ``` Search: ```text Resource ↓ Schema ↓ Permission ↓ Scope ↓ Search Runtime ↓ Search Provider ↓ Index ``` --- # 170. Action Integration 写入: ```text Action ↓ Action Runtime ↓ Domain Logic ↓ Repository ↓ Transaction ↓ Database ↓ Outbox ↓ Event ``` --- # 171. Index Integration ```text Event ↓ Index Job ↓ Worker ↓ Search Runtime ↓ Search Provider ``` --- # 172. Agent Integration Agent: ```text Goal ↓ Search / Query Capability ↓ QueryPlan / SearchPlan ↓ Runtime Validation ↓ Execution ``` Agent 不允许: ```text Database Access ``` --- # 173. MCP Integration MCP: ```text MCP ↓ Capability ↓ Search / Query Action ↓ Data Runtime ``` 禁止: ```text MCP → PostgreSQL ``` --- # 174. Plugin Integration Plugin 只需要声明: ```text Resource Schema Actions Search Definition Indexes Relations ``` DevOS 自动获得: ```text Query Search Generic UI Global Search Agent Capability MCP Exposure ``` --- # 175. Acceptance Criteria ## Data ```text [ ] Data Runtime [ ] Repository [ ] Data Provider [ ] Query Runtime [ ] Filter [ ] Sort [ ] Pagination [ ] Relations [ ] Aggregate [ ] Scope ``` ## Search ```text [ ] Search Runtime [ ] Full Text [ ] Semantic [ ] Hybrid abstraction [ ] Search Provider [ ] Index Runtime [ ] Incremental Index [ ] Rebuild [ ] Search Ranking ``` ## Security ```text [ ] Field permission [ ] Row scope [ ] Query authorization [ ] Search authorization [ ] Export authorization [ ] Sensitive field masking ``` ## Performance ```text [ ] Query timeout [ ] Query cost [ ] Slow query detection [ ] Cache [ ] DataLoader [ ] Batch [ ] Cursor pagination ``` ## Integration ```text [ ] Resource Registry [ ] Action Runtime [ ] Task Runtime [ ] Event Runtime [ ] Agent Runtime [ ] MCP Runtime [ ] Plugin Runtime ``` --- # 176. Integration Tests 必须测试: ```text Resource ↓ Query ↓ Permission ↓ Scope ↓ Database ``` 测试: ```text Org A cannot query Org B User cannot query forbidden field Invalid filter rejected Invalid sort rejected Large query rejected Query timeout works Cursor pagination works Relations do not produce N+1 Aggregate respects permission ``` --- # 177. Search Tests 测试: ```text full text search semantic search hybrid search ranking filter scope permission index rebuild incremental index index failure index recovery fallback ``` --- # 178. Agent Tests 测试: ```text Agent uses Query for structured requirement Agent uses Search for semantic requirement Agent cannot query unauthorized Resource Agent cannot request forbidden fields Agent cannot generate raw SQL Agent respects search budget Agent respects query limits ``` --- # 179. MCP Tests 测试: ```text MCP query MCP search MCP permission MCP scope MCP budget MCP timeout MCP cannot bypass Data Runtime ``` --- # 180. Plugin Tests 安装 Plugin: ```text Plugin ↓ Resource Schema ↓ Registry ↓ Query ↓ Search ↓ Generic UI ↓ Agent Capability ``` 必须全部自动生效。 --- # 181. Zcode Implementation Rules ## Rule 1 任何业务数据读取: ```text 必须经过 Data Runtime ``` --- ## Rule 2 任何业务数据写入: ```text 必须经过 Action Runtime ``` --- ## Rule 3 禁止: ```text UI → Prisma Plugin → Prisma Agent → Prisma MCP → Prisma ``` --- ## Rule 4 禁止暴露: ```text raw SQL ``` 给: ```text Agent MCP Plugin public API REST client ``` --- ## Rule 5 所有 Query 必须执行: ```text Schema Validation Permission Scope Cost Check Timeout ``` --- ## Rule 6 所有 Search 必须执行: ```text Permission Scope Budget ``` --- ## Rule 7 Database 是: ```text Source of Truth ``` Search Index 和 Cache 都是: ```text Derived State ``` --- ## Rule 8 Index 更新必须通过: ```text Event + Task/Job + Worker ``` 支持: ```text retry resume rebuild ``` --- ## Rule 9 大数据量操作必须: ```text Task + Job + Cursor ``` 不能同步读取全部数据。 --- ## Rule 10 Resource Schema 必须成为: ```text Single Source of Truth ``` 驱动: ```text Database API UI MCP Agent Search ``` --- # 182. Golden Rule DevOS 数据体系必须遵循: ```text Resource ↓ Schema ↓ Permission ↓ Scope ↓ Query / Search ↓ Data Runtime ↓ Provider ↓ Database / Index ``` 写入: ```text Action ↓ Action Runtime ↓ Data Runtime ↓ Database ↓ Outbox ↓ Event ↓ Index / Cache / Plugin / Agent ``` 最终形成: ```text Resource │ Schema │ ┌──────────┴──────────┐ │ │ Action Query │ │ Action Runtime Query Runtime │ │ │ ┌─────┴─────┐ │ │ │ │ Repository Search │ │ │ │ │ Search Runtime │ │ │ └───────┬───────┘ Search Index │ Database │ Outbox │ Event │ ┌──────────┼──────────┐ │ │ │ Cache Index Plugin │ │ │ └──────────┼──────────┘ │ Agent ``` --- # 183. Final Principle DevOS 不应该让每一个 Plugin 自己实现: ```text Pagination Filter Search Permission Filter Scope Export Import Cache Index Relation Query Builder Data Table ``` 这些应该全部成为: ```text DevOS Data Platform ``` 于是一个新的业务 Plugin 只需要定义: ```text Resource Schema + Actions + Relations + Search Definition ``` DevOS 自动提供: ```text Database Query Search Index Permission Scope Pagination Generic UI Global Search Agent Capability MCP Capability Export Import Cache Audit Observability ``` 这才是真正意义上的: ```text Reusable Development OS ``` 而不是: ```text 一个拥有很多功能的 Backend Template ```