Skip to main content

Projects & members

A project is the top-level tenant — workjournal, skillforests, or mindcoding. Everything else (collections, publications, promos, media, brand) belongs to exactly one project, and every access decision is scoped to project membership.

Collections

A collection groups publications. One entity covers both grouping styles:

  • Campaigns — time-boxed, with starts_on / ends_on dates and a planned → active → done status. This is where campaign planning happens (batch-create stubs into a campaign).
  • Sections — evergreen buckets that stay active.

A publication may belong to a collection or stand alone.

Brand

Each project has a single brand document — the context AI writers read before drafting so content stays on-brand. It's a structured JSON document covering positioning, a library of voices, audiences (with personas, goals, and voice references), topics, and proof points.

Any project member can read the brand; owners and managers can edit it. AI clients read it through the get_project_brand MCP tool before writing or reviewing.

Members & roles

Membership is a project_members(project_id, user_id, role) table. Roles are owner and manager — both can edit; the model is written per-user from day one so multi-tenant later is a policy change, not a schema rewrite.

RLS applies to everyone — including agents

Row-Level Security is enforced at the database. The MCP server executes queries as the calling user (its OAuth JWT), not with a service role, so an AI client sees and touches exactly what that user could. The admin UI (NocoDB) connects with its own dedicated admin_ui Postgres role.

Actors at a glance

ActorInterfaceTypical actions
AI clients (Claude / ChatGPT)MCPwrite drafts, review, generate promos, report pipeline status
YouNocoDB admin UIfinal approvals, scheduling, manual Substack publish, media curation
System (edge functions)SQL + upload-postdispatch approved promos, enforce transitions, audit log