Update groups API
This commit is contained in:
parent
2ee067c072
commit
5af92a7d81
|
@ -54,6 +54,10 @@ Returns the authenticated user.
|
|||
|
||||
Gets all groups, in no particular order.
|
||||
|
||||
Parameters:
|
||||
- `availableToUserId`: Optional. if specified, only groups that the user can
|
||||
join and groups they've already joined will be returned.
|
||||
|
||||
Requires no authorization.
|
||||
|
||||
### `GET /v0/groups/[slug]`
|
||||
|
@ -62,12 +66,18 @@ Gets a group by its slug.
|
|||
|
||||
Requires no authorization.
|
||||
|
||||
### `GET /v0/groups/by-id/[id]`
|
||||
### `GET /v0/group/by-id/[id]`
|
||||
|
||||
Gets a group by its unique ID.
|
||||
|
||||
Requires no authorization.
|
||||
|
||||
### `GET /v0/group/by-id/[id]/markets`
|
||||
|
||||
Gets a group's markets by its unique ID.
|
||||
|
||||
Requires no authorization.
|
||||
|
||||
### `GET /v0/markets`
|
||||
|
||||
Lists all markets, ordered by creation date descending.
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
updateDoc,
|
||||
where,
|
||||
} from 'firebase/firestore'
|
||||
import { uniq } from 'lodash'
|
||||
import { uniq, uniqBy } from 'lodash'
|
||||
import { Group, GROUP_CHAT_SLUG, GroupLink } from 'common/group'
|
||||
import {
|
||||
coll,
|
||||
|
@ -21,7 +21,7 @@ import {
|
|||
listenForValues,
|
||||
} from './utils'
|
||||
import { Contract } from 'common/contract'
|
||||
import { updateContract } from 'web/lib/firebase/contracts'
|
||||
import { getContractFromId, updateContract } from 'web/lib/firebase/contracts'
|
||||
import { db } from 'web/lib/firebase/init'
|
||||
import { filterDefined } from 'common/util/array'
|
||||
import { getUser } from 'web/lib/firebase/users'
|
||||
|
@ -31,6 +31,9 @@ export const groupMembers = (groupId: string) =>
|
|||
collection(groups, groupId, 'groupMembers')
|
||||
export const groupContracts = (groupId: string) =>
|
||||
collection(groups, groupId, 'groupContracts')
|
||||
const openGroupsQuery = query(groups, where('anyoneCanJoin', '==', true))
|
||||
const memberGroupsQuery = (userId: string) =>
|
||||
query(collectionGroup(db, 'groupMembers'), where('userId', '==', userId))
|
||||
|
||||
export function groupPath(
|
||||
groupSlug: string,
|
||||
|
@ -78,23 +81,24 @@ export function listenForGroupContractDocs(
|
|||
return listenForValues(groupContracts(groupId), setContractDocs)
|
||||
}
|
||||
|
||||
export function listenForOpenGroups(setGroups: (groups: Group[]) => void) {
|
||||
return listenForValues(
|
||||
query(groups, where('anyoneCanJoin', '==', true)),
|
||||
setGroups
|
||||
export async function listGroupContracts(groupId: string) {
|
||||
const contractDocs = await getValues<{
|
||||
contractId: string
|
||||
createdTime: number
|
||||
}>(groupContracts(groupId))
|
||||
return Promise.all(
|
||||
contractDocs.map((doc) => getContractFromId(doc.contractId))
|
||||
)
|
||||
}
|
||||
|
||||
export function listenForOpenGroups(setGroups: (groups: Group[]) => void) {
|
||||
return listenForValues(openGroupsQuery, setGroups)
|
||||
}
|
||||
|
||||
export function getGroup(groupId: string) {
|
||||
return getValue<Group>(doc(groups, groupId))
|
||||
}
|
||||
|
||||
export function getGroupContracts(groupId: string) {
|
||||
return getValues<{ contractId: string; createdTime: number }>(
|
||||
groupContracts(groupId)
|
||||
)
|
||||
}
|
||||
|
||||
export async function getGroupBySlug(slug: string) {
|
||||
const q = query(groups, where('slug', '==', slug))
|
||||
const docs = (await getDocs(q)).docs
|
||||
|
@ -112,10 +116,7 @@ export function listenForMemberGroupIds(
|
|||
userId: string,
|
||||
setGroupIds: (groupIds: string[]) => void
|
||||
) {
|
||||
const q = query(
|
||||
collectionGroup(db, 'groupMembers'),
|
||||
where('userId', '==', userId)
|
||||
)
|
||||
const q = memberGroupsQuery(userId)
|
||||
return onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => {
|
||||
if (snapshot.metadata.fromCache) return
|
||||
|
||||
|
@ -136,6 +137,24 @@ export function listenForMemberGroups(
|
|||
})
|
||||
}
|
||||
|
||||
export async function listAvailableGroups(userId: string) {
|
||||
const [openGroups, memberGroupSnapshot] = await Promise.all([
|
||||
getValues<Group>(openGroupsQuery),
|
||||
getDocs(memberGroupsQuery(userId)),
|
||||
])
|
||||
const memberGroups = filterDefined(
|
||||
await Promise.all(
|
||||
memberGroupSnapshot.docs.map((doc) => {
|
||||
return doc.ref.parent.parent?.id
|
||||
? getGroup(doc.ref.parent.parent?.id)
|
||||
: null
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
return uniqBy([...openGroups, ...memberGroups], (g) => g.id)
|
||||
}
|
||||
|
||||
export async function addUserToGroupViaId(groupId: string, userId: string) {
|
||||
// get group to get the member ids
|
||||
const group = await getGroup(groupId)
|
||||
|
|
18
web/pages/api/v0/group/by-id/[id]/markets.ts
Normal file
18
web/pages/api/v0/group/by-id/[id]/markets.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { applyCorsHeaders, CORS_UNRESTRICTED } from 'web/lib/api/cors'
|
||||
import { listGroupContracts } from 'web/lib/firebase/groups'
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
await applyCorsHeaders(req, res, CORS_UNRESTRICTED)
|
||||
const { id } = req.query
|
||||
const contracts = await listGroupContracts(id as string)
|
||||
if (!contracts) {
|
||||
res.status(404).json({ error: 'Group not found' })
|
||||
return
|
||||
}
|
||||
res.setHeader('Cache-Control', 'no-cache')
|
||||
return res.status(200).json(contracts)
|
||||
}
|
|
@ -1,14 +1,42 @@
|
|||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { listAllGroups } from 'web/lib/firebase/groups'
|
||||
import { listAllGroups, listAvailableGroups } from 'web/lib/firebase/groups'
|
||||
import { applyCorsHeaders, CORS_UNRESTRICTED } from 'web/lib/api/cors'
|
||||
import { z } from 'zod'
|
||||
import { validate } from 'web/pages/api/v0/_validate'
|
||||
import { ValidationError } from 'web/pages/api/v0/_types'
|
||||
|
||||
type Data = any[]
|
||||
const queryParams = z
|
||||
.object({
|
||||
availableToUserId: z.string().optional(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<Data>
|
||||
res: NextApiResponse
|
||||
) {
|
||||
await applyCorsHeaders(req, res, CORS_UNRESTRICTED)
|
||||
let params: z.infer<typeof queryParams>
|
||||
try {
|
||||
params = validate(queryParams, req.query)
|
||||
} catch (e) {
|
||||
if (e instanceof ValidationError) {
|
||||
return res.status(400).json(e)
|
||||
}
|
||||
console.error(`Unknown error during validation: ${e}`)
|
||||
return res.status(500).json({ error: 'Unknown error during validation' })
|
||||
}
|
||||
|
||||
const { availableToUserId } = params
|
||||
|
||||
// TODO: should we check if the user is a real user?
|
||||
if (availableToUserId) {
|
||||
const groups = await listAvailableGroups(availableToUserId)
|
||||
res.setHeader('Cache-Control', 'max-age=0')
|
||||
res.status(200).json(groups)
|
||||
return
|
||||
}
|
||||
|
||||
const groups = await listAllGroups()
|
||||
res.setHeader('Cache-Control', 'max-age=0')
|
||||
res.status(200).json(groups)
|
||||
|
|
Loading…
Reference in New Issue
Block a user