@seaverse/data-service-sdk 0.1.0 → 0.3.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/dist/index.cjs CHANGED
@@ -24,22 +24,72 @@ const ENDPOINTS = {
24
24
  /**
25
25
  * SeaVerse Data Service SDK Client
26
26
  *
27
- * Provides methods to manage Firestore tokens for authenticated users and guests.
27
+ * This client helps you get Firestore access tokens for your application.
28
+ * It supports both authenticated users and guest users.
29
+ *
30
+ * THREE-TIER PERMISSION MODEL:
31
+ * ---------------------------
32
+ * Your Firestore data is organized in three permission levels:
33
+ *
34
+ * 1. publicRead/ - System configs, announcements (Read: Everyone, Write: Admin only)
35
+ * 2. publicData/ - User posts, shared content (Read: Everyone, Write: Everyone)
36
+ * 3. userData/{userId}/ - Private user data (Read/Write: Owner only)
37
+ *
38
+ * QUICK START FOR LLM:
39
+ * -------------------
40
+ * Step 1: Get a Firestore token
41
+ * Step 2: Initialize Firebase with the token
42
+ * Step 3: Access Firestore using the correct data paths
28
43
  *
29
44
  * @example
30
45
  * ```typescript
31
- * // Create client instance
46
+ * // Step 1: Create client and get token
47
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
32
48
  * const client = new DataServiceClient();
33
49
  *
34
- * // Generate Firestore token for authenticated user
35
- * const token = await client.generateFirestoreToken({
36
- * token: 'user-jwt-token',
37
- * app_id: 'your-app-id',
50
+ * // For authenticated users:
51
+ * const tokenResponse = await client.generateFirestoreToken({
52
+ * token: 'user-jwt-token-from-auth-sdk',
53
+ * app_id: 'my-app-123',
54
+ * });
55
+ *
56
+ * // For guest users (no authentication required):
57
+ * const guestResponse = await client.generateGuestFirestoreToken({
58
+ * app_id: 'my-app-123',
59
+ * });
60
+ *
61
+ * // Step 2: Initialize Firebase
62
+ * import { initializeApp } from 'firebase/app';
63
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
64
+ * import { getFirestore, collection, addDoc, getDocs, serverTimestamp } from 'firebase/firestore';
65
+ *
66
+ * const app = initializeApp({ projectId: tokenResponse.project_id });
67
+ * const auth = getAuth(app);
68
+ * await signInWithCustomToken(auth, tokenResponse.custom_token);
69
+ * const db = getFirestore(app);
70
+ *
71
+ * // Step 3: Access Firestore data with correct paths
72
+ * const appId = tokenResponse.app_id;
73
+ * const userId = tokenResponse.user_id;
74
+ *
75
+ * // Write to publicData (everyone can write)
76
+ * await addDoc(collection(db, `appData/${appId}/publicData/posts`), {
77
+ * _appId: appId, // REQUIRED: For data isolation
78
+ * _createdAt: serverTimestamp(), // REQUIRED: Server timestamp
79
+ * _createdBy: userId, // REQUIRED: Current user ID
80
+ * title: 'My Post', // Your custom fields
81
+ * content: 'Hello world'
38
82
  * });
39
83
  *
40
- * // Generate Firestore token for guest
41
- * const guestToken = await client.generateGuestFirestoreToken({
42
- * app_id: 'your-app-id',
84
+ * // Read from publicData (everyone can read)
85
+ * const snapshot = await getDocs(collection(db, `appData/${appId}/publicData/posts`));
86
+ *
87
+ * // Write to userData (only owner can write)
88
+ * await addDoc(collection(db, `appData/${appId}/userData/${userId}/notes`), {
89
+ * _appId: appId, // REQUIRED
90
+ * _createdAt: serverTimestamp(), // REQUIRED
91
+ * _createdBy: userId, // REQUIRED
92
+ * note: 'Private note' // Your custom fields
43
93
  * });
44
94
  * ```
45
95
  */
@@ -88,8 +138,16 @@ class DataServiceClient {
88
138
  /**
89
139
  * Generate Firestore token for authenticated user
90
140
  *
91
- * This method generates a Firestore custom token for an authenticated user.
92
- * The user must provide a valid JWT token.
141
+ * Use this method when you have a logged-in user with a valid JWT token.
142
+ * The returned token allows access to:
143
+ * - publicRead data (read only)
144
+ * - publicData (read and write)
145
+ * - userData/{user_id} (read and write own data only)
146
+ *
147
+ * IMPORTANT FOR LLM: After getting the token, you MUST:
148
+ * 1. Initialize Firebase app with the project_id
149
+ * 2. Sign in with the custom_token using signInWithCustomToken()
150
+ * 3. Always include required fields in documents: _appId, _createdAt, _createdBy
93
151
  *
94
152
  * @param request - The request containing user token and app ID
95
153
  * @param options - Additional axios request configuration
@@ -97,14 +155,37 @@ class DataServiceClient {
97
155
  *
98
156
  * @example
99
157
  * ```typescript
100
- * const response = await client.generateFirestoreToken({
101
- * token: 'user-jwt-token',
102
- * app_id: 'my-app',
158
+ * // First, get user token from Auth SDK
159
+ * import { AuthClient } from '@seaverse/auth-sdk';
160
+ * const authClient = new AuthClient({ appId: 'my-app-123' });
161
+ * const loginResponse = await authClient.loginWithEmail({
162
+ * email: 'user@example.com',
163
+ * password: 'password123'
103
164
  * });
104
165
  *
105
- * console.log('Firestore ID Token:', response.id_token);
106
- * console.log('User ID:', response.user_id);
107
- * console.log('Expires in:', response.expires_in, 'seconds');
166
+ * // Then, get Firestore token
167
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
168
+ * const dataClient = new DataServiceClient();
169
+ * const firestoreToken = await dataClient.generateFirestoreToken({
170
+ * token: loginResponse.token, // JWT token from auth
171
+ * app_id: 'my-app-123'
172
+ * });
173
+ *
174
+ * console.log('Firestore Custom Token:', firestoreToken.custom_token);
175
+ * console.log('User ID:', firestoreToken.user_id);
176
+ * console.log('App ID:', firestoreToken.app_id);
177
+ * console.log('Token expires in:', firestoreToken.expires_in, 'seconds');
178
+ *
179
+ * // Now initialize Firebase and use Firestore
180
+ * import { initializeApp } from 'firebase/app';
181
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
182
+ * import { getFirestore } from 'firebase/firestore';
183
+ *
184
+ * const app = initializeApp({ projectId: firestoreToken.project_id });
185
+ * const auth = getAuth(app);
186
+ * await signInWithCustomToken(auth, firestoreToken.custom_token);
187
+ * const db = getFirestore(app);
188
+ * // Ready to use Firestore!
108
189
  * ```
109
190
  */
110
191
  async generateFirestoreToken(request, options) {
@@ -118,10 +199,18 @@ class DataServiceClient {
118
199
  return response.data;
119
200
  }
120
201
  /**
121
- * Generate Firestore token for guest user
202
+ * Generate Firestore token for guest user (no authentication required)
203
+ *
204
+ * Use this method when you want to allow anonymous users to access your app.
205
+ * Guest users have limited permissions:
206
+ * - publicRead data (read only)
207
+ * - publicData (read and write, but cannot access other users' data)
208
+ * - CANNOT access userData (no private data access)
122
209
  *
123
- * This method generates a Firestore custom token for a guest (unauthenticated) user.
124
- * No user authentication token is required.
210
+ * IMPORTANT FOR LLM:
211
+ * - Guest users get a temporary user_id (e.g., 'guest-abc123')
212
+ * - Still need to include required fields: _appId, _createdAt, _createdBy
213
+ * - Great for public forums, comment sections, or demo apps
125
214
  *
126
215
  * @param request - The request containing app ID
127
216
  * @param options - Additional axios request configuration
@@ -129,13 +218,39 @@ class DataServiceClient {
129
218
  *
130
219
  * @example
131
220
  * ```typescript
132
- * const response = await client.generateGuestFirestoreToken({
133
- * app_id: 'my-app',
221
+ * // Get guest token (no user authentication needed!)
222
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
223
+ * const client = new DataServiceClient();
224
+ *
225
+ * const guestToken = await client.generateGuestFirestoreToken({
226
+ * app_id: 'my-app-123'
227
+ * });
228
+ *
229
+ * console.log('Guest Firestore Custom Token:', guestToken.custom_token);
230
+ * console.log('Guest User ID:', guestToken.user_id); // e.g., 'guest-abc123'
231
+ * console.log('Role:', guestToken.role); // 'guest'
232
+ *
233
+ * // Initialize Firebase with guest token
234
+ * import { initializeApp } from 'firebase/app';
235
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
236
+ * import { getFirestore, collection, addDoc, serverTimestamp } from 'firebase/firestore';
237
+ *
238
+ * const app = initializeApp({ projectId: guestToken.project_id });
239
+ * const auth = getAuth(app);
240
+ * await signInWithCustomToken(auth, guestToken.custom_token);
241
+ * const db = getFirestore(app);
242
+ *
243
+ * // Guest can write to publicData
244
+ * await addDoc(collection(db, `appData/${guestToken.app_id}/publicData/comments`), {
245
+ * _appId: guestToken.app_id,
246
+ * _createdAt: serverTimestamp(),
247
+ * _createdBy: guestToken.user_id, // Guest user ID
248
+ * comment: 'Great app!',
249
+ * rating: 5
134
250
  * });
135
251
  *
136
- * console.log('Guest Firestore ID Token:', response.id_token);
137
- * console.log('Guest User ID:', response.user_id);
138
- * console.log('Role:', response.role); // 'guest'
252
+ * // Guest CANNOT write to userData (this will fail)
253
+ * // await addDoc(collection(db, `appData/${guestToken.app_id}/userData/${guestToken.user_id}/notes`), ...);
139
254
  * ```
140
255
  */
141
256
  async generateGuestFirestoreToken(request, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/config.ts","../src/client.ts"],"sourcesContent":[null,null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/config.ts","../src/client.ts"],"sourcesContent":[null,null],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,64 +2,164 @@ import { AxiosRequestConfig } from 'axios';
2
2
 
3
3
  /**
4
4
  * Type definitions for SeaVerse Data Service API
5
- * Firestore token management
5
+ * Firestore token management with three-tier permission model
6
+ *
7
+ * PERMISSION MODEL OVERVIEW:
8
+ * -------------------------
9
+ * SeaVerse uses a three-tier data permission model in Firestore:
10
+ *
11
+ * 1. publicRead/ - Read-only public data (e.g., system configs, announcements)
12
+ * Read: All authenticated users | Write: Admins only
13
+ *
14
+ * 2. publicData/ - Read-write public data (e.g., user-generated content)
15
+ * Read: All authenticated users | Write: All authenticated users
16
+ *
17
+ * 3. userData/{userId}/ - Private user data (e.g., personal settings, private notes)
18
+ * Read: Owner only | Write: Owner only
19
+ *
20
+ * DATA PATH STRUCTURE:
21
+ * -------------------
22
+ * appData/{app_id}/publicRead/{collection}/{docId}
23
+ * appData/{app_id}/publicData/{collection}/{docId}
24
+ * appData/{app_id}/userData/{userId}/{collection}/{docId}
25
+ *
26
+ * REQUIRED FIELDS FOR ALL DOCUMENTS:
27
+ * ---------------------------------
28
+ * All Firestore documents MUST include these fields:
29
+ * - _appId: string (Application ID for data isolation)
30
+ * - _createdAt: timestamp (Server timestamp for creation time)
31
+ * - _createdBy: string (User ID of the document creator)
32
+ *
33
+ * These fields ensure proper data isolation and security enforcement.
6
34
  */
7
35
  /**
8
36
  * Request to generate Firestore token for authenticated user
37
+ *
38
+ * This token allows the user to access Firestore data based on their role:
39
+ * - Regular users: Can access publicRead (read), publicData (read/write), and their own userData
40
+ * - Admin users: Can also write to publicRead data
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const request = {
45
+ * token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // User's JWT token from auth service
46
+ * app_id: 'my-app-123' // Your application ID
47
+ * };
48
+ * ```
9
49
  */
10
50
  interface GenerateFirestoreTokenRequest {
11
51
  /**
12
- * User account token (JWT)
52
+ * User account token (JWT) from SeaVerse Auth Service
53
+ * Obtain this token using the @seaverse/auth-sdk loginWithEmail() or other auth methods
13
54
  */
14
55
  token: string;
15
56
  /**
16
- * Application ID
57
+ * Application ID (app_id) that identifies your application
58
+ * This ID is used for data isolation - users can only access data within their app
17
59
  */
18
60
  app_id: string;
19
61
  }
20
62
  /**
21
- * Request to generate Firestore token for guest user
63
+ * Request to generate Firestore token for guest user (unauthenticated)
64
+ *
65
+ * Guest users have limited access:
66
+ * - Can read publicRead data (system configs, announcements)
67
+ * - Can read/write publicData (with proper permissions)
68
+ * - Cannot access any userData (user-specific private data)
69
+ *
70
+ * Use this for anonymous users or when authentication is not required.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const request = {
75
+ * app_id: 'my-app-123' // Your application ID
76
+ * };
77
+ * ```
22
78
  */
23
79
  interface GenerateGuestFirestoreTokenRequest {
24
80
  /**
25
- * Application ID
81
+ * Application ID (app_id) that identifies your application
82
+ * Guest users are isolated to this specific application
26
83
  */
27
84
  app_id: string;
28
85
  }
29
86
  /**
30
- * Firestore token response
87
+ * Firestore token response containing all necessary credentials to access Firestore
88
+ *
89
+ * Use these credentials to initialize Firebase SDK and access Firestore with proper permissions.
90
+ * The token includes user information and app context for data isolation.
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * // After receiving this response, initialize Firebase:
95
+ * import { initializeApp } from 'firebase/app';
96
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
97
+ * import { getFirestore } from 'firebase/firestore';
98
+ *
99
+ * const app = initializeApp({ projectId: response.project_id });
100
+ * const auth = getAuth(app);
101
+ * await signInWithCustomToken(auth, response.custom_token);
102
+ * const db = getFirestore(app);
103
+ * // Now you can use Firestore with proper permissions
104
+ * ```
31
105
  */
32
106
  interface FirestoreTokenResponse {
33
107
  /**
34
- * Firebase ID Token (exchanged from Custom Token)
35
- */
36
- id_token: string;
37
- /**
38
- * Firebase Refresh Token (optional)
108
+ * Firebase Custom Token - Use this to authenticate with Firebase
109
+ *
110
+ * IMPORTANT: You MUST use this with signInWithCustomToken() to get authenticated:
111
+ *
112
+ * ```typescript
113
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
114
+ * const auth = getAuth(app);
115
+ * await signInWithCustomToken(auth, response.custom_token);
116
+ * ```
117
+ *
118
+ * This Custom Token contains:
119
+ * - appId claim: For data isolation (determines which data you can access)
120
+ * - User ID: Identifies the user
121
+ *
122
+ * After calling signInWithCustomToken(), Firebase automatically:
123
+ * 1. Exchanges the Custom Token for an ID Token
124
+ * 2. Uses the ID Token for all subsequent Firestore requests
125
+ * 3. Handles token refresh automatically
126
+ *
127
+ * Custom Token itself does not expire, but the ID Token it generates expires after 1 hour
39
128
  */
40
- refresh_token?: string;
129
+ custom_token: string;
41
130
  /**
42
131
  * Firebase Project ID
132
+ * Use this to initialize Firebase app: initializeApp({ projectId: '...' })
43
133
  */
44
134
  project_id: string;
45
135
  /**
46
136
  * Firestore Database ID
137
+ * The specific database within the Firebase project
138
+ * Default is usually '(default)'
47
139
  */
48
140
  database_id: string;
49
141
  /**
50
- * Application ID
142
+ * Application ID - Your app's unique identifier
143
+ * This ID determines which data the user can access
144
+ * All your Firestore paths should include this app_id for proper data isolation
51
145
  */
52
146
  app_id?: string;
53
147
  /**
54
- * User ID
148
+ * User ID (Firebase UID)
149
+ * Use this to construct userData paths: appData/{app_id}/userData/{user_id}/...
150
+ * For guest users, this will be a generated guest user ID
55
151
  */
56
152
  user_id: string;
57
153
  /**
58
- * User role (guest, appadmin, superadmin)
154
+ * User role - Determines write permissions
155
+ * - 'guest': Can read publicRead/publicData, write publicData
156
+ * - 'user': Can read publicRead/publicData, write publicData, read/write own userData
157
+ * - 'admin' or 'appadmin': Can also write to publicRead data
59
158
  */
60
159
  role?: string;
61
160
  /**
62
161
  * Token expiration time in seconds (typically 3600 = 1 hour)
162
+ * After this time, you need to generate a new token or refresh using refresh_token
63
163
  */
64
164
  expires_in: number;
65
165
  }
@@ -115,22 +215,72 @@ interface DataServiceClientOptions {
115
215
  /**
116
216
  * SeaVerse Data Service SDK Client
117
217
  *
118
- * Provides methods to manage Firestore tokens for authenticated users and guests.
218
+ * This client helps you get Firestore access tokens for your application.
219
+ * It supports both authenticated users and guest users.
220
+ *
221
+ * THREE-TIER PERMISSION MODEL:
222
+ * ---------------------------
223
+ * Your Firestore data is organized in three permission levels:
224
+ *
225
+ * 1. publicRead/ - System configs, announcements (Read: Everyone, Write: Admin only)
226
+ * 2. publicData/ - User posts, shared content (Read: Everyone, Write: Everyone)
227
+ * 3. userData/{userId}/ - Private user data (Read/Write: Owner only)
228
+ *
229
+ * QUICK START FOR LLM:
230
+ * -------------------
231
+ * Step 1: Get a Firestore token
232
+ * Step 2: Initialize Firebase with the token
233
+ * Step 3: Access Firestore using the correct data paths
119
234
  *
120
235
  * @example
121
236
  * ```typescript
122
- * // Create client instance
237
+ * // Step 1: Create client and get token
238
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
123
239
  * const client = new DataServiceClient();
124
240
  *
125
- * // Generate Firestore token for authenticated user
126
- * const token = await client.generateFirestoreToken({
127
- * token: 'user-jwt-token',
128
- * app_id: 'your-app-id',
241
+ * // For authenticated users:
242
+ * const tokenResponse = await client.generateFirestoreToken({
243
+ * token: 'user-jwt-token-from-auth-sdk',
244
+ * app_id: 'my-app-123',
245
+ * });
246
+ *
247
+ * // For guest users (no authentication required):
248
+ * const guestResponse = await client.generateGuestFirestoreToken({
249
+ * app_id: 'my-app-123',
250
+ * });
251
+ *
252
+ * // Step 2: Initialize Firebase
253
+ * import { initializeApp } from 'firebase/app';
254
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
255
+ * import { getFirestore, collection, addDoc, getDocs, serverTimestamp } from 'firebase/firestore';
256
+ *
257
+ * const app = initializeApp({ projectId: tokenResponse.project_id });
258
+ * const auth = getAuth(app);
259
+ * await signInWithCustomToken(auth, tokenResponse.custom_token);
260
+ * const db = getFirestore(app);
261
+ *
262
+ * // Step 3: Access Firestore data with correct paths
263
+ * const appId = tokenResponse.app_id;
264
+ * const userId = tokenResponse.user_id;
265
+ *
266
+ * // Write to publicData (everyone can write)
267
+ * await addDoc(collection(db, `appData/${appId}/publicData/posts`), {
268
+ * _appId: appId, // REQUIRED: For data isolation
269
+ * _createdAt: serverTimestamp(), // REQUIRED: Server timestamp
270
+ * _createdBy: userId, // REQUIRED: Current user ID
271
+ * title: 'My Post', // Your custom fields
272
+ * content: 'Hello world'
129
273
  * });
130
274
  *
131
- * // Generate Firestore token for guest
132
- * const guestToken = await client.generateGuestFirestoreToken({
133
- * app_id: 'your-app-id',
275
+ * // Read from publicData (everyone can read)
276
+ * const snapshot = await getDocs(collection(db, `appData/${appId}/publicData/posts`));
277
+ *
278
+ * // Write to userData (only owner can write)
279
+ * await addDoc(collection(db, `appData/${appId}/userData/${userId}/notes`), {
280
+ * _appId: appId, // REQUIRED
281
+ * _createdAt: serverTimestamp(), // REQUIRED
282
+ * _createdBy: userId, // REQUIRED
283
+ * note: 'Private note' // Your custom fields
134
284
  * });
135
285
  * ```
136
286
  */
@@ -140,8 +290,16 @@ declare class DataServiceClient {
140
290
  /**
141
291
  * Generate Firestore token for authenticated user
142
292
  *
143
- * This method generates a Firestore custom token for an authenticated user.
144
- * The user must provide a valid JWT token.
293
+ * Use this method when you have a logged-in user with a valid JWT token.
294
+ * The returned token allows access to:
295
+ * - publicRead data (read only)
296
+ * - publicData (read and write)
297
+ * - userData/{user_id} (read and write own data only)
298
+ *
299
+ * IMPORTANT FOR LLM: After getting the token, you MUST:
300
+ * 1. Initialize Firebase app with the project_id
301
+ * 2. Sign in with the custom_token using signInWithCustomToken()
302
+ * 3. Always include required fields in documents: _appId, _createdAt, _createdBy
145
303
  *
146
304
  * @param request - The request containing user token and app ID
147
305
  * @param options - Additional axios request configuration
@@ -149,22 +307,53 @@ declare class DataServiceClient {
149
307
  *
150
308
  * @example
151
309
  * ```typescript
152
- * const response = await client.generateFirestoreToken({
153
- * token: 'user-jwt-token',
154
- * app_id: 'my-app',
310
+ * // First, get user token from Auth SDK
311
+ * import { AuthClient } from '@seaverse/auth-sdk';
312
+ * const authClient = new AuthClient({ appId: 'my-app-123' });
313
+ * const loginResponse = await authClient.loginWithEmail({
314
+ * email: 'user@example.com',
315
+ * password: 'password123'
155
316
  * });
156
317
  *
157
- * console.log('Firestore ID Token:', response.id_token);
158
- * console.log('User ID:', response.user_id);
159
- * console.log('Expires in:', response.expires_in, 'seconds');
318
+ * // Then, get Firestore token
319
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
320
+ * const dataClient = new DataServiceClient();
321
+ * const firestoreToken = await dataClient.generateFirestoreToken({
322
+ * token: loginResponse.token, // JWT token from auth
323
+ * app_id: 'my-app-123'
324
+ * });
325
+ *
326
+ * console.log('Firestore Custom Token:', firestoreToken.custom_token);
327
+ * console.log('User ID:', firestoreToken.user_id);
328
+ * console.log('App ID:', firestoreToken.app_id);
329
+ * console.log('Token expires in:', firestoreToken.expires_in, 'seconds');
330
+ *
331
+ * // Now initialize Firebase and use Firestore
332
+ * import { initializeApp } from 'firebase/app';
333
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
334
+ * import { getFirestore } from 'firebase/firestore';
335
+ *
336
+ * const app = initializeApp({ projectId: firestoreToken.project_id });
337
+ * const auth = getAuth(app);
338
+ * await signInWithCustomToken(auth, firestoreToken.custom_token);
339
+ * const db = getFirestore(app);
340
+ * // Ready to use Firestore!
160
341
  * ```
161
342
  */
162
343
  generateFirestoreToken(request: GenerateFirestoreTokenRequest, options?: AxiosRequestConfig): Promise<FirestoreTokenResponse>;
163
344
  /**
164
- * Generate Firestore token for guest user
345
+ * Generate Firestore token for guest user (no authentication required)
165
346
  *
166
- * This method generates a Firestore custom token for a guest (unauthenticated) user.
167
- * No user authentication token is required.
347
+ * Use this method when you want to allow anonymous users to access your app.
348
+ * Guest users have limited permissions:
349
+ * - publicRead data (read only)
350
+ * - publicData (read and write, but cannot access other users' data)
351
+ * - CANNOT access userData (no private data access)
352
+ *
353
+ * IMPORTANT FOR LLM:
354
+ * - Guest users get a temporary user_id (e.g., 'guest-abc123')
355
+ * - Still need to include required fields: _appId, _createdAt, _createdBy
356
+ * - Great for public forums, comment sections, or demo apps
168
357
  *
169
358
  * @param request - The request containing app ID
170
359
  * @param options - Additional axios request configuration
@@ -172,13 +361,39 @@ declare class DataServiceClient {
172
361
  *
173
362
  * @example
174
363
  * ```typescript
175
- * const response = await client.generateGuestFirestoreToken({
176
- * app_id: 'my-app',
364
+ * // Get guest token (no user authentication needed!)
365
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
366
+ * const client = new DataServiceClient();
367
+ *
368
+ * const guestToken = await client.generateGuestFirestoreToken({
369
+ * app_id: 'my-app-123'
370
+ * });
371
+ *
372
+ * console.log('Guest Firestore Custom Token:', guestToken.custom_token);
373
+ * console.log('Guest User ID:', guestToken.user_id); // e.g., 'guest-abc123'
374
+ * console.log('Role:', guestToken.role); // 'guest'
375
+ *
376
+ * // Initialize Firebase with guest token
377
+ * import { initializeApp } from 'firebase/app';
378
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
379
+ * import { getFirestore, collection, addDoc, serverTimestamp } from 'firebase/firestore';
380
+ *
381
+ * const app = initializeApp({ projectId: guestToken.project_id });
382
+ * const auth = getAuth(app);
383
+ * await signInWithCustomToken(auth, guestToken.custom_token);
384
+ * const db = getFirestore(app);
385
+ *
386
+ * // Guest can write to publicData
387
+ * await addDoc(collection(db, `appData/${guestToken.app_id}/publicData/comments`), {
388
+ * _appId: guestToken.app_id,
389
+ * _createdAt: serverTimestamp(),
390
+ * _createdBy: guestToken.user_id, // Guest user ID
391
+ * comment: 'Great app!',
392
+ * rating: 5
177
393
  * });
178
394
  *
179
- * console.log('Guest Firestore ID Token:', response.id_token);
180
- * console.log('Guest User ID:', response.user_id);
181
- * console.log('Role:', response.role); // 'guest'
395
+ * // Guest CANNOT write to userData (this will fail)
396
+ * // await addDoc(collection(db, `appData/${guestToken.app_id}/userData/${guestToken.user_id}/notes`), ...);
182
397
  * ```
183
398
  */
184
399
  generateGuestFirestoreToken(request: GenerateGuestFirestoreTokenRequest, options?: AxiosRequestConfig): Promise<FirestoreTokenResponse>;