feat: add Tags API endpoints and validation schemas
- GET /api/tags — public, filterable by ?pool=craft|cooperative, active only, sorted by label - POST /api/tags/suggest — auth-required, creates TagSuggestion doc - Add tagSuggestionSchema and communityConnectionsUpdateSchema to schemas.js - Extend memberProfileUpdateSchema with craftTags, craftTagsPrivacy, communityConnectionsPrivacy
This commit is contained in:
parent
18b8106405
commit
79d038c724
3 changed files with 56 additions and 1 deletions
16
server/api/tags/index.get.js
Normal file
16
server/api/tags/index.get.js
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import Tag from '../../models/tag.js'
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
await connectDB()
|
||||||
|
|
||||||
|
const query = getQuery(event)
|
||||||
|
const filter = { active: true }
|
||||||
|
|
||||||
|
if (query.pool) {
|
||||||
|
filter.pool = query.pool
|
||||||
|
}
|
||||||
|
|
||||||
|
const tags = await Tag.find(filter).sort({ label: 1 }).lean()
|
||||||
|
|
||||||
|
return { tags }
|
||||||
|
})
|
||||||
17
server/api/tags/suggest.post.js
Normal file
17
server/api/tags/suggest.post.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import TagSuggestion from '../../models/tagSuggestion.js'
|
||||||
|
import { tagSuggestionSchema } from '../../utils/schemas.js'
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
await connectDB()
|
||||||
|
|
||||||
|
const member = await requireAuth(event)
|
||||||
|
const body = await validateBody(event, tagSuggestionSchema)
|
||||||
|
|
||||||
|
await TagSuggestion.create({
|
||||||
|
label: body.label,
|
||||||
|
pool: body.pool,
|
||||||
|
suggestedBy: member._id
|
||||||
|
})
|
||||||
|
|
||||||
|
return { success: true }
|
||||||
|
})
|
||||||
|
|
@ -48,7 +48,10 @@ export const memberProfileUpdateSchema = z.object({
|
||||||
locationPrivacy: privacyEnum.optional(),
|
locationPrivacy: privacyEnum.optional(),
|
||||||
socialLinksPrivacy: privacyEnum.optional(),
|
socialLinksPrivacy: privacyEnum.optional(),
|
||||||
offeringPrivacy: privacyEnum.optional(),
|
offeringPrivacy: privacyEnum.optional(),
|
||||||
lookingForPrivacy: privacyEnum.optional()
|
lookingForPrivacy: privacyEnum.optional(),
|
||||||
|
craftTags: z.array(z.string().max(100)).max(16).optional(),
|
||||||
|
craftTagsPrivacy: privacyEnum.optional(),
|
||||||
|
communityConnectionsPrivacy: privacyEnum.optional()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const eventRegistrationSchema = z.object({
|
export const eventRegistrationSchema = z.object({
|
||||||
|
|
@ -346,3 +349,22 @@ export const memberInviteSchema = z.object({
|
||||||
memberIds: z.array(z.string().min(1)).min(1).max(100),
|
memberIds: z.array(z.string().min(1)).min(1).max(100),
|
||||||
emailTemplate: z.string().min(1).max(10000)
|
emailTemplate: z.string().min(1).max(10000)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// --- Tag schemas ---
|
||||||
|
|
||||||
|
export const tagSuggestionSchema = z.object({
|
||||||
|
label: z.string().min(1).max(100),
|
||||||
|
pool: z.enum(['craft', 'cooperative'])
|
||||||
|
})
|
||||||
|
|
||||||
|
export const communityConnectionsUpdateSchema = z.object({
|
||||||
|
topics: z.array(z.object({
|
||||||
|
tagSlug: z.string().min(1).max(100),
|
||||||
|
state: z.enum(['help', 'interested', 'seeking'])
|
||||||
|
})).max(20).optional(),
|
||||||
|
offerPeerSupport: z.boolean().optional(),
|
||||||
|
availability: z.string().max(500).optional(),
|
||||||
|
slackHandle: z.string().max(200).optional(),
|
||||||
|
personalMessage: z.string().max(2000).optional(),
|
||||||
|
details: z.string().max(300).optional()
|
||||||
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue