Group Schema

Planned — not yet live. The group feature is not implemented. This schema reflects the intended Firestore structure based on the product doc.

Firestore Document (groups/{groupId})

Field Type Required Constraints Description
id string yes non-empty Unique group identifier (nanoId); matches document ID
name string yes 3–100 chars, non-empty trimmed Display name of the group
description string yes non-empty trimmed Group description; visible to all users regardless of type
poster string \| null no valid URL Cover image URL
ownerId string yes non-empty UID of the group owner; changes only via ownership transfer
adminsId string[] yes UIDs of group admins; may be empty
type "public" \| "private" yes enum public = listed in discovery feed; private = invite-only
baseLocation.name string yes non-empty Human-readable city or neighbourhood name
baseLocation.lat number yes −90 to 90 WGS-84 latitude
baseLocation.lng number yes −180 to 180 WGS-84 longitude
inviteCode string \| null yes non-empty when set Rotating invite code; null when invite is disabled. Embed in link as ?code={inviteCode}
settings.requireApproval boolean yes If true, new members require owner/admin approval
settings.inviteEnabled boolean yes Whether invite link and QR code are enabled
settings.allowAdminChangeName boolean yes default false Whether admins (not just owner) can change the group name
settings.allowAdminChangeDescription boolean yes default true Whether admins can change the group description
settings.allowMembersToCreateRides boolean yes default false Whether any member can create rides; when false, only admins can
archivedAt Timestamp \| null yes Set when the group is archived; null for active groups
deletedAt Timestamp \| null no Set when the group is soft-deleted; triggers DeleteGroupWorkflow
memberCount number yes integer ≥ 1 Denormalised count of current members; updated on join/leave/remove
createdAt Timestamp yes server-set Document creation time
updatedAt Timestamp yes server-set Last modification time; changes on group property or settings updates; does NOT change when members join or leave
{
  "id": "grp_abc123",
  "name": "Bangalore Riders",
  "description": "Weekend rides across Karnataka",
  "poster": "https://example.com/poster.jpg",
  "ownerId": "uid_owner",
  "adminsId": ["uid_admin1"],
  "type": "public",
  "baseLocation": {
    "name": "Bangalore",
    "lat": 12.9716,
    "lng": 77.5946,
  },
  "inviteCode": "x7kP2mQn", // null when inviteEnabled is false
  "settings": {
    "requireApproval": true,
    "inviteEnabled": true,
    "allowAdminChangeName": false,
    "allowAdminChangeDescription": true,
    "allowMembersToCreateRides": false,
  },
  "archivedAt": null,
  "deletedAt": null,
  "memberCount": 24,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "updatedAt": "2025-06-01T08:00:00.000Z",
}

Sub-collections

groups/{groupId}/members/{userId}

Field Type Required Constraints Description
id string yes non-empty UID of the member (matches document ID)
name string yes non-empty Display name at time of joining (denormalised)
photoUrl string \| null no valid URL Profile photo URL at time of joining (denormalised)
role "owner" \| "admin" \| "member" yes enum Member's role in the group
joinedAt Timestamp yes server-set When the member joined
createdAt Timestamp yes server-set Document creation time
updatedAt Timestamp yes server-set Changes on role change or profile update
{
  "id": "uid_rider",
  "name": "Arjun Mehta",
  "photoUrl": "https://example.com/avatar.jpg",
  "role": "member", // "owner" | "admin" | "member"
  "joinedAt": "2025-02-01T10:00:00.000Z",
  "createdAt": "2025-02-01T10:00:00.000Z",
  "updatedAt": "2025-02-01T10:00:00.000Z",
}

groups/{groupId}/requests/{requestId}

Temporary records for pending join requests. Deleted when approved or rejected.

Field Type Required Constraints Description
id string yes non-empty Request ID (nanoId); matches document ID
type "join" yes enum Request type; currently only "join"
userId string yes non-empty UID of the requesting user
name string yes non-empty Display name of the requester (denormalised)
photoUrl string \| null no valid URL Avatar URL of the requester (denormalised)
createdAt Timestamp yes server-set When the request was submitted
{
  "id": "req_xyz789",
  "type": "join",
  "userId": "uid_requester",
  "name": "Priya Sharma",
  "photoUrl": "https://example.com/avatar.jpg",
  "createdAt": "2025-06-01T09:00:00.000Z",
}

User Membership Index

Group membership for a user is also tracked in the user's groups sub-collection: users/{userId}/groups/{groupId} — see User Schema.

Indexes

Fields Query Type Reason
type asc + archivedAt asc + baseLocation.lat asc Composite Public group discovery by proximity (active groups only)
type asc + archivedAt asc + baseLocation.name asc Composite Public group discovery by city name search
ownerId asc Single-field Fetch all groups owned by a user
archivedAt asc Single-field Find groups eligible for archiving scan
deletedAt asc Single-field Find groups pending deletion cleanup