Skip to content

Wiki Module

Location: apps/api/src/modules/wiki/

Aggregate roots: WikiEntry, WikiProposal, WikiVote

The Wiki context provides a community-maintained knowledge base for each interest. Proposals start as pending and are approved either automatically when netVotes >= 3 or by an admin override. The rep gate prevents contributions from brand-new accounts.


Constants

ConstantValueDescription
WIKI_VOTE_APPROVAL_THRESHOLD3Net votes needed for auto-approval
WIKI_MIN_REP5Minimum reputation in the interest to propose or vote

Prisma Models

ModelTableNotes
WikiEntrywiki_entriesCanonical versioned content per interest
WikiProposalwiki_proposalsCommunity-submitted edit
WikiVotewiki_votes+1 / -1 vote on a proposal

WikiEntry Fields

FieldTypeNotes
idUUID PK
interestIdUUID FKOne entry per version
contentTextMarkdown body
summaryString? (280)
authorIdUUIDAdmin/approved proposer
versionIntAuto-incremented on approval
createdAtDateTime
updatedAtDateTime

Unique: (interestId, version)

WikiProposal Fields

FieldTypeNotes
idUUID PK
interestIdUUID FK
contentText
summaryString? (280)
proposerIdUUID FK → users
statusString (20)pending | approved | rejected
netVotesIntMaterialised counter (+1 votes – −1 votes)
createdAtDateTime
updatedAtDateTime

WikiVote Fields

FieldTypeNotes
idUUID PK
proposalIdUUID FK
voterIdUUID
valueInt+1 or -1
createdAtDateTime

Unique: (proposalId, voterId) — one vote per user per proposal.


Key Methods

MethodDescription
getEntry(interestSlug)Return latest canonical WikiEntry for an interest
getProposals(interestSlug, opts)List proposals (all or by status)
submitProposal(userId, interestSlug, content, summary)Create pending proposal after rep gate
vote(proposalId, voterId, value)Cast or update vote; auto-approves at threshold
adminApprove(proposalId, adminId)Force-approve bypassing vote threshold
adminReject(proposalId, adminId, note)Reject a proposal

Rep Gate

checkRepGate(userId, interestId):

  1. Check ReputationSnapshot for value >= WIKI_MIN_REP in the interest.
  2. Fallback: allow if total reputation across all interests >= 20.
  3. Otherwise: throw ForbiddenException.

Auto-Approval Logic

When a vote is cast and proposal.netVotes >= WIKI_VOTE_APPROVAL_THRESHOLD:

  1. Create a new WikiEntry with version = previous.version + 1.
  2. Update proposal status → approved.
  3. Emit wiki.proposal.approved.

HTTP Endpoints

All under /api/v1/wiki/. Require JwtAuthGuard.

MethodPathDescription
GET/wiki/:interestSlugGet current wiki entry
GET/wiki/:interestSlug/proposalsList proposals
POST/wiki/:interestSlug/proposalsSubmit proposal
POST/wiki/proposals/:id/voteVote { value: 1 | -1 }
POST/wiki/proposals/:id/approveAdmin approve (AdminGuard)
POST/wiki/proposals/:id/rejectAdmin reject (AdminGuard)

Events Emitted

EventPayloadConsumed by
wiki.proposal.approved{ proposalId, interestId, version }Notifications

Regulus — invite-only social-knowledge platform