Database Overview
Database Name:cric_talkDatabase ID:
695761d00008fd927f78Platform: Appwrite TablesDB
Status: Enabled CricTalk uses Appwrite’s TablesDB with row-level security for access control. The schema consists of 7 tables handling posts, comments, chat rooms, users, notifications, and rate limiting.
Schema Relationships
Table: posts
Table ID: postsRow Security: Enabled
Description: User-generated posts with engagement tracking
Columns
Post content text
- Max Size: 512 characters
- Indexed: Full-text search enabled
Array of image URLs or file IDs
- Max Size: 4 items
- Element Size: Standard string
Reference to the post creator’s user ID
- Max Size: 36 characters (UUID)
- Indexed: Ascending index for author queries
- Relationship: users.$id
Denormalized author username for display
- Max Size: 36 characters
- Purpose: Avoid joins on user table for list views
Total like count
- Range: -9223372036854775808 to 9223372036854775807
- Default: 0
- Indexed: Descending for popularity sorting
Array of user IDs who liked the post
- Max Size: 1024 items
- Element Size: Standard string
- Purpose: Track like status per user, prevent duplicate likes
Total view count
- Range: -9223372036854775808 to 9223372036854775807
- Default: 0
- Indexed: Descending for trending posts
Array of user IDs who viewed the post
- Max Size: 1024 items
- Element Size: Standard string
- Purpose: Ensure unique view counting
Total number of comments
- Range: -9223372036854775808 to 9223372036854775807
- Default: 0
- Indexed: Ascending
- Updated: Incremented via comments-guard function
Indexes
authorId_index
authorId_index
likes_index
likes_index
Type: Key Index
Column:
Order: DESC
Use Case: Sort posts by popularity (most liked first)
Column:
likesOrder: DESC
Use Case: Sort posts by popularity (most liked first)
views_index
views_index
Type: Key Index
Column:
Order: DESC
Use Case: Trending posts, most viewed content
Column:
viewsOrder: DESC
Use Case: Trending posts, most viewed content
commentCount_index
commentCount_index
Type: Key Index
Column:
Order: ASC
Use Case: Filter posts by engagement level
Column:
commentCountOrder: ASC
Use Case: Filter posts by engagement level
createdAt_index
createdAt_index
Type: Key Index
Column:
Order: DESC
Use Case: Chronological feed (newest first)
Column:
$createdAt (system field)Order: DESC
Use Case: Chronological feed (newest first)
updatedAt_index
updatedAt_index
Type: Key Index
Column:
Order: DESC
Use Case: Recently edited posts
Column:
$updatedAt (system field)Order: DESC
Use Case: Recently edited posts
index_7 (Full-Text)
index_7 (Full-Text)
Type: Full-Text Index
Column:
Order: ASC
Use Case: Search posts by content keywords
Column:
contentOrder: ASC
Use Case: Search posts by content keywords
Row-Level Security
Permissions:- Read:
Role.users()- Any authenticated user can read - Update:
Role.user(authorId)- Only post author can update - Delete:
Role.user(authorId)- Only post author can delete
Table: comments
Table ID: commentsRow Security: Enabled
Description: Comments on posts
Columns
ID of the parent post
- Max Size: 36 characters (UUID)
- Indexed: Ascending for post-comment lookups
- Relationship: posts.$id
ID of the comment author
- Max Size: 36 characters (UUID)
- Relationship: users.$id
Comment text content
- Max Size: 512 characters
Flag indicating if comment has been modified
- Default: false
- Purpose: Show “edited” indicator in UI
Indexes
index_postId
index_postId
Type: Key Index
Column:
Order: ASC
Use Case: Fetch all comments for a specific post
Column:
postIdOrder: ASC
Use Case: Fetch all comments for a specific post
index_createdAt
index_createdAt
Type: Key Index
Column:
Order: DESC
Use Case: Display comments chronologically
Column:
$createdAt (system field)Order: DESC
Use Case: Display comments chronologically
Row-Level Security
Permissions:- Read:
Role.users()- Any authenticated user - Update:
Role.user(authorId)- Only comment author - Delete:
Role.user(authorId)- Only comment author
Table: rooms
Table ID: roomsRow Security: Enabled
Description: Live chat rooms for cricket match discussions
Columns
Array of team names playing in the match
- Max Size: Variable
- Element Size: 36 characters
- Example:
["India", "Australia"]
Match start date and time
- Format: ISO 8601 datetime
- Purpose: Schedule room availability
Match end date and time
- Format: ISO 8601 datetime
- Purpose: Auto-close rooms after match
Type of cricket match
- Max Size: 32 characters
- Examples: “T20”, “ODI”, “Test”
Whether the room is locked (no new messages)
- Default: false
- Purpose: Moderate or close rooms
Username of room creator
- Max Size: 36 characters
User ID of room creator
- Max Size: 36 characters (UUID)
- Relationship: users.$id
Indexes
No custom indexes defined (relies on system indexes).Row-Level Security
Permissions:- Read:
Role.users()- Any authenticated user - Update:
Role.user(authorId)- Only room creator - Delete:
Role.user(authorId)- Only room creator
Table: roomMessaage
Table ID: roommessaage (note: typo in original schema)Row Security: Enabled
Description: Messages within chat rooms
Columns
ID of the parent room
- Max Size: 36 characters (UUID)
- Relationship: rooms.$id
ID of the message sender
- Max Size: 36 characters (UUID)
- Relationship: users.$id
Username of message sender (denormalized)
- Max Size: 36 characters
Message text content
- Max Size: 512 characters
Whether the message has been edited
- Default: false
Indexes
No custom indexes defined.Row-Level Security
Permissions:- Read:
Role.users()- Any authenticated user in room - Update:
Role.user(authorId)- Only message author - Delete:
Role.user(authorId)- Only message author
Table: users
Table ID: usersRow Security: Disabled
Description: Extended user profile data (supplements Appwrite auth users)
This table stores additional user data beyond what Appwrite’s built-in auth system provides. It does NOT have row security enabled, allowing global read access for user lookups.
Columns
User’s display name
- Max Size: 36 characters
- Source: From Appwrite user.name or email prefix
Total number of messages sent by user
- Range: -9223372036854775808 to 9223372036854775807
- Default: 0
- Purpose: Leaderboard and activity tracking
Array of Expo push notification tokens
- Max Size: Variable
- Element Size: 120 characters (Expo token format)
- Purpose: Support multiple devices per user
- Example:
["ExponentPushToken[xxxxx]", "ExponentPushToken[yyyyy]"]
Indexes
No custom indexes defined.Row-Level Security
Status: DisabledReasoning: User profiles are publicly readable for displaying usernames, message counts, etc. Push tokens are managed server-side only.
Table: notifications
Table ID: notificationsRow Security: Enabled
Description: In-app notification records
Columns
ID of the user receiving the notification
- Max Size: 36 characters (UUID)
- Indexed: Ascending for user notification queries
- Relationship: users.$id
Notification title/heading
- Max Size: 32 characters
- Examples: “New Comment”, “Post Liked”
Notification body text
- Max Size: 512 characters
- Examples: “John commented on your post”, “Your post received 10 likes”
Indexes
userId_index
userId_index
Type: Key Index
Column:
Order: ASC
Use Case: Fetch all notifications for a user
Column:
userIdOrder: ASC
Use Case: Fetch all notifications for a user
createdAt_index
createdAt_index
Type: Key Index
Column:
Order: DESC
Use Case: Display notifications in chronological order (newest first)
Column:
$createdAt (system field)Order: DESC
Use Case: Display notifications in chronological order (newest first)
Row-Level Security
Permissions:- Read:
Role.user(userId)- Only the recipient can read their notifications - Update: None (notifications are read-only after creation)
- Delete:
Role.user(userId)- User can clear their notifications
Table: rateLimit
Table ID: ratelimitRow Security: Disabled
Description: Rate limiting tracking using sliding window algorithm
Columns
ID of the user being rate limited
- Max Size: 36 characters (UUID)
- Indexed: Ascending for user lookups
- Relationship: users.$id
Type of activity being rate limited
- Max Size: 36 characters
- Indexed: Ascending for activity-specific queries
- Values:
create_post,update_post,delete_post,create_comment,send_message, etc.
Time window identifier (Unix timestamp / 60000)
- Range: -9223372036854775808 to 9223372036854775807
- Indexed: Ascending for window lookups
- Calculation:
Math.floor(Date.now() / 60000) - Purpose: Groups requests into 1-minute windows
Number of requests in current window
- Range: 1 to 60
- Default: 1
- Limit: 10 for most activities
- Purpose: Track request count per window
Indexes
userid_index
userid_index
Type: Key Index
Column:
Order: ASC
Use Case: Lookup user’s rate limit records
Column:
userIdOrder: ASC
Use Case: Lookup user’s rate limit records
activity_index
activity_index
Type: Key Index
Column:
Order: ASC
Use Case: Filter by activity type
Column:
activityOrder: ASC
Use Case: Filter by activity type
windowKey_index
windowKey_index
Type: Key Index
Column:
Order: ASC
Use Case: Query current time window
Column:
windowKeyOrder: ASC
Use Case: Query current time window
createdAt_index
createdAt_index
Type: Key Index
Column:
Order: DESC
Use Case: Clean up old rate limit records
Column:
$createdAt (system field)Order: DESC
Use Case: Clean up old rate limit records
Row-Level Security
Status: DisabledReasoning: Rate limit checks are performed server-side via guard functions. Users don’t directly access this table.
Algorithm Details
Window Calculation
Current window key:
Math.floor(Date.now() / 60000)This creates 1-minute time windows that reset every 60 seconds.Subsequent Requests
If record exists:
- Check if
activityCount >= 10 - If yes, reject with rate limit error
- If no, increment
activityCount
System Fields
All tables include Appwrite’s standard system fields:Unique document ID (UUID format)
ISO 8601 timestamp of document creation
ISO 8601 timestamp of last update
Array of permission strings for row-level access control
Migration & Backup
Best Practices
- Schema Changes: Use Appwrite CLI to version control schema changes
- Backups: Export table data regularly using Appwrite’s export functionality
- Indexes: Add indexes before launching features that query large datasets
- Data Integrity: Use serverless functions to enforce foreign key relationships
Performance Considerations
Optimization Tips
- Use Indexes: All query filters should use indexed columns
- Limit Results: Always use
Query.limit()for list views - Pagination: Use
Query.offset()or cursor-based pagination for large datasets - Full-Text Search: The
posts.contentfull-text index enables fast keyword search - Caching: Client-side Zustand stores cache frequently accessed data