@seaverse/data-service-sdk 0.1.0 → 0.2.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.id_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 id_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 ID Token:', firestoreToken.id_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.id_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 ID Token:', guestToken.id_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.id_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,153 @@ 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.id_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
108
  * Firebase ID Token (exchanged from Custom Token)
109
+ * Use this with signInWithCustomToken() to authenticate with Firebase
110
+ * This token expires after the time specified in expires_in (typically 1 hour)
35
111
  */
36
112
  id_token: string;
37
113
  /**
38
114
  * Firebase Refresh Token (optional)
115
+ * Used to refresh the id_token when it expires
116
+ * May not be present for guest users
39
117
  */
40
118
  refresh_token?: string;
41
119
  /**
42
120
  * Firebase Project ID
121
+ * Use this to initialize Firebase app: initializeApp({ projectId: '...' })
43
122
  */
44
123
  project_id: string;
45
124
  /**
46
125
  * Firestore Database ID
126
+ * The specific database within the Firebase project
127
+ * Default is usually '(default)'
47
128
  */
48
129
  database_id: string;
49
130
  /**
50
- * Application ID
131
+ * Application ID - Your app's unique identifier
132
+ * This ID determines which data the user can access
133
+ * All your Firestore paths should include this app_id for proper data isolation
51
134
  */
52
135
  app_id?: string;
53
136
  /**
54
- * User ID
137
+ * User ID (Firebase UID)
138
+ * Use this to construct userData paths: appData/{app_id}/userData/{user_id}/...
139
+ * For guest users, this will be a generated guest user ID
55
140
  */
56
141
  user_id: string;
57
142
  /**
58
- * User role (guest, appadmin, superadmin)
143
+ * User role - Determines write permissions
144
+ * - 'guest': Can read publicRead/publicData, write publicData
145
+ * - 'user': Can read publicRead/publicData, write publicData, read/write own userData
146
+ * - 'admin' or 'appadmin': Can also write to publicRead data
59
147
  */
60
148
  role?: string;
61
149
  /**
62
150
  * Token expiration time in seconds (typically 3600 = 1 hour)
151
+ * After this time, you need to generate a new token or refresh using refresh_token
63
152
  */
64
153
  expires_in: number;
65
154
  }
