@seaverse/data-service-sdk 0.7.0 → 0.8.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 CHANGED
@@ -30,8 +30,8 @@ SeaVerse organizes your Firestore data into three permission levels:
30
30
 
31
31
  | Permission Level | Path Pattern | Read Access | Write Access | Use Case |
32
32
  |-----------------|--------------|-------------|--------------|----------|
33
- | **publicRead** | `appData/{app_id}/publicRead/{collection}/{docId}` | All authenticated users | Admin only | System configs, announcements, static content |
34
- | **publicData** | `appData/{app_id}/publicData/{collection}/{docId}` | All authenticated users | All authenticated users | User posts, comments, shared content |
33
+ | **publicRead** | `appData/{app_id}/publicRead/_data/{collection}/{docId}` | All authenticated users | Admin only | System configs, announcements, static content |
34
+ | **publicData** | `appData/{app_id}/publicData/_data/{collection}/{docId}` | All authenticated users | All authenticated users | User posts, comments, shared content |
35
35
  | **userData** | `appData/{app_id}/userData/{user_id}/{collection}/{docId}` | Owner only | Owner only | User settings, private notes, personal data |
36
36
 
37
37
  ### 🚨 CRITICAL: Firestore Path Rules (For LLM)
@@ -39,33 +39,31 @@ SeaVerse organizes your Firestore data into three permission levels:
39
39
  **Firestore path segments MUST follow these rules:**
40
40
 
41
41
  1. **Collection paths = ODD number of segments** (1, 3, 5, 7...)
42
- - Example: `appData/my-app/publicData/posts` (4 segments) WRONG!
43
- - Correct: Use collection() function, Firestore handles this automatically
42
+ - Example: `appData/my-app/publicData/_data/posts` (5 segments) CORRECT!
43
+ - Firestore requires odd-numbered segments for collections
44
44
 
45
45
  2. **Document paths = EVEN number of segments** (2, 4, 6, 8...)
46
- - Example: `appData/my-app/publicData/posts/doc123` (5 segments) ✅ CORRECT!
46
+ - Example: `appData/my-app/publicData/_data/posts/doc123` (6 segments) ✅ CORRECT!
47
47
 
48
48
  3. **How to use correctly:**
49
49
 
50
50
  ```typescript
51
- // ✅ CORRECT - Using collection() for collection paths
52
- collection(db, `appData/${appId}/publicData/posts`) // Firestore handles this as a collection
51
+ // ✅ CORRECT - Collection paths have ODD segments
52
+ collection(db, `appData/${appId}/publicData/_data/posts`) // 5 segments (odd)
53
53
 
54
- // ✅ CORRECT - Using doc() for document paths
55
- doc(db, `appData/${appId}/publicData/posts/doc123`) // 5 segments (odd) = document
54
+ // ✅ CORRECT - Document paths have EVEN segments
55
+ doc(db, `appData/${appId}/publicData/_data/posts/doc123`) // 6 segments (even)
56
56
 
57
- // WRONG - Manually counting segments
58
- // Don't worry about counting! Use Firebase functions:
59
- // - collection() for collections
60
- // - doc() for documents
61
- // - addDoc() automatically adds document ID
57
+ // 💡 TIP: Always use path helper functions to avoid counting!
58
+ // - getPublicDataPath(appId, 'posts') // Returns correct collection path
59
+ // - getPublicDataDocPath(appId, 'posts', 'doc123') // Returns correct document path
62
60
  ```
63
61
 
64
62
  **Path Structure Examples:**
65
63
 
66
64
  ```typescript
67
65
  // Public Data (everyone can read/write)
68
- const postsRef = collection(db, `appData/${appId}/publicData/posts`);
66
+ const postsRef = collection(db, `appData/${appId}/publicData/_data/posts`);
69
67
  await addDoc(postsRef, { ...data }); // Firestore adds document ID
70
68
 
71
69
  // User Private Data (owner only)
@@ -73,13 +71,14 @@ const notesRef = collection(db, `appData/${appId}/userData/${userId}/notes`);
73
71
  await addDoc(notesRef, { ...data });
74
72
 
75
73
  // Public Read-Only (everyone can read, admin can write)
76
- const configRef = collection(db, `appData/${appId}/publicRead/config`);
74
+ const configRef = collection(db, `appData/${appId}/publicRead/_data/config`);
77
75
  await getDocs(configRef);
78
76
  ```
