steedos-builder6-tables

Installation
SKILL.md

Builder6 Tables | Builder6 数据表

Overview | 概述

The Tables module (@builder6/tables) provides data table management with automatic lookup field resolution, DataLoader batching, and DevExtreme-compatible query parameters. Collections are stored in MongoDB with the naming convention t_{baseId}_{tableId}.

Collection Naming | 集合命名

MongoDB collection: t_{baseId}_{tableId}

Example: t_app1_orders for base app1, table orders.

API Endpoints | API 端点

All endpoints require AuthGuard. Base path: /api/v6/tables/.

Method Path Description
POST /:baseId/:tableId Create record
GET /:baseId/:tableId List records (paginated)
GET /:baseId/:tableId/:recordId Get single record
PUT/PATCH /:baseId/:tableId/:recordId Update record
DELETE /:baseId/:tableId/:recordId Delete record
DELETE /:baseId/:tableId Delete multiple (body: {records: [...]})
GET /meta/bases/:baseId/tables/:tableId Get table metadata

Record Operations | 记录操作

Create | 创建

POST /api/v6/tables/app1/orders
Body: { "name": "Order 1", "amount": 100 }

Auto-injected fields: owner, created_by, created, modified_by, modified, space.

Lookup fields in the body are automatically resolved — you can pass { _id: "..." } objects or plain string IDs.

Query | 查询

GET /api/v6/tables/app1/orders?filters=["amount",">",50]&sort=created desc&top=20&skip=0
Parameter Required Default Description
fields No all Comma-separated or JSON array
filters No none DevExtreme filter format (JSON)
sort No none "field asc, field2 desc"
skip Yes 0 Pagination offset
top Yes 20 Page size

Response:

{
  "data": [{ "_id": "...", "name": "Order 1", "amount": 100, ... }],
  "totalCount": 42
}

Batch Delete | 批量删除

DELETE /api/v6/tables/app1/orders
Body: { "records": ["id1", "id2", "id3"] }
Response: { "records": [{ "deleted": true, "_id": "id1" }, ...] }

Lookup Field Resolution | 查找字段解析

On Read (convertRecordLookupFields)

When records are returned, lookup fields are expanded:

// Stored in DB
{ "customer": "cust123" }

// Returned to client (expanded via DataLoader)
{ "customer": { "_id": "cust123", "name": "Acme Corp" } }

Supports both single lookup and multiple: true (array of IDs → array of objects).

On Write (roolbackRecordFields)

When records are saved, lookup fields are converted back:

// Client sends
{ "customer": { "_id": "cust123", "name": "Acme Corp" } }

// Stored in DB
{ "customer": "cust123" }

If a string value (not an ID) is passed, the system searches by both _id and name in the referenced collection.

DataLoader Batching

Lookup fields are resolved via DataLoader to prevent N+1 queries:

const loader = new DataLoader(async (ids: string[]) => {
  const records = await mongodbService.find(collectionName, {
    _id: { $in: ids }
  }, { projection: { _id: 1, name: 1 } });
  return ids.map(id => records.find(r => r._id === id));
});

Loaders are cached per collection name within the service instance.

Field Type Handling | 字段类型处理

On write, field types are auto-converted:

Field Type Conversion
lookup Object → _id string; string → lookup by _id or name
date, datetime, time String → new Date(value)

MetaService | 元数据服务

MetaService provides table field schema:

// Get all fields for a table
const fields = await metaService.getTableMeta(baseId, tableId);

// Built-in lookup fields
// created_by and modified_by are automatically treated as lookup → users

DevExtreme Query Adapter | DevExtreme 查询适配器

@builder6/query-mongodb translates DevExtreme loadOptions to MongoDB aggregation:

import { querySimple } from '@builder6/query-mongodb';

const result = await querySimple(collection, {
  take: 20,
  skip: 0,
  filter: ["amount", ">", 50],
  sort: [{ selector: "created", desc: true }],
  select: ["name", "amount"],
  requireTotalCount: true,
}, { replaceIds: false });

// result: { data: [...], totalCount: N }
Related skills
Installs
12
GitHub Stars
1.6K
First Seen
14 days ago