Skip to content

Content Contexts — Events, Deliberation, Education, Projects, Marketplace

Location: apps/api/src/modules/{events,deliberation,education,projects}/ + apps/api/src/modules/economy/marketplace.*

One page for the Wave 3–6 content bounded contexts. All share the pattern: UUID-only cross-context refs, JwtAuthGuard, Zod-validated bodies, cursor-paginated lists with optional interestId filter, removedAt soft-remove for admin moderation.


Events

Aggregate roots: Event, EventRsvp. Modes online | in_person; RSVP statuses going | maybe | declined; the host auto-RSVPs as going. Capacity only constrains new going RSVPs.

MethodPathDescription
POST/eventsCreate (startsAt must be in the future)
GET/events?interestId=&limit=&cursor=Upcoming events
GET/events/mineHosting or RSVP'd (going/maybe)
GET/events/:idDetail + up to 8 "going" attendees
POST/events/:id/rsvpSet my RSVP status
POST/events/:id/cancelHost cancels

Emits events.rsvp.created { ... } when someone (not the host) goes — consumed by notifications.

Deliberation

Aggregate roots: Debate (+ arguments + votes), Problem (+ solutions + votes). Debate sides: for | against; one vote per user, changeable. Problems collect solutions; the author resolves with an accepted solution.

MethodPathDescription
POST / GET/debatesCreate / list debates (motion 8–200 chars)
GET/debates/:idDetail with both sides' arguments + tallies
POST/debates/:id/argumentsAdd a for/against argument
POST/debates/:id/voteVote a side
POST/debates/:id/closeAuthor closes the debate
POST / GET/problemsCreate / list problems
GET/problems/:idDetail + solutions
POST/problems/:id/solutionsPropose a solution
POST/problems/solutions/:solutionId/voteUpvote a solution
POST/problems/:id/resolveAuthor accepts a solution

Education

Aggregate roots: Course (status draftpublished), Lesson, Flashcard, enrollments. Only published courses are listable/enrollable; drafts visible to the author only.

MethodPathDescription
GET/courses / /courses/mine / /courses/recommendedPublished lists / my courses / interest-fit picks
POST/coursesCreate draft (depthBand 1–5)
GET/courses/:idDetail (draft → author only)
POST/courses/:id/lessonsAdd a lesson
POST/courses/:id/publishPublish (sets publishedAt)
POST/courses/:id/enrollEnroll
POST/courses/:id/lessons/:lessonId/completeMark lesson done
GET / POST/courses/lessons/:lessonId/flashcardsList / add flashcards
POST/courses/lessons/:lessonId/flashcards/generateAI-generate cards

Emits education.course.published, education.lesson.completed, education.course.completed.

Projects

Aggregate roots: Project (+ members). Statuses: open | active | shipped | archived.

MethodPathDescription
GET/projects / /projects/mineList / my projects
POST/projectsCreate (title, summary, link, interestId)
GET/projects/:idDetail
POST/projects/:id/join / /projects/:id/leaveMembership
POST/projects/:idOwner patches status/link/summary

Marketplace

Aggregate roots: MarketOffering, MarketOrder, MarketLedgerEntry (append-only — never UPDATE). Internal mana credit only (1–10 000 mana), same EmojiWallet as /modules/economy.

Escrow flow: buyer placeOrder → buyer's wallet row is locked FOR UPDATE, mana debited into escrow (order.status = 'escrow', ledger escrow_hold) → provider markDelivered → buyer release (provider paid, ledger release) or provider refund (buyer re-credited, ledger refund). order.status is the lifecycle; the ledger is the audit trail.

MethodPathDescription
GET/market/offerings / /market/offerings/mineBrowse / my offerings
GET/market/offerings/:idOffering card
POST/market/offeringsCreate offering (priceMana 1–10 000)
POST/market/offerings/:id/activeToggle active
POST/market/offerings/:id/orderPlace order (mana → escrow)
GET/market/orders/mineMy orders (as buyer or provider)
POST/market/orders/:id/deliverProvider marks delivered
POST/market/orders/:id/releaseBuyer releases escrow
POST/market/orders/:id/refundProvider refunds

Emits marketplace.order.placed, marketplace.order.released.


Unified Admin Moderation

All these contexts (plus videos/audio) share one oversight surface — 8 kinds: events, debates, problems, courses, projects, videos, audio, offerings.

MethodPathDescription
GET/admin/content?kind=&page=&search=&status=Paginated list per kind
POST/admin/content/:kind/:id/removeSoft-remove (removedAt), audit-logged
POST/admin/content/:kind/:id/restoreRestore

See also: /modules/videos, /modules/economy, /modules/discovery.

Regulus — invite-only social-knowledge platform