ghostguild-org/docs/superpowers/specs/2026-04-14-board-classifieds-design.md
Jennie Robinson Faber 707447fc88 spec: board classifieds redesign
Replace passive tag-matching with active classifieds posts.
Corkboard/zine card UI, Slack topic channel integration,
admin channel mapping, simplified profile board section.
2026-04-14 15:09:40 +01:00

6.8 KiB

Board Classifieds Redesign

Overview

Replace the Board's passive tag-matching system with an active classifieds board where members post what they're seeking and offering. Posts are the single source of truth for board presence. The UI follows a corkboard/zine card layout. All communication happens on Slack via curated topic channels.

Goals

  • Give members a reason to browse and return to the Board
  • Make the Board feel like a BBS — fun, personal, alive
  • Push all conversation to Slack (no in-app messaging)
  • Replace the abstract tag-state system with concrete, human-readable posts

Design Decisions

Decision Choice Rationale
Visual style Corkboard / zine cards Fits existing design language, gives each post personality
Posts vs matching Posts replace tag-matching entirely Single source of truth, simpler mental model
Post lifecycle Evergreen until removed by author Simple, member-managed
Posts per member Unlimited Community will self-regulate
Slack integration Web URL links to curated topic channels gammaspace.slack.com/archives/{channelId} — tested, works reliably
Slack deep links Protocol (slack://) and app links do not work Tested — only web URL format opens the correct channel
Channel management Admin-managed, curated set with tag mapping Admin UI to map cooperative tags to Slack channels
Unmapped tags No Slack link shown No fallback channel
Visibility All members see all posts Behind members-auth middleware
Migration None needed Pre-launch, test data only

Data Model

New: BoardPost

author        ObjectId, ref Member, required
title         String, required, max 120
seeking       String, optional, max 500
offering      String, optional, max 500
note          String, optional, max 300
tags          [String] — slugs from cooperative tag pool
createdAt     Date
updatedAt     Date

Validation: at least one of seeking or offering is required.

New: BoardChannel

name          String, required — display name (e.g. "Structure & Governance")
slackChannelId String, required — Slack channel ID (e.g. "C09DDGZGXAP")
tagSlugs      [String] — cooperative tag slugs mapped to this channel
createdAt     Date
updatedAt     Date

Member Model Changes

Remove:

  • board.topics (array of tag/state objects)
  • board.details
  • board.offerPeerSupport
  • board.availability
  • board.personalMessage

Keep:

  • board.slackHandle — author's Slack identity, shown on posts
  • Privacy toggle for Slack handle visibility

Board Page

Layout

Corkboard card grid. 2 columns on desktop, 1 column at ≤1024px. Newest posts first.

Header

  • Page title "Board" with post count subtitle
  • "+ New Post" button
  • Tag filter drawer (existing pattern — toggleable, filters posts by tag)

Post Card

Each card displays:

  • Type indicator: SEEKING (gold) / OFFERING (green) / SEEKING ↔ OFFERING (ember) — derived from which fields are filled
  • Title — prominent, Brygada 1918
  • Seeking text — if present
  • Offering text — if present
  • Note — personal touch, slightly different visual treatment
  • Tags — dashed-border pills
  • Footer: author avatar + name + circle badge
  • Slack link: "Discuss on Slack →" linking to mapped channel. Only shown if post's tags map to a channel. Uses https://gammaspace.slack.com/archives/{channelId}. If tags map to multiple channels, use the first match.

New Post Form

Inline at top of the Board page (not a modal). Fields:

  • Title (required, 120 chars)
  • Seeking (optional, 500 chars)
  • Offering (optional, 500 chars)
  • Note (optional, 300 chars)
  • Tags (multi-select from cooperative tag pool)

Validation: at least one of seeking/offering required. Form appears on "+ New Post" click, collapses after submission.

Empty State

Friendly prompt to be the first to post, with link to create.

Profile Board Section

Replaces the current cooperative tag selector, details textarea, and peer support section.

Shows

  • List of member's active posts (compact card previews)
  • Edit and delete actions per post
  • "+ New Post" button (navigates to Board page or opens same inline form)
  • Slack handle setting (identity-level, not per-post)
  • Privacy toggle for Slack handle

Removes

  • CooperativeTagSelector three-state tag picker
  • Details textarea
  • Offer Peer Support toggle + conditional fields (availability, personal message)

No Posts State

Prompt to visit the Board and post something.

Admin: Board Channels

New admin page for managing Slack channel mappings.

UI

  • List of board channels showing: display name, Slack channel ID, mapped tags
  • Add / edit / remove channels
  • Tag mapping: multi-select from cooperative tags
  • Unmapped tag indicator: shows cooperative tags not yet assigned to any channel

Behavior

  • Admins create channels in Slack manually, then register them here by pasting the channel ID
  • Frontend uses the channel list to build Slack links on post cards

API Routes

New

Method Path Auth Purpose
GET /api/board/posts member List all posts, newest first. Tag filtering via query params. Populates author name/avatar/circle/slackHandle.
POST /api/board/posts member Create a post. Validates at least one of seeking/offering.
PATCH /api/board/posts/:id member (own post) Edit a post.
DELETE /api/board/posts/:id member (own post) Delete a post.
GET /api/board/channels member List channels with tag mappings (for building Slack links).
GET /api/admin/board-channels admin List channels for admin UI.
POST /api/admin/board-channels admin Create channel mapping.
PATCH /api/admin/board-channels/:id admin Update channel mapping.
DELETE /api/admin/board-channels/:id admin Remove channel mapping.

Remove

Path Reason
GET /api/board/suggestions Replaced by posts
PATCH /api/members/me/board Board profile fields removed (slackHandle stays on existing member profile patch)

Components

Stays (repurposed)

  • CooperativeTagSelector — simplified to a plain tag picker (no three-state toggle) for use in post creation form

Goes

  • Match-card UI on Board page
  • Peer support section on profile page

New

  • BoardPostCard — the corkboard card component
  • BoardPostForm — inline creation/edit form
  • BoardPostList — grid layout for post cards (used on Board page and profile)
  • Admin channel management components

Composables

Remove

  • useBoard (the old getSuggestions wrapper)

New

  • useBoardPosts — CRUD for posts, tag filtering
  • useBoardChannels — fetch channel mappings, resolve tag→channel for Slack links