manifold/functions/src/create-group.ts
Ian Philips 3b3717d307
Groups (#510)
* Folds=>groups

* Show groups on user profile

* Allow group creation from /create

* Refactoring to groups

* Convert folds to groups

* Add new add to group notification

* Fix user profile tab bug

* Add groups nav and tab for my groups

* Remove bad profile pages

* remove comments

* Add group list dropdown to sidebar

* remove unused

* group cards ui

* Messages=>Comments, v2, groupDetails

* Discussion time

* Cleaning up some code

* Remove follow count

* Fix pool scoring for cpmm

* Fix imports

* Simplify rules, add GroupUser collection

* Fix group cards

* Refactor

* Refactor

* Small fixes

* Remove string

* Add api error detail handling

* Clear name field

* Componentize

* Spacing

* Undo userpage memo

* Member groups are already in my tab

* Remove active contracts reference for now

* Remove unused

* Refactoring

* Allow adding old questions to a group

* Rename

* Wording

* Throw standard v2 APIError

* Hide input for non-members, add about under title

* Multiple names to & # more

* Move comments firestore rules to appropriate subpaths

* Group membership, pool=>volume

* Cleanup, useEvent

* Raise state to parent

* Eliminate unused

* Cleaning up

* Clean code

* Revert tags input deletion

* Cleaning code

* Stylling

* Limit members to display

* Array cleanup

* Add categories back in

* Private=>closed

* Unused vars
2022-06-22 11:35:50 -05:00

88 lines
2.2 KiB
TypeScript

import * as admin from 'firebase-admin'
import { getUser } from './utils'
import { Contract } from '../../common/contract'
import { slugify } from '../../common/util/slugify'
import { randomString } from '../../common/util/random'
import {
Group,
MAX_ABOUT_LENGTH,
MAX_GROUP_NAME_LENGTH,
MAX_ID_LENGTH,
} from '../../common/group'
import { APIError, newEndpoint, validate } from '../../functions/src/api'
import { z } from 'zod'
const bodySchema = z.object({
name: z.string().min(1).max(MAX_GROUP_NAME_LENGTH),
memberIds: z.array(z.string().min(1).max(MAX_ID_LENGTH)),
anyoneCanJoin: z.boolean(),
about: z.string().min(1).max(MAX_ABOUT_LENGTH).optional(),
})
export const creategroup = newEndpoint(['POST'], async (req, auth) => {
const { name, about, memberIds, anyoneCanJoin } = validate(
bodySchema,
req.body
)
const creator = await getUser(auth.uid)
if (!creator)
throw new APIError(400, 'No user exists with the authenticated user ID.')
// Add creator id to member ids for convenience
if (!memberIds.includes(creator.id)) memberIds.push(creator.id)
console.log(
'creating group for',
creator.username,
'named',
name,
'about',
about,
'other member ids',
memberIds
)
const slug = await getSlug(name)
const groupRef = firestore.collection('groups').doc()
const group: Group = {
id: groupRef.id,
creatorId: creator.id,
slug,
name,
about: about ?? '',
createdTime: Date.now(),
mostRecentActivityTime: Date.now(),
// TODO: allow users to add contract ids on group creation
contractIds: [],
anyoneCanJoin,
memberIds,
}
await groupRef.create(group)
return { status: 'success', group: group }
})
const getSlug = async (name: string) => {
const proposedSlug = slugify(name)
const preexistingGroup = await getGroupFromSlug(proposedSlug)
return preexistingGroup ? proposedSlug + '-' + randomString() : proposedSlug
}
const firestore = admin.firestore()
export async function getGroupFromSlug(slug: string) {
const snap = await firestore
.collection('groups')
.where('slug', '==', slug)
.get()
return snap.empty ? undefined : (snap.docs[0].data() as Contract)
}