@lastshotlabs/slingshot-community
npm install @lastshotlabs/slingshot-community
Functions
Section titled “Functions”createCommunityPackage
Section titled “createCommunityPackage”Create the community package using the definePackage authoring path.
Wires all 19 community entities — each entity module uses
wiring: { mode: 'manual', buildAdapter } so the package factory can
capture the resolved adapter into a closure-owned CommunityAdapterRefs
bag for adapter-dependent middleware and event subscribers.
Cross-package contracts:
- Requires
slingshot-permissionsforPermissionsState. - Requires
slingshot-notificationsforNotificationsBuilderFactoryCap. - Publishes
CommunityInteractionsPeerCapfor consumers (notablyslingshot-interactions).
Optional integrations (duck-typed):
slingshot-push— when present, registers push formatters for community notification types.slingshot-embeds— when present, unfurls links in thread/reply bodies and writes the resolved embeds back viaattachEmbeds.
function createCommunityPackage(rawConfig: CommunityPluginConfig,): SlingshotPackageDefinitionSource: packages/slingshot-community/src/plugin.ts
ThreadEntity
Section titled “ThreadEntity”Entity definition for a community thread (topic post).
Exported as ThreadEntity from the package index. Threads are searchable
(syncMode: 'write-through') — the search plugin indexes them automatically
on every create/update.
Remarks: Key operations: - publish: draft → published state transition; sets publishedAt. - lock / unlock: toggle the locked flag (prevents new replies). - pin / unpin: toggle the pinned flag. - listByContainer: paginated lookup by container. - search: full-text search on title and body.
Remarks: Cascade: when auth:user.deleted fires, all threads by that user are soft-deleted (status → 'deleted', deletedBy set).
Source: packages/slingshot-community/src/entities/thread.ts
threadOperations
Section titled “threadOperations”Custom operations for the Thread entity.
publish: draft → published state transition.lock/unlock: toggle the locked flag.pin/unpin: toggle the pinned flag.listByContainer: paginated lookup filtered bycontainerId.search: full-text search on title and body within a container.searchInContainer: multi-filter search withq,tag,authorId, andstatusquery params. Route:GET container/:containerId/threads/search.listByContainerSorted: sorted thread listing with sort preset and optional time-window filter. Route:GET container/:containerId/threads.
Source: packages/slingshot-community/src/entities/thread.ts
Constants
Section titled “Constants”AuditLogEntryEntity
Section titled “AuditLogEntryEntity”Entity definition for a moderation audit log entry.
Audit entries are server-only (no create/update/delete HTTP routes). They are created by middleware after moderation actions (bans, report resolutions, warnings, etc.).
Source: packages/slingshot-community/src/entities/auditLogEntry.ts
auditLogEntryOperations
Section titled “auditLogEntryOperations”Custom operations for the AuditLogEntry entity.
listByContainer: Audit entries for a container (paginated).listByActor: Audit entries by a specific actor.
Source: packages/slingshot-community/src/entities/auditLogEntry.ts
AutoModRuleEntity
Section titled “AutoModRuleEntity”Entity definition for an auto-moderation rule.
Rules are evaluated by AutoModEvaluator in the autoMod middleware
pipeline. Each rule has a matcher (keyword, regex, or heuristic) and
a decision (flag, reject, or shadow-ban).
Source: packages/slingshot-community/src/entities/autoModRule.ts
autoModRuleOperations
Section titled “autoModRuleOperations”Custom operations for the AutoModRule entity.
listActive: All enabled rules for a container (includes global rules).
Source: packages/slingshot-community/src/entities/autoModRule.ts
BanEntity
Section titled “BanEntity”Entity definition for a user ban.
Exported as BanEntity from the package index.
Remarks: Bans are never hard-deleted; they are lifted by the removeBan batch operation which sets unbannedBy and unbannedAt. The banCheck middleware queries the ban store on every thread/reply creation request and returns 403 if an active ban exists.
Remarks: The banNotify middleware fires after a ban is created, emitting a community:user.banned event and creating an in-app notification for the banned user.
Source: packages/slingshot-community/src/entities/ban.ts
banOperations
Section titled “banOperations”Custom operations for the Ban entity.
isUserBanned: boolean check for an active ban on (userId, containerId).getUserBan: fetch the active ban record for a user.removeBan: batch-update all matching bans to setunbannedByandunbannedAt(i.e. lift the ban). Requires thecommunity:container.lift-banpermission.
Source: packages/slingshot-community/src/entities/ban.ts
BookmarkEntity
Section titled “BookmarkEntity”Entity definition for a user bookmark.
Bookmarks let users save threads or replies for later. An optional
tag field supports user-defined categorization.
Source: packages/slingshot-community/src/entities/bookmark.ts
bookmarkOperations
Section titled “bookmarkOperations”Custom operations for the Bookmark entity.
isBookmarked: Check if a target is bookmarked by the caller.listByUser: All bookmarks for a user.
Source: packages/slingshot-community/src/entities/bookmark.ts
Community
Section titled “Community”Source: packages/slingshot-community/src/public.ts
COMMUNITY_PLUGIN_STATE_KEY
Section titled “COMMUNITY_PLUGIN_STATE_KEY”Plugin state key for slingshot-community (string form).
Single-sourced constant — no magic string 'slingshot-community' in
cross-package contracts. Kept for back-compat with consumers that use
pluginState.get(COMMUNITY_PLUGIN_STATE_KEY) directly.
New code should prefer the typed reference CommunityPluginStateRef
with readPluginState / publishPluginState so the value type is checked
at the call site.
Source: packages/slingshot-community/src/types/state.ts
CommunityEntities
Section titled “CommunityEntities”Read-only adapter surface for community entities.
Cross-package consumers (SSR loaders, search indexers, application-defined plugins) resolve adapters with:
import { CommunityEntities } from '@lastshotlabs/slingshot-community';import { requireEntityAdapter } from '@lastshotlabs/slingshot-core';
const containers = requireEntityAdapter(carrier, CommunityEntities.Container);const c = await containers.getBySlug('cool-community');The exposed methods are the canonical lookup paths used elsewhere in this
package’s HTTP routes; readonly([...]) enforces the slice at runtime.
Mutation paths (create/update/delete) are intentionally excluded — those go through the HTTP routes, server actions, or the entity event bus so the full middleware chain (banCheck, autoMod, threadStateGuard, …) runs.
Source: packages/slingshot-community/src/public.ts
CommunityInteractionsPeerCap
Section titled “CommunityInteractionsPeerCap”Source: packages/slingshot-community/src/public.ts
communityPluginConfigSchema
Section titled “communityPluginConfigSchema”Zod validation schema for CommunityPluginConfig.
Used by createCommunityPackage() to validate the raw config object at
construction time via validatePluginConfig(). Exported so callers can
pre-validate config before passing it in, or use it to generate JSON Schema
for tooling.
Remarks: The schema is intentionally JSON-safe for config-driven mode. Live runtime objects such as permissions adapters, admin gates, and callback hooks are resolved from plugin/app state during setup rather than accepted here.
Config Fields
Section titled “Config Fields”| Field | Description |
|---|---|
| `/** Controls who can create containers. ‘admin’ = admin-scoped permission; ‘user’ = any authenticated user. */ | |
| containerCreation` | Who can create containers. One of: admin, user. |
/** Mount path for community routes. Default | URL path prefix for community routes. Omit to use ‘/community’. |
Source: packages/slingshot-community/src/types/config.ts
ContainerEntity
Section titled “ContainerEntity”Entity definition for a community container (space/channel).
Exported as ContainerEntity from the package index to avoid name collision
with the Container model interface.
Remarks: Soft-delete is enabled via the deletedAt field. The getBySlug custom operation provides URL-routing by slug and optional tenant scope.
Remarks: Container creation is gated by the containerCreationGuard middleware, which enforces the containerCreation: 'admin' | 'user' policy from the plugin config.
Source: packages/slingshot-community/src/entities/container.ts
ContainerInviteEntity
Section titled “ContainerInviteEntity”Entity definition for a container invite link.
Invite links carry a unique capability token. Anyone with the token can join the container (subject to ban checks and use-count limits).
Remarks: Key operations: - redeemInvite: Atomic claim + member creation. - claimInviteSlot: Internal atomic claim (no HTTP route). - releaseInviteSlot: Internal compensating op (no HTTP route).
Source: packages/slingshot-community/src/entities/containerInvite.ts
containerInviteOperations
Section titled “containerInviteOperations”Custom operations for the ContainerInvite entity.
findByToken: Capability-based lookup by token.redeemInvite: Atomic claim + join flow. Handler wired in plugin.listByContainer: All invites for a container.claimInviteSlot: Internal atomic claim (no HTTP route).releaseInviteSlot: Internal compensating release (no HTTP route).
Source: packages/slingshot-community/src/entities/containerInvite.ts
ContainerMemberEntity
Section titled “ContainerMemberEntity”Entity definition for a container membership record.
Exported as ContainerMemberEntity from the package index.
Remarks: The create route is treated as a self-join endpoint: the authenticated user may only create their own membership and the effective role is always normalized to member. Elevated roles are granted only through assignRole.
Remarks: The assignRole upsert operation allows role changes without deleting the existing membership. The grantManager middleware reconciles the backing permission grants after promotions, demotions, and removals.
Remarks: Cascade: when auth:user.deleted fires, all memberships for that user are hard-deleted.
Source: packages/slingshot-community/src/entities/containerMember.ts
containerMemberModule
Section titled “containerMemberModule”Package-authoring module for ContainerMember. See containerModule for rationale.
Source: packages/slingshot-community/src/entities/containerMember.ts
containerMemberOperations
Section titled “containerMemberOperations”Custom operations for the ContainerMember entity.
listByRole: members of a container filtered by role.getMember: look up a single membership by containerId + userId.isMember: boolean existence check for a (containerId, userId) pair.assignRole: upsert a member’s role without dropping the record.removeUserMemberships: batch-delete all memberships for a user (used by the user-deletion cascade).
Source: packages/slingshot-community/src/entities/containerMember.ts
containerModule
Section titled “containerModule”Package-authoring module for Container. Used by Community.publicEntities
(in ../public.ts) to expose the canonical adapter surface to cross-package
consumers via Community.publicEntity(containerModule).readonly([...]).
Source: packages/slingshot-community/src/entities/container.ts
containerOperations
Section titled “containerOperations”Custom operations for the Container entity.
getBySlug: looks up a container by its URL-safe slug and optional tenantId.
Source: packages/slingshot-community/src/entities/container.ts
ContainerRuleEntity
Section titled “ContainerRuleEntity”Entity definition for a community rule displayed to container members.
Exported as ContainerRuleEntity from the package index.
Remarks: Rules are ordered by the order field (ascending). Create multiple rules and set order values to control display sequence. Updating order re-sorts without deleting and re-creating records. There is no enforced uniqueness on order, so stable sort by createdAt is used as a tie-breaker.
Remarks: Container rules have no auth gate on scoped reads. Write operations require container settings management permission.
Source: packages/slingshot-community/src/entities/containerRule.ts
containerRuleOperations
Section titled “containerRuleOperations”Custom operations for the ContainerRule entity.
listByContainer: all rules for a container, ordered by theorderfield.
Source: packages/slingshot-community/src/entities/containerRule.ts
ContainerSettingEntity
Section titled “ContainerSettingEntity”Entity definition for per-container moderation settings.
Overrides plugin-level defaults for slow mode, word filters, and rate limits. Read by middleware at request time.
Source: packages/slingshot-community/src/entities/containerSetting.ts
containerSettingOperations
Section titled “containerSettingOperations”Custom operations for the ContainerSetting entity.
getByContainer: Lookup settings by containerId.
Source: packages/slingshot-community/src/entities/containerSetting.ts
ContainerSubscriptionEntity
Section titled “ContainerSubscriptionEntity”Entity definition for a user’s subscription to a container.
Controls notification delivery preferences at the container level.
notifyOn determines which events generate notifications.
Source: packages/slingshot-community/src/entities/containerSubscription.ts
containerSubscriptionOperations
Section titled “containerSubscriptionOperations”Custom operations for the ContainerSubscription entity.
listSubscribers: All subscribers for a container.getSubscription: Single subscription lookup by userId + containerId.
Source: packages/slingshot-community/src/entities/containerSubscription.ts
DEFAULT_SCORING_CONFIG
Section titled “DEFAULT_SCORING_CONFIG”Default scoring config — used when config.scoring is not provided.
Source: packages/slingshot-community/src/types/config.ts
ReactionEntity
Section titled “ReactionEntity”Entity definition for a user reaction (upvote, downvote, or emoji) on a thread or reply.
Exported as ReactionEntity from the package index.
Remarks: The updateScore custom operation is the core of the scoring system. It is adapter-only (no HTTP route) and is injected by reactionBuildAdapter in plugin.ts with a handler that reads config.scoring from the plugin config closure. The handler: 1. Lists all reactions for the target entity. 2. Computes the score using the configured algorithm (computeNetScore / computeHotScore / computeControversialScore). 3. Writes score and reactionSummary back to the target thread or reply.
Remarks: Cascade: when auth:user.deleted fires, all reactions by that user are hard-deleted.
Source: packages/slingshot-community/src/entities/reaction.ts
reactionModule
Section titled “reactionModule”Package-authoring module for Reaction. See containerModule for rationale.
Source: packages/slingshot-community/src/entities/reaction.ts
reactionOperations
Section titled “reactionOperations”Custom operations for the Reaction entity.
listByTarget: all reactions on a specific thread or reply.updateScore: adapter-only op (no HTTP route). Handler injected byreactionBuildAdapterinplugin.ts. Aggregates reactions, computes the configured algorithm’s score, and writesscore+reactionSummaryto the target thread or reply.
Source: packages/slingshot-community/src/entities/reaction.ts
ReplyEntity
Section titled “ReplyEntity”Entity definition for a reply within a thread.
Exported as ReplyEntity from the package index. Replies are searchable
(syncMode: 'write-through').
Remarks: Reply creation is gated by threadStateGuard (blocks replies to locked or deleted threads), banCheck (blocks banned users), and autoMod.
Remarks: Cascade: when auth:user.deleted fires, all replies by that user are soft-deleted.
Source: packages/slingshot-community/src/entities/reply.ts
replyModule
Section titled “replyModule”Package-authoring module for Reply. See containerModule for rationale.
Source: packages/slingshot-community/src/entities/reply.ts
replyOperations
Section titled “replyOperations”Custom operations for the Reply entity.
listByThread: paginated lookup filtered bythreadId.search: full-text search onbodywithin a thread.
Source: packages/slingshot-community/src/entities/reply.ts
ReportEntity
Section titled “ReportEntity”Entity definition for a user-submitted content report.
Exported as ReportEntity from the package index.
Remarks: List and get operations require the community:container.review-report permission. The package-owned auto-moderation middleware can automatically create report records when declarative moderation rules flag content for review.
Source: packages/slingshot-community/src/entities/report.ts
reportOperations
Section titled “reportOperations”Custom operations for the Report entity.
resolve: pending → resolved state transition; records the moderator’s user ID and a description of the action taken.dismiss: pending → dismissed state transition; records the dismissing moderator’s user ID.
Both operations require the community:container.review-report permission
and are audited via the auditLog middleware.
Source: packages/slingshot-community/src/entities/report.ts
TagEntity
Section titled “TagEntity”Entity definition for a community tag.
Tags are tenant-scoped labels that can be applied to threads via ThreadTag.
usageCount is denormalized and updated by tagUsageIncrement /
tagUsageDecrement middleware on ThreadTag create/delete.
Source: packages/slingshot-community/src/entities/tag.ts
tagOperations
Section titled “tagOperations”Custom operations for the Tag entity.
getBySlug: lookup by slug and optional tenantId.incrementUsage: atomically increment usageCount.decrementUsage: atomically decrement usageCount.
Source: packages/slingshot-community/src/entities/tag.ts
threadModule
Section titled “threadModule”Package-authoring module for Thread. See containerModule for rationale.
Source: packages/slingshot-community/src/entities/thread.ts
ThreadSubscriptionEntity
Section titled “ThreadSubscriptionEntity”Entity definition for a user’s subscription to a specific thread.
Controls notification delivery for new replies to the thread.
Source: packages/slingshot-community/src/entities/threadSubscription.ts
threadSubscriptionOperations
Section titled “threadSubscriptionOperations”Custom operations for the ThreadSubscription entity.
getSubscription: Single subscription lookup by userId + threadId.listByThread: All subscribers to a thread.
Source: packages/slingshot-community/src/entities/threadSubscription.ts
ThreadTagEntity
Section titled “ThreadTagEntity”Entity definition for a thread–tag association.
Each row links one thread to one tag. Middleware on create/delete maintains
the Tag.usageCount denormalized counter and syncs the Thread.tagIds
array field.
Source: packages/slingshot-community/src/entities/threadTag.ts
threadTagOperations
Section titled “threadTagOperations”Custom operations for the ThreadTag entity.
listByThread: all tags for a thread.listByTag: all threads for a tag.
Source: packages/slingshot-community/src/entities/threadTag.ts
UserMuteEntity
Section titled “UserMuteEntity”Entity definition for a user mute.
When a user mutes another user (optionally scoped to a container), content from the muted user is hidden in lists and notifications are suppressed.
Source: packages/slingshot-community/src/entities/userMute.ts
userMuteOperations
Section titled “userMuteOperations”Custom operations for the UserMute entity.
isMuted: Check if a user is muted by the caller.listByUser: All mutes for a user.
Source: packages/slingshot-community/src/entities/userMute.ts
WarningEntity
Section titled “WarningEntity”Entity definition for a moderator warning issued to a user.
Warnings are container-scoped. The acknowledgedAt field is set when
the user acknowledges the warning via the acknowledge operation.
Source: packages/slingshot-community/src/entities/warning.ts
warningOperations
Section titled “warningOperations”Custom operations for the Warning entity.
acknowledge: SetacknowledgedAton the warning.listByUser: All warnings for a user.
Source: packages/slingshot-community/src/entities/warning.ts
Interfaces
Section titled “Interfaces”A ban restricting a user from creating content.
When containerId is present the ban applies to a single container.
When absent it is a global (platform-wide) ban. The banCheck middleware
enforces active bans on thread and reply creation routes.
Bans are lifted by the removeBan operation (not by deletion), which sets
unbannedBy and unbannedAt.
Remarks: Relationships: scoped to a Container via containerId (optional) and references a user via userId.
Remarks: Operations (community plugin): list (moderator-only, by userId / containerId), create (issues a new ban), removeBan (fieldUpdate setting unbannedBy + unbannedAt; does not delete the record).
Remarks: Side effects: creating a ban triggers the banNotify after-middleware, which creates a shared notification via slingshot-notifications.
Remarks: Expiry: bans with expiresAt in the past are considered inactive. The banCheck middleware checks expiresAt > now before blocking content creation.
Remarks: Permission gates: create and removeBan require community:container.manage-bans or container moderator/owner role.
Source: packages/slingshot-community/src/types/models.ts
CommunityAdminGate
Section titled “CommunityAdminGate”Admin gate for community moderation routes.
Implement this interface to control access to admin-only community endpoints and to record a tamper-proof audit trail of moderation decisions in tests or custom integrations.
Remarks: createCommunityPackage() does not accept an adminGate config field. This interface remains exported for the internal moderation middleware/runtime contracts that power tests and package-owned integrations.
Source: packages/slingshot-community/src/types/config.ts
CommunityInteractionsPeer
Section titled “CommunityInteractionsPeer”Cross-package peer surface used by slingshot-interactions (and other
component-aware consumers) to resolve community-owned message trees and
apply component updates returned by interaction dispatchers.
Source: packages/slingshot-community/src/public.ts
CommunityPluginState
Section titled “CommunityPluginState”Plugin runtime state published by createCommunityPackage().
entityAdapters is published into this same slot by the inner entity plugin
via publishEntityAdaptersState and is the canonical adapter surface
requireEntityAdapter(...) consults. It’s typed as a record here so the
plugin’s own publish merge preserves it without needing to know each entity
adapter’s full type at this seam.
Source: packages/slingshot-community/src/types/state.ts
CommunityWsConfig
Section titled “CommunityWsConfig”WebSocket configuration for the community plugin.
When provided, enables real-time presence tracking and typing indicators
on community containers. Each container gets a live channel at
containers:{containerId}:live.
Remarks: The wsEndpoint must be declared in the app’s WsConfig.endpoints with presence: true. In config-driven mode only wsEndpoint is required — the plugin self-wires its subscribe guard and incoming handlers during setupPost using SlingshotContext.wsPublish and SlingshotContext.ws.
Source: packages/slingshot-community/src/types/config.ts
Container
Section titled “Container”A community space that groups threads together (analogous to a subreddit, channel, or forum category).
Containers use soft-delete (deletedAt). Deleted containers are excluded
from list results unless includeDeleted: true is passed.
Remarks: Relationships: owns Thread[], ContainerMember[], ContainerRule[], Report[], and Ban[] records scoped to its ID. Deleting a container does not automatically cascade-delete child records — children should be cleaned up separately or filtered by checking the container’s deletedAt timestamp.
Remarks: Operations (community plugin): list, getById, create, update, delete (soft), getBySlug (lookup by slug), and search.
Remarks: Permission gates: create requires community:container.write; update and delete require community:container.manage or container owner role.
Source: packages/slingshot-community/src/types/models.ts
ContainerMember
Section titled “ContainerMember”Membership record linking a user to a container.
The (containerId, userId) pair is unique. Use the assignRole operation
to change a member’s role without deleting and re-creating the record.
Remarks: Relationships: belongs to one Container via containerId. Represents a single user’s membership and role within that container.
Remarks: Operations (community plugin): list (by containerId), join (create member with role: 'member'), leave (delete), assignRole (fieldUpdate on role). The assignRole operation triggers the grantManager after-middleware, which creates or revokes the corresponding 'community:container' permission grant for moderator and owner roles.
Remarks: Permission gates: join requires authentication; assignRole requires the community:container.manage-members permission or container owner role.
Source: packages/slingshot-community/src/types/models.ts
ContainerRule
Section titled “ContainerRule”A community rule displayed to members of a container.
Rules are shown in ascending order. Update the order field to
re-sort without deleting records.
Remarks: Relationships: belongs to one Container via containerId.
Remarks: Operations (community plugin): list (by containerId), create, update (title, description, order), delete.
Remarks: Permission gates: create, update, and delete require the community:container.manage permission or container owner role.
Source: packages/slingshot-community/src/types/models.ts
GetRepliesOptions
Section titled “GetRepliesOptions”Options for fetching replies for a thread.
Source: packages/slingshot-community/src/types/models.ts
ListBansOptions
Section titled “ListBansOptions”Options for paginating and filtering active bans.
Source: packages/slingshot-community/src/types/models.ts
ListContainersOptions
Section titled “ListContainersOptions”Options for paginating through containers.
Passed to the Container entity adapter’s list operation. Extends
PaginationOptions with community-specific filters.
Source: packages/slingshot-community/src/types/models.ts
ListReportsOptions
Section titled “ListReportsOptions”Options for paginating and filtering content reports.
Requires the community:container.review-report permission to use.
Source: packages/slingshot-community/src/types/models.ts
ListThreadsOptions
Section titled “ListThreadsOptions”Options for paginating and filtering threads within a container.
Source: packages/slingshot-community/src/types/models.ts
ModerationTarget
Section titled “ModerationTarget”Describes the content submitted to the auto-moderation hook.
Passed to internal auto-moderation evaluators before a thread or reply is written to the database.
Remarks: createCommunityPackage() does not accept an autoModerationHook config field. This type remains exported for the package-owned moderation middleware/runtime contracts.
Source: packages/slingshot-community/src/types/config.ts
Reaction
Section titled “Reaction”A single user reaction on a thread or reply.
Each (targetId, targetType, userId) tuple is unique — reacting twice
replaces the previous reaction. The updateScore aggregate operation
on the Reaction entity automatically updates the target’s score and
reactionSummary fields.
Remarks: Relationships: belongs to either a Thread or Reply via targetId / targetType. Each user may have at most one reaction per target (enforced by the upsert operation on the entity).
Remarks: Operations (community plugin): upsert (add or change reaction), remove (delete reaction), list (by targetId + targetType).
Remarks: Side effects: every upsert or remove calls the updateScore computedAggregate operation on the parent Thread or Reply to refresh score and reactionSummary. This is performed in an afterHook registered during setupPost.
Source: packages/slingshot-community/src/types/models.ts
ReactionSummary
Section titled “ReactionSummary”Aggregate reaction counts for a thread or reply.
Materialised by the updateScore aggregate operation whenever a reaction is
added or removed. Stored as a JSON column on Thread and Reply.
Source: packages/slingshot-community/src/types/models.ts
A user reply within a thread.
Replies support threaded (nested) display via parentId and depth. The
score field is updated automatically via the updateScore aggregate
operation whenever a reaction is added or removed.
Remarks: Relationships: belongs to one Thread via threadId. May have a parent Reply via parentId (top-level replies have no parentId). Owns Reaction[] records where targetType === 'reply'. Soft-deletes via status: 'deleted'.
Remarks: Operations (community plugin): list, getById, create, update, delete (status transition to 'deleted'), updateScore (computedAggregate), and search.
Remarks: Guards: creation is blocked by the threadStateGuard middleware if the parent thread is not 'published' or is locked. Ban check middleware also blocks creation if the author has an active container-scoped or global ban.
Remarks: Permission gates: create requires authentication; delete requires the caller to be the author, a container moderator, or container owner.
Source: packages/slingshot-community/src/types/models.ts
Report
Section titled “Report”A user-submitted report about a piece of content or a user account.
Reports start as 'pending'. Moderators transition them to 'resolved'
or 'dismissed' via the resolve and dismiss operations, which require
the community:container.review-report permission.
Remarks: Relationships: references a Thread, Reply, or user by targetId / targetType. There is no foreign-key constraint — the referenced content may be soft-deleted at the time the report is reviewed.
Remarks: Operations (community plugin): list (moderator-only, by status / containerId), create (any authenticated user), resolve (transition to 'resolved' + fieldUpdate on resolvedBy / resolvedAction), dismiss (transition to 'dismissed').
Remarks: Auto-moderation: the autoMod middleware may create reports with reporterId: 'system:automod' automatically when content is flagged.
Remarks: Permission gates: list, resolve, and dismiss require community:container.review-report or container moderator/owner role.
Source: packages/slingshot-community/src/types/models.ts
ScoringConfig
Section titled “ScoringConfig”Declarative scoring configuration for the community plugin.
Consumed by updateScore (per-backend op.custom) and computeNetScore /
computeHotScore / computeControversialScore pure functions in
src/lib/scoring.ts. Config is frozen at plugin construction time and
closed over by the per-backend handler factories.
Source: packages/slingshot-community/src/types/config.ts
SearchOptions
Section titled “SearchOptions”Options for full-text search within the community.
Passed to the search custom operation on Thread and Reply entities.
Full-text search is powered by the slingshot-search plugin when configured;
falls back to DB-native LIKE queries otherwise.
Source: packages/slingshot-community/src/types/models.ts
Thread
Section titled “Thread”A post (topic) within a container.
Threads start as 'draft' and become visible after the publish transition
operation. score is derived from reactionSummary via the updateScore
aggregate and updated automatically on every reaction change.
Remarks: Relationships: belongs to one Container via containerId. Owns Reply[] records scoped to its ID. Owns Reaction[] records where targetType === 'thread'. Soft-deletes (via status: 'deleted') rather than removing rows.
Remarks: Operations (community plugin): list, getById, create, update, delete (status transition to 'deleted'), publish (transition to 'published'), pin / unpin (fieldUpdate on pinned), lock / unlock (fieldUpdate on locked), updateScore (computedAggregate), and search.
Remarks: Cascades: deleting a thread does not cascade to replies or reactions; replies are excluded by the status !== 'deleted' guard on thread lookup.
Remarks: Permission gates: create requires authentication; delete/pin/lock require the caller to be the author, a container moderator, or container owner.
Source: packages/slingshot-community/src/types/models.ts
AfterHook
Section titled “AfterHook”After-hook called with the committed result for side effects.
The operation has already been written to the store before this hook runs. The return value is ignored.
Remarks: After-hooks fire after the entity has been written to the store and the success response has been prepared. They are called in-band — the HTTP response is not sent until all after-hooks resolve. Use them for immediate side effects (e.g. analytics, cache invalidation, event emission) rather than deferred async work. If an after-hook throws, the write has already been committed and cannot be rolled back.
Source: packages/slingshot-community/src/types/hooks.ts
BeforeHook
Section titled “BeforeHook”Before-hook called with the incoming request input before the operation is executed.
Return the (optionally transformed) input to allow the operation to proceed.
Return null or undefined to reject the request with a 400 Bad Request
response.
Remarks: Before-hooks fire after request body parsing and before any write to the entity store. They run synchronously in the request lifecycle so any thrown error or rejected promise will bubble up as a 500 unless caught by the Hono error handler. Input mutations (e.g. injecting computed fields, stripping forbidden keys) should be done here rather than in after-hooks.
Source: packages/slingshot-community/src/types/hooks.ts
CommunityPluginConfig
Section titled “CommunityPluginConfig”Fully-typed configuration for the community plugin.
Inferred from communityPluginConfigSchema. Pass a value of this type
to createCommunityPackage(). Only containerCreation is required — all
other fields are optional.
Remarks: Field summary:
Remarks: - containerCreation — 'admin' restricts container creation to requests that pass the standard community container-write permission; 'user' allows any authenticated user. - scoring — Declarative score algorithm + weights used by the runtime updateScore operation. - mountPath — Base path for all community routes. Defaults to '/community'. - disableRoutes — Array of entity route names to skip mounting, useful for replacing a default route with a custom implementation.
Source: packages/slingshot-community/src/types/config.ts
ContainerMemberRole
Section titled “ContainerMemberRole”Role a user holds within a container (community space).
'member': standard read/write access.'moderator': can pin/lock threads, delete content, review reports, and apply bans.'owner': full permissions including managing moderators and other owners.
Source: packages/slingshot-community/src/types/models.ts
ModerationDecision
Section titled “ModerationDecision”Outcome returned by the auto-moderation hook.
'allow': content passes; proceed normally.'flag': content is queued for human review but still visible.'reject': content is blocked immediately; the request returns400.
Source: packages/slingshot-community/src/types/config.ts
ReactionType
Section titled “ReactionType”Type of reaction a user can attach to a thread or reply.
'upvote'/'downvote': counted inreactionSummaryand contribute toscore.'emoji': freeform emoji reactions tracked inreactionSummary.emojis.
Source: packages/slingshot-community/src/types/models.ts
ReplyStatus
Section titled “ReplyStatus”Lifecycle status of a reply.
'published': visible to members.'deleted': soft-deleted; hidden but retained for audit.
Source: packages/slingshot-community/src/types/models.ts
ReportStatus
Section titled “ReportStatus”Workflow status of a content report.
'pending': awaiting review.'resolved': a moderator took action (e.g. removed the content).'dismissed': the report was reviewed and no action was taken.
Source: packages/slingshot-community/src/types/models.ts
ReportTargetType
Section titled “ReportTargetType”The kind of content or account that was reported.
'thread': a thread post was reported.'reply': a reply was reported.'user': a user account was reported.
Source: packages/slingshot-community/src/types/models.ts
ThreadStatus
Section titled “ThreadStatus”Lifecycle status of a thread.
'draft': created but not yet visible to other users.'published': visible to members; set via thepublishoperation.'deleted': soft-deleted; hidden from lists but retained for audit.
Source: packages/slingshot-community/src/types/models.ts