@seaverse/data-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,408 @@
1
+ # @seaverse/data-sdk
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@seaverse/data-sdk.svg)](https://www.npmjs.com/package/@seaverse/data-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ 高性能数据服务 SDK,基于 PostgreSQL/AlloyDB + PostgREST + RLS 架构。
7
+
8
+ ## 🚀 核心概念
9
+
10
+ ### App ID 是什么?
11
+
12
+ **App ID** 是您在 SeaVerse 平台上创建的应用的唯一标识符。它用于:
13
+ - ✅ 多租户数据隔离(每个应用的数据互不干扰)
14
+ - ✅ 权限控制(RLS 策略基于 app_id)
15
+ - ✅ 资源配额管理
16
+
17
+ **如何获取 App ID?**
18
+ 1. 登录 [SeaVerse 控制台](https://console.seaverse.ai)
19
+ 2. 进入"应用管理"
20
+ 3. 复制您的 App ID
21
+
22
+ > ⚠️ **重要**:所有 SDK 操作都需要提供有效的 `appId`,否则无法访问数据。
23
+
24
+ ## 特性
25
+
26
+ - ✅ TypeScript 类型支持
27
+ - ✅ 自动处理 JWT 认证
28
+ - ✅ RLS 安全控制
29
+ - ✅ 应用隔离
30
+ - ✅ 简单易用的 API
31
+ - ✅ 完整的错误处理
32
+ - ✅ 支持过滤、排序、分页
33
+ - ✅ 支持标签和 JSONB 字段查询
34
+
35
+ ## 安装
36
+
37
+ ```bash
38
+ npm install @seaverse/data-sdk
39
+ ```
40
+
41
+ ## 快速开始
42
+
43
+ ### 1. 初始化 SDK
44
+
45
+ SDK 提供三种初始化方式,根据您的使用场景选择:
46
+
47
+ ```typescript
48
+ import { DataClient } from '@seaverse/data-sdk';
49
+
50
+ // 方式1: SeaVerse 平台应用(自动检测环境)- 推荐
51
+ // 适用于部署在 SeaVerse 平台的应用
52
+ const client = new DataClient({
53
+ appId: 'my-app-123', // 必需:应用ID
54
+ token: 'user-jwt-token', // 必需:用户JWT token
55
+ });
56
+
57
+ // 方式2: 第三方应用(指定环境)
58
+ // 适用于非 SeaVerse 平台或需要明确指定环境的应用
59
+ const client = new DataClient({
60
+ appId: 'my-app-123',
61
+ token: 'user-jwt-token',
62
+ environment: 'production', // 可选:'production' | 'staging' | 'development' | 'local'
63
+ });
64
+
65
+ // 方式3: 完全自定义(自定义 baseURL)
66
+ // 适用于私有部署或特殊环境
67
+ const client = new DataClient({
68
+ appId: 'my-app-123',
69
+ token: 'user-jwt-token',
70
+ baseURL: 'https://custom-api.example.com', // 自定义API地址
71
+ });
72
+ ```
73
+
74
+ **配置选项说明:**
75
+
76
+ | 参数 | 类型 | 必需 | 说明 |
77
+ |-----|------|------|------|
78
+ | `appId` | string | ✅ | 应用ID,从控制台获取 |
79
+ | `token` | string | ✅ | 用户JWT token,用于身份验证 |
80
+ | `baseURL` | string | ⬜️ | 自定义API地址,优先级最高 |
81
+ | `environment` | Environment | ⬜️ | 环境类型,当未提供baseURL时使用 |
82
+ | `timeout` | number | ⬜️ | 请求超时时间(毫秒),默认10000 |
83
+ | `headers` | object | ⬜️ | 自定义请求头 |
84
+ | `debug` | boolean | ⬜️ | 是否开启调试日志 |
85
+
86
+ ### 2. 查询数据
87
+
88
+ ```typescript
89
+ // 查询列表
90
+ const notes = await client.query({
91
+ table: 'notes',
92
+ filters: {
93
+ category: 'work',
94
+ visibility: 'private',
95
+ },
96
+ order: {
97
+ field: 'created_at',
98
+ direction: 'desc',
99
+ },
100
+ pagination: {
101
+ limit: 20,
102
+ offset: 0,
103
+ },
104
+ });
105
+
106
+ // 查询单条
107
+ const note = await client.get('note-id-123');
108
+ ```
109
+
110
+ ### 3. 创建数据
111
+
112
+ ```typescript
113
+ const newNote = await client.create({
114
+ table: 'notes',
115
+ data: {
116
+ title: '我的笔记',
117
+ content: '笔记内容...',
118
+ },
119
+ visibility: 'private',
120
+ category: 'work',
121
+ tags: ['important', 'todo'],
122
+ });
123
+ ```
124
+
125
+ ### 4. 更新数据
126
+
127
+ ```typescript
128
+ const updated = await client.update('note-id-123', {
129
+ data: {
130
+ title: '更新的标题',
131
+ content: '更新的内容',
132
+ },
133
+ category: 'personal',
134
+ });
135
+ ```
136
+
137
+ ### 5. 删除数据
138
+
139
+ ```typescript
140
+ // 删除单条
141
+ await client.delete('note-id-123');
142
+
143
+ // 批量删除
144
+ await client.batchDelete(['id-1', 'id-2', 'id-3']);
145
+ ```
146
+
147
+ ### 6. 管理员操作
148
+
149
+ ```typescript
150
+ // 检查是否是管理员
151
+ const isAdmin = await client.isAdmin();
152
+ ```
153
+
154
+ ## API 文档
155
+
156
+ ### API 概览
157
+
158
+ | 方法 | 说明 | 参数 | 返回值 |
159
+ |------|------|------|--------|
160
+ | `query(options)` | 查询数据列表 | `QueryOptions` | `Promise<DataRecord[]>` |
161
+ | `get(id)` | 获取单条数据 | `id: string` | `Promise<DataRecord \| null>` |
162
+ | `create(options)` | 创建数据 | `CreateDataOptions` | `Promise<DataRecord>` |
163
+ | `update(id, options)` | 更新数据 | `id: string`, `UpdateDataOptions` | `Promise<DataRecord>` |
164
+ | `delete(id)` | 删除数据 | `id: string` | `Promise<void>` |
165
+ | `batchDelete(ids)` | 批量删除 | `ids: string[]` | `Promise<void>` |
166
+ | `queryWithPagination(options)` | 查询带分页信息 | `QueryOptions` | `Promise<PaginatedResponse<DataRecord>>` |
167
+ | `isAdmin()` | 检查管理员权限 | - | `Promise<boolean>` |
168
+ | `updateToken(token)` | 更新JWT token | `token: string` | `void` |
169
+ | `updateAppId(appId)` | 更新应用ID | `appId: string` | `void` |
170
+ | `getAppId()` | 获取当前应用ID | - | `string` |
171
+ | `getUserId()` | 获取当前用户ID | - | `string` |
172
+
173
+ ### 查询选项(QueryOptions)
174
+
175
+ ```typescript
176
+ interface QueryOptions {
177
+ // 表名(必填)
178
+ table: string;
179
+
180
+ // 过滤条件
181
+ filters?: {
182
+ id?: string; // 数据 ID
183
+ category?: string; // 分类
184
+ visibility?: 'public' | 'private'; // 可见性
185
+ tags?: string[]; // 标签
186
+ data?: Record<string, any>; // data_value 字段过滤
187
+ created_after?: string; // 创建时间(之后)
188
+ created_before?: string; // 创建时间(之前)
189
+ };
190
+
191
+ // 排序
192
+ order?: {
193
+ field: 'created_at' | 'updated_at';
194
+ direction: 'asc' | 'desc';
195
+ };
196
+
197
+ // 分页
198
+ pagination?: {
199
+ limit: number;
200
+ offset: number;
201
+ };
202
+ }
203
+ ```
204
+
205
+ ### 数据记录(DataRecord)
206
+
207
+ ```typescript
208
+ interface DataRecord {
209
+ id: string;
210
+ app_id: string;
211
+ table_name: string;
212
+ data_value: Record<string, any>; // 实际数据
213
+ owner_user_id: string;
214
+ visibility: 'public' | 'private';
215
+ category?: string;
216
+ tags?: string[];
217
+ created_at: string;
218
+ updated_at: string;
219
+ }
220
+ ```
221
+
222
+ ## 权限说明
223
+
224
+ ### RLS 自动控制
225
+
226
+ SDK 会自动通过 RLS 策略控制权限:
227
+
228
+ - ✅ **应用隔离**:用户只能访问自己应用的数据
229
+ - ✅ **用户隔离**:用户只能访问自己的私密数据
230
+ - ✅ **公开数据**:所有人可以读取公开数据
231
+ - ✅ **管理员权限**:管理员可以访问应用内所有数据
232
+
233
+ ### 操作权限矩阵
234
+
235
+ | 操作 | Owner | Admin | 其他用户(private) | 其他用户(public) |
236
+ |------|-------|-------|-------------------|-------------------|
237
+ | 读取 | ✅ | ✅ | ❌ | ✅ |
238
+ | 创建 | ✅ | ✅ | ✅(自己的) | ✅(自己的) |
239
+ | 修改 | ✅ | ✅ | ❌ | ❌ |
240
+ | 删除 | ✅ | ✅ | ❌ | ❌ |
241
+
242
+ ## 错误处理
243
+
244
+ ```typescript
245
+ import { SDKError } from '@seaverse/data-sdk';
246
+
247
+ try {
248
+ await client.create({ ... });
249
+ } catch (error) {
250
+ if (error instanceof SDKError) {
251
+ console.error('错误代码:', error.code);
252
+ console.error('状态码:', error.statusCode);
253
+ console.error('详情:', error.details);
254
+ }
255
+ }
256
+ ```
257
+
258
+ ### 错误代码
259
+
260
+ - `REQUEST_FAILED` - 请求失败
261
+ - `TIMEOUT` - 请求超时
262
+ - `NETWORK_ERROR` - 网络错误
263
+ - `INVALID_TOKEN` - Token 无效
264
+ - `NOT_FOUND` - 数据不存在或无权限
265
+ - `PERMISSION_DENIED` - 权限不足
266
+ - `VALIDATION_ERROR` - 参数验证失败
267
+
268
+ ## 高级用法
269
+
270
+ ### 动态更新 Token
271
+
272
+ ```typescript
273
+ // JWT 过期后更新 token
274
+ client.updateToken('new-jwt-token');
275
+ ```
276
+
277
+ ### 切换应用
278
+
279
+ ```typescript
280
+ // 切换到其他应用
281
+ client.updateAppId('another-app-id');
282
+ ```
283
+
284
+ ### JSONB 字段查询
285
+
286
+ ```typescript
287
+ // 查询 data_value 中的字段
288
+ const results = await client.query({
289
+ table: 'posts',
290
+ filters: {
291
+ data: {
292
+ title: 'Hello World', // data_value->>'title' = 'Hello World'
293
+ author: 'Alice', // data_value->>'author' = 'Alice'
294
+ },
295
+ },
296
+ });
297
+ ```
298
+
299
+ ### 标签查询
300
+
301
+ ```typescript
302
+ // 查询包含指定标签的数据
303
+ const results = await client.query({
304
+ table: 'posts',
305
+ filters: {
306
+ tags: ['javascript', 'typescript'], // 包含任一标签
307
+ },
308
+ });
309
+ ```
310
+
311
+ ### 时间范围查询
312
+
313
+ ```typescript
314
+ // 查询指定时间范围的数据
315
+ const results = await client.query({
316
+ table: 'logs',
317
+ filters: {
318
+ created_after: '2026-01-01T00:00:00Z',
319
+ created_before: '2026-01-31T23:59:59Z',
320
+ },
321
+ });
322
+ ```
323
+
324
+ ### 分页查询
325
+
326
+ ```typescript
327
+ // 查询带总数的分页数据
328
+ const result = await client.queryWithPagination({
329
+ table: 'posts',
330
+ pagination: { limit: 10, offset: 0 },
331
+ });
332
+
333
+ console.log(`总共 ${result.total} 条,当前返回 ${result.data.length} 条`);
334
+ console.log(`是否还有更多: ${result.hasMore}`);
335
+ ```
336
+
337
+ ## 性能说明
338
+
339
+ 基于新的 RLS 架构,SDK 具有以下性能特性:
340
+
341
+ - ⚡ **查询 10000 条数据**:~30ms(vs 旧架构 50 秒)
342
+ - ⚡ **STABLE 函数缓存**:管理员查询自动缓存
343
+ - ⚡ **短路求值**:优先检查 visibility 和 owner
344
+ - ⚡ **哈希分区**:256 个分区,支持并行查询
345
+
346
+ ## 环境配置
347
+
348
+ SDK 支持多环境部署,根据不同的使用场景灵活配置。
349
+
350
+ ### 预设环境
351
+
352
+ | Environment | baseURL | 适用场景 | 自动检测规则 |
353
+ |-------------|---------|----------|-------------|
354
+ | **production** | `https://data.seaverse.ai` | 生产环境 | 默认环境 |
355
+ | **staging** | `https://data.sg.seaverse.dev` | 预发布环境 | hostname 包含 `staging` |
356
+ | **development** | `https://data-dev.seaverse.dev` | 开发测试 | hostname 包含 `-dev` 或 `.dev` |
357
+ | **local** | `http://localhost:3000` | 本地开发 | hostname 是 `localhost` 或 `127.0.0.1` |
358
+
359
+ ### 配置优先级
360
+
361
+ SDK 按以下优先级选择 API 端点:
362
+
363
+ 1. **显式 `baseURL`** - 最高优先级,直接使用指定的URL
364
+ 2. **`environment` 参数** - 使用预设环境配置
365
+ 3. **自动检测** - 最低优先级,根据 hostname 自动判断
366
+
367
+ ### 使用示例
368
+
369
+ 参见"快速开始 → 初始化 SDK"部分的三种初始化方式。
370
+
371
+ ## 错误码说明
372
+
373
+ SDK 提供了详细的错误码,方便问题诊断:
374
+
375
+ | 错误码 | HTTP状态码 | 说明 | 解决方法 |
376
+ |--------|-----------|------|---------|
377
+ | `REQUEST_FAILED` | 4xx/5xx | 请求失败 | 检查请求参数和服务器状态 |
378
+ | `TIMEOUT` | - | 请求超时 | 增加 timeout 配置或检查网络 |
379
+ | `NETWORK_ERROR` | - | 网络错误 | 检查网络连接 |
380
+ | `INVALID_TOKEN` | 401 | Token无效或过期 | 使用 `updateToken()` 更新token |
381
+ | `NOT_FOUND` | 404 | 数据不存在或无权限 | 检查数据ID和权限 |
382
+ | `PERMISSION_DENIED` | 403 | 权限不足 | 确认用户有相应权限 |
383
+ | `VALIDATION_ERROR` | 400 | 参数验证失败 | 检查请求参数格式 |
384
+
385
+ ## 版本历史
386
+
387
+ ### v0.1.0 (2026-01-10)
388
+
389
+ **🎉 首个版本发布**
390
+
391
+ - ✅ 基于 PostgreSQL/AlloyDB + PostgREST + RLS 架构
392
+ - ✅ 完整的 CRUD 操作支持
393
+ - ✅ 多环境配置与自动检测
394
+ - ✅ 分页查询支持
395
+ - ✅ 管理员权限检查
396
+ - ✅ TypeScript 类型定义
397
+ - ✅ 完整的错误处理
398
+
399
+ ## 相关资源
400
+
401
+ - [SeaVerse 官网](https://seaverse.ai)
402
+ - [开发者文档](https://docs.seaverse.ai)
403
+ - [GitHub 仓库](https://github.com/seaverseai/sv-sdk)
404
+ - [问题反馈](https://github.com/seaverseai/sv-sdk/issues)
405
+
406
+ ## License
407
+
408
+ MIT © [SeaVerse Team](https://seaverse.ai)