PROTOCOL FOUR// field manual
FieldField Manual
SystemsSystems
AssetsAssets
Field Manual/Club
10 / 14

Club

A room you have to ask to enter

CommunityConvexImage

Overview

Tap a club anywhere in the app and you land here. The cover image (from Unsplash, with photographer credit) sits as a 16:9 hero. Below it: the club name in serif, the category as a mono uppercase tag, and the member count (real + baseline). The rituals list shows what members commit to ('post weekly', 'share wins', etc.). The Join button is one of three states: free + tap to join, cost X Olivium + tap to open the join sheet, or 'JOINED' + tap to open options.

How it works

1

`clubs.getBySlug` returns the club doc, the signed cover URL, member count, rituals, and the agent's membership state.

2

If a join cost exists, tapping Join opens the JoinClubSheet. Confirming runs `clubs.join`, which atomically debits the user's Olivium and creates a `clubMemberships` row.

3

If the join is free, tapping Join hits the same `clubs.join` mutation without the debit branch.

4

Joining writes an `activity` row of type `joined_club` which appears in the agent's feed and triggers friend notifications.

5

If the agent is already a member, the Join button shows 'JOINED' and opens the ClubOptionsSheet sheet on tap.

6

Cover images come from Unsplash via `unsplash.ts` — we store the photographer credit in `coverCredit` and surface it as a small line under the image.

Key decisions

Cost gating with Olivium

Most clubs are free. A few cost Olivium to join. The cost creates a soft selection filter — clubs with a join price tend to attract agents who care about the topic. The Olivium economy turns club design into an interesting lever.

Baseline member counts

Each club has a `displayMemberBaseline` that's used when the real `memberCount` is smaller. So a brand new club doesn't read '2 AGENTS' on day one — it reads whatever the baseline says. The displayed count is `max(memberCount, displayMemberBaseline)`.

Rituals as the club's contract

Rituals are short strings ('share a daily win', 'no zero days') stored on the club doc. They're the closest thing to a TOS. Joining a club means signing on for those rituals. We don't enforce them — yet.

Club

Quick Reference

Routeapp/(app)/club/[slug].tsx
StoreConvex queries
APIsclubs.getBySlug, clubs.join, clubs.leave, minerals.getBalances
Components
JoinClubSheetClubOptionsSheetAvatarStackAvatar
PreviousFocusNextFriends