CommunityModule is the social layer for customers. Three surfaces, 116 routes in all: /client/community/* for the customer app (82 routes), /community/* for the older networking API (26 routes), and /social/topics/* for the Listening feature's keyword rules (8 routes). A socket gateway on the /community-chat namespace carries live messages.
Every community record is keyed by the person's email, read from the signed-in customer (data.email). Routes that need a person return 401 when there is none.
The community app tutorial builds a client on these routes; Event App networking uses the connection and messaging half.
Who may write
/client/community/*has no class-level role. Routes markedpubliccarry@PublicRoute()and still read the viewer when one is signed in, so private content shows to members./community/*is@Roles(RoleType.User)at class level./social/topics/*has no@Rolesor@StaffOnly; it needs a valid token.- A customer (or the site's app token acting for one) may not create, update, publish, approve or delete any
community_*record through/repository/*or/upstream/save-integration. The JWT guard refuses with "Use the community endpoints to change community records". Staff with content permissions can still use the repository, which is how held posts get approved.
Pages
/client/community/pagesNo auth/client/community/pages/mineJWT/client/community/pages/:pageIdNo auth/client/community/pagesJWT/client/community/pages/:pageIdJWT/client/community/pages/:pageId/joinJWT/client/community/pages/:pageId/leaveJWT/client/community/pages/:pageId/inviteJWT/client/community/pages/:pageId/membersNo authA page (community_page) is a group or space; membership is community_page_member with a role (owner, admin, member) and status. The creator becomes owner. Only owners and admins may update a page, invite people or add anyone other than themselves.
visibility: public pages are readable by anyone; others only by active members. Pages indraft,archivedorremovedstatus read as 404.joinPolicy:openjoins at once,approval_requiredcreates apendingmembership,invite_onlyrefuses a self-join. Abannedmember cannot rejoin or leave.postingPolicy:anyone,members(default) oradmins_only.moderationLevel: pre_approveholds posts and stories from non-admins aspending.
Update accepts only: title, slug, type, description, shortDescription, category, tags, status, coverImage, logo, images, visibility, joinPolicy, postingPolicy, moderationLevel, features, website.
Creating an event auto-creates a public, open page linked to it (linkedEntity); creating an event_ticket adds the holderEmail to that page as a member. See Events.
Feed, posts and comments
/client/community/feedNo auth/client/community/postsJWT/client/community/posts/:postIdNo auth/client/community/posts/:postIdJWT/client/community/posts/:postIdJWT/client/community/posts/:postId/shareJWT/client/community/posts/:postId/voteJWT/client/community/posts/:postId/commentsNo auth/client/community/posts/:postId/commentsJWT/client/community/comments/:commentIdJWTThe feed filters by page, author, type, hashtag, and sorts latest (default) or trending (by reaction count). It shows only posts from pages the viewer can read, hides private posts from everyone but the author, and hides pending/draft posts from everyone but the author. Signed-in viewers get viewerLiked and viewerSaved on each post.
Posting to a page follows that page's posting policy and moderation level. #tags and @mentions are pulled from the content; each hashtag is counted in community_hashtag. Only the author may edit or delete; delete sets status: removed. Editing a page post re-applies moderation. Page posts, private posts and held posts cannot be shared. A poll vote is refused twice unless poll.allowMultiple. Comments nest one level via parentComment.
Reactions and hashtags
/client/community/reactJWT/client/community/reactionsNo auth/client/community/hashtags/trendingNo authreact takes target, targetType and type. Only post and comment targets are accepted. Sending the same type again removes it; a different type replaces it. Counts land in stats.reactions and reactionSummary. hashtags/trending currently returns an empty list.
Stories
/client/community/storiesNo auth/client/community/storiesJWT/client/community/stories/:storyId/viewJWT/client/community/stories/:storyIdJWTA story expires 24 hours after creation unless highlight is set. The list returns the active stories and the same stories grouped by author. Page stories follow the page's posting and moderation rules.
Follows, bookmarks, notifications, badges
/client/community/followJWT/client/community/follow/:followingIdJWT/client/community/followersJWT/client/community/followingJWT/client/community/bookmarksJWT/client/community/bookmarksJWT/client/community/bookmarks/:targetJWT/client/community/notificationsJWT/client/community/notifications/readJWT/client/community/notifications/read-allJWT/client/community/notifications/unread-countJWT/client/community/badgesNo auth/client/community/badges/mineJWTA follow targets a person or a page (followingType); following twice returns the existing record. badges lists community_badge records not retired; badges/mine currently returns an empty list.
Announcements
/client/community/pages/:pageId/announcementsNo auth/client/community/announcements/:announcementIdNo auth/client/community/pages/:pageId/announcementsJWTOnly page owners and admins may create one. Reading follows the page's visibility.
People
/client/community/peopleNo auth/client/community/people/suggestionsJWT/client/community/people/:emailNo authpeople?page=<pageId>&q= searches that page's members; without page it returns an empty list. people/:email returns a public profile only: name, image, company, job title, bio, city, country, interests, social. people/suggestions returns an empty list for now.
Group chats
/client/community/groupsJWT/client/community/groupsJWT/client/community/groups/:groupIdJWT/client/community/groups/:groupId/messagesJWT/client/community/groups/:groupId/messagesJWT/client/community/groups/:groupId/membersJWT/client/community/groups/:groupId/members/:emailJWTThe creator is the group admin. Only members can read a group (others get 404); only admins add members or remove someone else; anyone may remove themselves. A group tied to a page can only be created by a page admin.
Connections, direct messages, meetings, blocking
The same 26 routes exist twice: under /client/community/* (customer; 401 without an email) and under /community/* (@Roles(User)).
/client/community/connections/requestJWT/client/community/connections/:id/respondJWT/client/community/connectionsJWT/client/community/connections/pendingJWT/client/community/connections/sentJWT/client/community/connections/statsJWT/client/community/connections/accept-allJWT/client/community/connections/:idJWT/client/community/messagesJWT/client/community/messages/threadsJWT/client/community/messages/thread/:userIdJWT/client/community/messages/readJWT/client/community/messages/thread/:userId/readJWT/client/community/messages/:idJWT/client/community/messages/unread-countJWT/client/community/meetingsJWT/client/community/meetingsJWT/client/community/meetings/upcomingJWT/client/community/meetings/:idJWT/client/community/meetings/:id/respondJWT/client/community/meetings/:idJWT/client/community/meetings/:idJWT/client/community/blocksJWT/client/community/blocks/:userIdJWT/client/community/blocksJWT/client/community/reportsJWT- Connections (
community_connection): only the target may accept or reject apendingrequest. A second request while pending, connected or blocked is refused. - Messages (
community_message): connection is not required, but a block in either direction refuses the send. AreplyTomust be in the same one-to-one thread. Delete hides the message for the caller only. - Meetings (
community_meeting): the organizer must be connected with every participant. It startsproposedand becomesconfirmedwhen all accept. Only the organizer can edit; changing the time resets every response. Organizer or participants may cancel.upcominglists confirmed meetings from now. - Blocks and reports (
community_block): blocking marks any connection between the two asblocked. A report is acommunity_blockwithreported: trueandreportStatus: pending; a second pending report on the same person is refused. Staff review them on the operator side:GET /community/reportslists the pending ones andPOST /community/reports/:id/reviewtakes{ action: action_taken | dismissed, notes }. Both are staff-only — never a customer or the site's app token.
Media
/client/community/media/uploadJWT/client/community/media/mineJWT/client/community/media/renameJWT/client/community/media/:pathJWTUploads (multipart field file) are stored under community/<email>/media/ and belong to the uploader; posts, stories and profiles reference the URL. Rename and delete only accept a path inside the caller's own folder, and a new name may not contain directory separators.
Live chat socket
Namespace /community-chat, websocket transport. Connect with auth: { token, orgId } using a customer token. Client events: sendMessage, sendGroupMessage, typing, groupTyping, markRead, getOnlineUsers, joinGroup, leaveGroup. Server events include message, groupMessage, typing, groupTyping, onlineUsers, onlineStatus, joinedGroup, leftGroup and error. Sends go through the same services as the REST routes, so the same block and membership rules apply.
Social listening topics
/social/topicsJWT/social/topics/:idJWT/social/topicsJWT/social/topics/:idJWT/social/topics/:idJWT/social/topics/testJWT/social/topics/backfillJWT/social/topics/:id/backfillJWTA topic (social_topic, a string datatype, not in the DataType enum) is a saved rule: patterns (each a string or { value, mode: keyword | phrase | regex, caseSensitive }), excludePatterns, optional platforms and activityTypes, and enabled. It triggers nothing; matches are written to social_activity.topicMatches[]. test dry-runs a topic against a sample without saving. backfill rescans recent social_activity rows (default 30 days, days in the body) and rewrites only the matches for the scanned topics. Deleting a topic leaves its old matches until the next scan.
Datatypes
community_page, community_page_member, community_post, community_comment, community_reaction, community_hashtag, community_story, community_follow, community_bookmark, community_notification, community_announcement, community_badge, community_group_chat, community_message, community_connection, community_meeting, community_block, plus social_topic and social_activity.