@latimer-woods-tech/community
v0.2.0
Published
The portfolio's **community layer**, built once as an extractable horizontal (charter: [`docs/planning/community-layer.md`](../../docs/planning/community-layer.md), RATIFIED 2026-07-05). Capricast is the first and flagship host; other apps distribute **th
Readme
@latimer-woods-tech/community
The portfolio's community layer, built once as an extractable horizontal
(charter: docs/planning/community-layer.md,
RATIFIED 2026-07-05). Capricast is the first and flagship host; other apps
distribute through the network as Spaces — they do not each mount their own.
Extraction contract (structural, not aspirational). This package has zero host imports, owns its own Drizzle schema namespace, and reaches the host only through three narrow ports (identity / moderation / payments). Re-hosting the graph to its own brand/domain/DB is a package lift, not a rewrite.
What's in Phase 1 (this release)
The community core, with no Spaces and no money yet:
| Concern | Surface |
|---|---|
| Follow graph | GraphService — free, directional follow/unfollow, counts, lists |
| Blocks (C2) | GraphService.block/unblock — a block in either direction is a hard wall; it severs follows both ways |
| Posts / comments / reactions | ContentService — text/image posts, threaded comments on posts and host videos, idempotent reactions |
| Home feed | FeedService — follow-scoped SQL (author IN (following)), no fan-out infrastructure |
| Notifications | NotificationsService — a durable per-recipient event log (hot counters live in DOs) |
| Reports (C2/C4) | ReportsService — in-app report-content + report-user sink, immutable + audit-preserving |
Architecture
schema/ follows · blocks · posts · comments · reactions · reports · notification_events
— own Drizzle namespace; every user column is an OPAQUE host actor id (text)
store/ CommunityStore port + InMemoryCommunityStore reference (the SQL adapter's contract)
services/ GraphService · ContentService · FeedService · NotificationsService · ReportsService
ports/ IdentityPort (host user table) · ModerationPort (C2 filter + report sink) · PaymentsPort (Phase 2)The services depend only on the CommunityStore port and the host ports, so
they are unit-testable without a live database. The host (Capricast v1) backs
CommunityStore with a @latimer-woods-tech/neon FactoryDb adapter and
injects the three ports at mount time.
Usage
import {
GraphService,
ContentService,
FeedService,
NotificationsService,
ReportsService,
InMemoryCommunityStore,
} from '@latimer-woods-tech/community';
// Host wires the store (Neon adapter in prod; in-memory here) + the ports.
const store = new InMemoryCommunityStore();
const identity = { actorExists: async (id) => hostUserExists(id) };
const moderation = {
screen: async (text) => hostContentFilter(text), // C2 objectionable-content filter
onReport: async (r) => hostModerationQueue.enqueue(r),
};
const notifications = new NotificationsService({ store });
const graph = new GraphService({ store, identity });
const content = new ContentService({ store, identity, moderation, notifications });
const feed = new FeedService({ store });
const reports = new ReportsService({ store, moderation });
await graph.follow('alice', 'bob');
const post = await content.createPost({ authorId: 'bob', body: 'gm' });
await content.react({ actorId: 'alice', objectType: 'post', objectId: post.id });
const home = await feed.home('alice'); // bob's post, follow-scopedCompliance posture
The C2 gate (charter §6) must be satisfied by the host before any public UGC
surface ships. This package provides the storage + service half: report content,
report user, block user, and a moderation-screen hook. The host supplies the
policy (ModerationPort), the published contact, the 13+ age gate, and the UI.
Reports are immutable except for moderation status, preserving the original for
the REPORT-Act (C4) 1-year audit trail.
Migration
migrations/0001_community_core.sql is the raw DDL matching the Drizzle schema.
Apply it against the host's Neon database:
psql "$NEON_CONNECTION_STRING" -f node_modules/@latimer-woods-tech/community/migrations/0001_community_core.sqlQuality gates
Runtime-agnostic (Cloudflare Workers clean: Web Crypto only, no process, no
Node built-ins). npm run typecheck && npm run lint && npm run test && npm run build
— ≥90/85 coverage, zero lint warnings, JSDoc on exported symbols.
Roadmap
- Phase 2 — Spaces (owner/membership/space feeds), paid tiers via
@latimer-woods-tech/operator,community-realtimeSpaceRoom/PresenceRoom on@latimer-woods-tech/realtime. - Phase 3 — chart-native profiles, practitioner verification, 1:1 readings.
- Phase 4 — embeddable member-JWT surface; cross-app Space links.