@@ -115,22 +204,72 @@ interface DataServiceClientOptions {
115
204
  /**
116
205
  * SeaVerse Data Service SDK Client
117
206
  *
118
- * Provides methods to manage Firestore tokens for authenticated users and guests.
207
+ * This client helps you get Firestore access tokens for your application.
208
+ * It supports both authenticated users and guest users.
209
+ *
210
+ * THREE-TIER PERMISSION MODEL:
211
+ * ---------------------------
212
+ * Your Firestore data is organized in three permission levels:
213
+ *
214
+ * 1. publicRead/ - System configs, announcements (Read: Everyone, Write: Admin only)
215
+ * 2. publicData/ - User posts, shared content (Read: Everyone, Write: Everyone)
216
+ * 3. userData/{userId}/ - Private user data (Read/Write: Owner only)
217
+ *
218
+ * QUICK START FOR LLM:
219
+ * -------------------
220
+ * Step 1: Get a Firestore token
221
+ * Step 2: Initialize Firebase with the token
222
+ * Step 3: Access Firestore using the correct data paths
119
223
  *
120
224
  * @example
121
225
  * ```typescript
122
- * // Create client instance
226
+ * // Step 1: Create client and get token
227
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
123
228
  * const client = new DataServiceClient();
124
229
  *
125
- * // Generate Firestore token for authenticated user
126
- * const token = await client.generateFirestoreToken({
127
- * token: 'user-jwt-token',
128
- * app_id: 'your-app-id',
230
+ * // For authenticated users:
231
+ * const tokenResponse = await client.generateFirestoreToken({
232
+ * token: 'user-jwt-token-from-auth-sdk',
233
+ * app_id: 'my-app-123',
234
+ * });
235
+ *
236
+ * // For guest users (no authentication required):
237
+ * const guestResponse = await client.generateGuestFirestoreToken({
238
+ * app_id: 'my-app-123',
239
+ * });
240
+ *
241
+ * // Step 2: Initialize Firebase
242
+ * import { initializeApp } from 'firebase/app';
243
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
244
+ * import { getFirestore, collection, addDoc, getDocs, serverTimestamp } from 'firebase/firestore';
245
+ *
246
+ * const app = initializeApp({ projectId: tokenResponse.project_id });
247
+ * const auth = getAuth(app);
248
+ * await signInWithCustomToken(auth, tokenResponse.id_token);
249
+ * const db = getFirestore(app);
250
+ *
251
+ * // Step 3: Access Firestore data with correct paths
252
+ * const appId = tokenResponse.app_id;
253
+ * const userId = tokenResponse.user_id;
254
+ *
255
+ * // Write to publicData (everyone can write)
256
+ * await addDoc(collection(db, `appData/${appId}/publicData/posts`), {
257
+ * _appId: appId, // REQUIRED: For data isolation
258
+ * _createdAt: serverTimestamp(), // REQUIRED: Server timestamp
259
+ * _createdBy: userId, // REQUIRED: Current user ID
260
+ * title: 'My Post', // Your custom fields
261
+ * content: 'Hello world'
129
262
  * });
130
263
  *
131
- * // Generate Firestore token for guest
132
- * const guestToken = await client.generateGuestFirestoreToken({
133
- * app_id: 'your-app-id',
264
+ * // Read from publicData (everyone can read)
265
+ * const snapshot = await getDocs(collection(db, `appData/${appId}/publicData/posts`));
266
+ *
267
+ * // Write to userData (only owner can write)
268
+ * await addDoc(collection(db, `appData/${appId}/userData/${userId}/notes`), {
269
+ * _appId: appId, // REQUIRED
270
+ * _createdAt: serverTimestamp(), // REQUIRED
271
+ * _createdBy: userId, // REQUIRED
272
+ * note: 'Private note' // Your custom fields
134
273
  * });
135
274
  * ```
136
275
  */
@@ -140,8 +279,16 @@ declare class DataServiceClient {
140
279
  /**
141
280
  * Generate Firestore token for authenticated user
142
281
  *
143
- * This method generates a Firestore custom token for an authenticated user.
144
- * The user must provide a valid JWT token.
282
+ * Use this method when you have a logged-in user with a valid JWT token.
283
+ * The returned token allows access to:
284
+ * - publicRead data (read only)
285
+ * - publicData (read and write)
286
+ * - userData/{user_id} (read and write own data only)
287
+ *
288
+ * IMPORTANT FOR LLM: After getting the token, you MUST:
289
+ * 1. Initialize Firebase app with the project_id
290
+ * 2. Sign in with the id_token using signInWithCustomToken()
291
+ * 3. Always include required fields in documents: _appId, _createdAt, _createdBy
145
292
  *
146
293
  * @param request - The request containing user token and app ID
147
294
  * @param options - Additional axios request configuration
@@ -149,22 +296,53 @@ declare class DataServiceClient {
149
296
  *
150
297
  * @example
151
298
  * ```typescript
152
- * const response = await client.generateFirestoreToken({
153
- * token: 'user-jwt-token',
154
- * app_id: 'my-app',
299
+ * // First, get user token from Auth SDK
300
+ * import { AuthClient } from '@seaverse/auth-sdk';
301
+ * const authClient = new AuthClient({ appId: 'my-app-123' });
302
+ * const loginResponse = await authClient.loginWithEmail({
303
+ * email: 'user@example.com',
304
+ * password: 'password123'
155
305
  * });
156
306
  *
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');
307
+ * // Then, get Firestore token
308
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
309
+ * const dataClient = new DataServiceClient();
310
+ * const firestoreToken = await dataClient.generateFirestoreToken({
311
+ * token: loginResponse.token, // JWT token from auth
312
+ * app_id: 'my-app-123'
313
+ * });
314
+ *
315
+ * console.log('Firestore ID Token:', firestoreToken.id_token);
316
+ * console.log('User ID:', firestoreToken.user_id);
317
+ * console.log('App ID:', firestoreToken.app_id);
318
+ * console.log('Token expires in:', firestoreToken.expires_in, 'seconds');
319
+ *
320
+ * // Now initialize Firebase and use Firestore
321
+ * import { initializeApp } from 'firebase/app';
322
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
323
+ * import { getFirestore } from 'firebase/firestore';
324
+ *
325
+ * const app = initializeApp({ projectId: firestoreToken.project_id });
326
+ * const auth = getAuth(app);
327
+ * await signInWithCustomToken(auth, firestoreToken.id_token);
328
+ * const db = getFirestore(app);
329
+ * // Ready to use Firestore!
160
330
  * ```
161
331
  */
162
332
  generateFirestoreToken(request: GenerateFirestoreTokenRequest, options?: AxiosRequestConfig): Promise<FirestoreTokenResponse>;
163
333
  /**
164
- * Generate Firestore token for guest user
334
+ * Generate Firestore token for guest user (no authentication required)
335
+ *
336
+ * Use this method when you want to allow anonymous users to access your app.
337
+ * Guest users have limited permissions:
338
+ * - publicRead data (read only)
339
+ * - publicData (read and write, but cannot access other users' data)
340
+ * - CANNOT access userData (no private data access)
165
341
  *
166
- * This method generates a Firestore custom token for a guest (unauthenticated) user.
167
- * No user authentication token is required.
342
+ * IMPORTANT FOR LLM:
343
+ * - Guest users get a temporary user_id (e.g., 'guest-abc123')
344
+ * - Still need to include required fields: _appId, _createdAt, _createdBy
345
+ * - Great for public forums, comment sections, or demo apps
168
346
  *
169
347
  * @param request - The request containing app ID
170
348
  * @param options - Additional axios request configuration
@@ -172,13 +350,39 @@ declare class DataServiceClient {
172
350
  *
173
351
  * @example
174
352
  * ```typescript
175
- * const response = await client.generateGuestFirestoreToken({
176
- * app_id: 'my-app',
353
+ * // Get guest token (no user authentication needed!)
354
+ * import { DataServiceClient } from '@seaverse/data-service-sdk';
355
+ * const client = new DataServiceClient();
356
+ *
357
+ * const guestToken = await client.generateGuestFirestoreToken({
358
+ * app_id: 'my-app-123'
359
+ * });
360
+ *
361
+ * console.log('Guest Firestore ID Token:', guestToken.id_token);
362
+ * console.log('Guest User ID:', guestToken.user_id); // e.g., 'guest-abc123'
363
+ * console.log('Role:', guestToken.role); // 'guest'
364
+ *
365
+ * // Initialize Firebase with guest token
366
+ * import { initializeApp } from 'firebase/app';
367
+ * import { getAuth, signInWithCustomToken } from 'firebase/auth';
368
+ * import { getFirestore, collection, addDoc, serverTimestamp } from 'firebase/firestore';
369
+ *
370
+ * const app = initializeApp({ projectId: guestToken.project_id });
371
+ * const auth = getAuth(app);
372
+ * await signInWithCustomToken(auth, guestToken.id_token);
373
+ * const db = getFirestore(app);
374
+ *
375
+ * // Guest can write to publicData
376
+ * await addDoc(collection(db, `appData/${guestToken.app_id}/publicData/comments`), {
377
+ * _appId: guestToken.app_id,
378
+ * _createdAt: serverTimestamp(),
379
+ * _createdBy: guestToken.user_id, // Guest user ID
380
+ * comment: 'Great app!',
381
+ * rating: 5
177
382
  * });
178
383
  *
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'
384
+ * // Guest CANNOT write to userData (this will fail)
385
+ * // await addDoc(collection(db, `appData/${guestToken.app_id}/userData/${guestToken.user_id}/notes`), ...);
182
386
  * ```
183
387
  */
184
388
  generateGuestFirestoreToken(request: GenerateGuestFirestoreTokenRequest, options?: AxiosRequestConfig): Promise<FirestoreTokenResponse>;