79
77
 
80
78
  **The pattern is always:**
81
- - `appData` → `{app_id}` → `{permission_layer}` → `{collection}` → (auto-generated doc ID)
82
- - This gives you 5 segments total = document path
79
+ - `appData` → `{app_id}` → `{permission_layer}` → `_data` → `{collection}` → (auto-generated doc ID)
80
+ - Collection: 5 segments (odd)
81
+ - Document: 6 segments (even) ✅
83
82
 
84
83
  ### Required Fields
85
84
 
@@ -549,7 +548,7 @@ const tokenResponse = await client.generateGuestFirestoreToken({ app_id: 'my-app
549
548
  const { db, appId, userId } = await initializeWithToken(tokenResponse);
550
549
 
551
550
  // Ready to use Firestore
552
- await addDoc(collection(db, `appData/${appId}/publicData/posts`), { ... });
551
+ await addDoc(collection(db, `appData/${appId}/publicData/_data/posts`), { ... });
553
552
  ```
554
553
 
555
554
  **Note:** This function requires Firebase SDK to be installed separately:
@@ -563,7 +562,7 @@ npm install firebase
563
562
 
564
563
  ```typescript
565
564
  // Anyone (including guests) can post comments
566
- await addDoc(collection(db, `appData/${appId}/publicData/comments`), {
565
+ await addDoc(collection(db, `appData/${appId}/publicData/_data/comments`), {
567
566
  _appId: appId,
568
567
  _createdAt: serverTimestamp(),
569
568
  _createdBy: userId,
@@ -574,7 +573,7 @@ await addDoc(collection(db, `appData/${appId}/publicData/comments`), {
574
573
 
575
574
  // Anyone can read comments
576
575
  const comments = await getDocs(
577
- collection(db, `appData/${appId}/publicData/comments`)
576
+ collection(db, `appData/${appId}/publicData/_data/comments`)
578
577
  );
579
578
  ```
580
579
 
@@ -603,7 +602,7 @@ const settings = await getDoc(
603
602
  // Only admins can write to publicRead
604
603
  // Regular users and guests can only read
605
604
  const announcements = await getDocs(
606
- collection(db, `appData/${appId}/publicRead/announcements`)
605
+ collection(db, `appData/${appId}/publicRead/_data/announcements`)
607
606
  );
608
607
 
609
608
  announcements.forEach(doc => {
@@ -618,7 +617,7 @@ import { query, where, orderBy, limit } from 'firebase/firestore';
618
617
 
619
618
  // Query posts created by a specific user
620
619
  const userPosts = query(
621
- collection(db, `appData/${appId}/publicData/posts`),
620
+ collection(db, `appData/${appId}/publicData/_data/posts`),
622
621
  where('_createdBy', '==', userId),
623
622
  orderBy('_createdAt', 'desc'),
624
623
  limit(10)
@@ -789,7 +788,7 @@ async function completeExample() {
789
788
 
790
789
  // 4. Create a post (publicData)
791
790
  const postRef = await addDoc(
792
- collection(db, `appData/${appId}/publicData/posts`),
791
+ collection(db, `appData/${appId}/publicData/_data/posts`),
793
792
  {
794
793
  _appId: appId,
795
794
  _createdAt: serverTimestamp(),
@@ -803,7 +802,7 @@ async function completeExample() {
803
802
 
804
803
  // 5. Read all posts
805
804
  const postsSnapshot = await getDocs(
806
- collection(db, `appData/${appId}/publicData/posts`)
805
+ collection(db, `appData/${appId}/publicData/_data/posts`)
807
806
  );
808
807
  postsSnapshot.forEach(doc => {
809
808
  console.log('Post:', doc.id, doc.data());
@@ -811,7 +810,7 @@ async function completeExample() {
811
810
 
812
811
  // 6. Query user's own posts
813
812
  const myPostsQuery = query(
814
- collection(db, `appData/${appId}/publicData/posts`),
813
+ collection(db, `appData/${appId}/publicData/_data/posts`),
815
814
  where('_createdBy', '==', userId)
816
815
  );
817
816
  const myPosts = await getDocs(myPostsQuery);
package/dist/browser.js CHANGED
@@ -4200,7 +4200,7 @@ class DataServiceClient {
4200
4200
  * ```typescript
4201
4201
  * // Read system announcements
4202
4202
  * const path = getPublicReadPath('my-app', 'announcements');
4203
- * // Returns: 'appData/my-app/publicRead/announcements'
4203
+ * // Returns: 'appData/my-app/publicRead/_data/announcements'
4204
4204
  *
4205
4205
  * const snapshot = await getDocs(collection(db, path));
4206
4206
  * ```
@@ -4208,7 +4208,7 @@ class DataServiceClient {
4208
4208
  function getPublicReadPath(appId, collectionName) {
4209
4209
  validateSegment('appId', appId);
4210
4210
  validateSegment('collectionName', collectionName);
4211
- return `appData/${appId}/publicRead/${collectionName}`;
4211
+ return `appData/${appId}/publicRead/_data/${collectionName}`;
4212
4212
  }
4213
4213
  /**
4214
4214
  * Generate path for publicData (read/write for all authenticated users)
@@ -4221,7 +4221,7 @@ function getPublicReadPath(appId, collectionName) {
4221
4221
  * ```typescript
4222
4222
  * // Write a public post
4223
4223
  * const path = getPublicDataPath('my-app', 'posts');
4224
- * // Returns: 'appData/my-app/publicData/posts'
4224
+ * // Returns: 'appData/my-app/publicData/_data/posts'
4225
4225
  *
4226
4226
  * await addDoc(collection(db, path), {
4227
4227
  * _appId: appId,
@@ -4234,7 +4234,7 @@ function getPublicReadPath(appId, collectionName) {
4234
4234
  function getPublicDataPath(appId, collectionName) {
4235
4235
  validateSegment('appId', appId);
4236
4236
  validateSegment('collectionName', collectionName);
4237
- return `appData/${appId}/publicData/${collectionName}`;
4237
+ return `appData/${appId}/publicData/_data/${collectionName}`;
4238
4238
  }
4239
4239
  /**
4240
4240
  * Generate path for userData (private, read/write only by owner)
@@ -4275,7 +4275,7 @@ function getUserDataPath(appId, userId, collectionName) {
4275
4275
  * @example
4276
4276
  * ```typescript
4277
4277
  * const path = getPublicReadDocPath('my-app', 'announcements', 'announcement-1');
4278
- * // Returns: 'appData/my-app/publicRead/announcements/announcement-1'
4278
+ * // Returns: 'appData/my-app/publicRead/_data/announcements/announcement-1'
4279
4279
  *
4280
4280
  * const docSnap = await getDoc(doc(db, path));
4281
4281
  * ```
@@ -4284,7 +4284,7 @@ function getPublicReadDocPath(appId, collectionName, docId) {
4284
4284
  validateSegment('appId', appId);
4285
4285
  validateSegment('collectionName', collectionName);
4286
4286
  validateSegment('docId', docId);
4287
- return `appData/${appId}/publicRead/${collectionName}/${docId}`;
4287
+ return `appData/${appId}/publicRead/_data/${collectionName}/${docId}`;
4288
4288
  }
4289
4289
  /**
4290
4290
  * Generate path for a specific document in publicData
@@ -4297,7 +4297,7 @@ function getPublicReadDocPath(appId, collectionName, docId) {
4297
4297
  * @example
4298
4298
  * ```typescript
4299
4299
  * const path = getPublicDataDocPath('my-app', 'posts', 'post-123');
4300
- * // Returns: 'appData/my-app/publicData/posts/post-123'
4300
+ * // Returns: 'appData/my-app/publicData/_data/posts/post-123'
4301
4301
  *
4302
4302
  * const docSnap = await getDoc(doc(db, path));
4303
4303
  * ```
@@ -4306,7 +4306,7 @@ function getPublicDataDocPath(appId, collectionName, docId) {
4306
4306
  validateSegment('appId', appId);
4307
4307
  validateSegment('collectionName', collectionName);
4308
4308
  validateSegment('docId', docId);
4309
- return `appData/${appId}/publicData/${collectionName}/${docId}`;
4309
+ return `appData/${appId}/publicData/_data/${collectionName}/${docId}`;
4310
4310
  }
4311
4311
  /**
4312
4312
  * Generate path for a specific document in userData