diff --git a/NIP.md b/NIP.md index 4cd026b..0c41e98 100644 --- a/NIP.md +++ b/NIP.md @@ -2064,7 +2064,7 @@ bare `p` tag on the crew is only a claim until the member self-labels. | `sponsor` | Optional **sponsoring shop** — a NIP-15 stall coordinate (`30017:pubkey:d`) for a local skate shop that backs the crew. Renders a "Sponsored by [Shop]" banner linking to the shop. Only shown when the shop resolves. | | `coordinator` | Optional **encrypted-chat coordinator** for the crew's private group. Shape: `["coordinator", , , ]`. `` is an `http(s)`/`wss` endpoint of a **Cordn** coordinator (an MLS / RFC 9420 Delivery Service reached over ContextVM). The crew event stays public and discoverable; message content, membership secrets and MLS ratchets live client-side. Nothing crew-specific is published to public relays. `` is the coordinator service pubkey (hex) for ContextVM addressing; `` is the human (hex) who runs it, if delegated. | | `video` | Optional **crew video / montage** ("The Part") — a **YouTube** or **Instagram** URL, rendered as the crew's headline embed. Only these two sources are accepted (skate parts live on YouTube, clips on Instagram); any other URL is ignored. No native/self-hosted video. Clients must parse it to a known embed (YouTube video id / Instagram shortcode) and reject anything else rather than render an untrusted iframe. | -| `crew-role` | Optional **skate role** assigned to a roster member. Shape: `["crew-role", , ]`, repeatable (a member may hold several). `` ∈ `filmer`, `photographer`, `editor`, `artist`, `manager`, `og`. These are the *functions* on a skate team (the filmer is as vital as the skaters) and are purely a **flex/label** — they grant **no powers** (only the `admin` marker does). Only honoured for the founder or a listed member; roles on non-roster pubkeys are ignored. | +| `crew-role` | Optional **skate role** assigned to a roster member. Shape: `["crew-role", , ]`, repeatable (a member may hold several). `` ∈ the full Lab-craft set — `filmer`, `photographer`, `editor`, `coach`, `builder`, `artist`, `graffiti`, `tattoo`, `trainer`, `musician`, `judge` — plus the crew-specific `manager` and `og`. The Lab-craft roles mirror the Lab profession kinds (35001–35012), so a crew's "filmer" speaks the same language as a Lab Filmer profile. These are the *functions* on a skate team (the filmer is as vital as the skaters) and are purely a **flex/label** — they grant **no powers** (only the `admin` marker does). Only honoured for the founder or a listed member; roles on non-roster pubkeys are ignored. | ### Crew-Hosted Events diff --git a/src/lib/types.ts b/src/lib/types.ts index 53b3db3..1f94fea 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1676,10 +1676,19 @@ export interface SkateCrew { * `["crew-role", , ]` */ export type CrewRole = - | 'filmer' - | 'photographer' - | 'editor' - | 'artist' + // ── Lab crafts (mirror the Lab profession kinds 35001–35012) ── + | 'filmer' // 35002 + | 'photographer' // 35004 + | 'editor' // 35003 + | 'coach' // 35001 + | 'builder' // 35005 + | 'artist' // 35007 (designer / board graphics) + | 'graffiti' // 35008 + | 'tattoo' // 35009 + | 'trainer' // 35010 (physio / strength) + | 'musician' // 35011 + | 'judge' // 35012 + // ── Crew-specific roles (no Lab equivalent) ── | 'manager' | 'og'; @@ -1688,18 +1697,34 @@ export interface CrewMemberRole { role: CrewRole; } -/** Human labels + emoji for each crew role (skate-native language). */ -export const CREW_ROLE_META: Record = { - filmer: { label: 'Filmer', emoji: '🎥' }, - photographer: { label: 'Photographer', emoji: '📷' }, - editor: { label: 'Editor', emoji: '✂️' }, - artist: { label: 'Artist', emoji: '🎨' }, - manager: { label: 'Team Manager', emoji: '📋' }, - og: { label: 'OG', emoji: '👑' }, +/** + * Human labels + emoji for each crew role (skate-native language). Lab crafts + * reuse the same emoji as their Lab profession so the language stays consistent + * across the app; `labKind` links a role back to its Lab profile kind (if any) + * so we can cross-link "this filmer has a Lab profile" later. + */ +export const CREW_ROLE_META: Record = { + filmer: { label: 'Filmer', emoji: '🎥', labKind: SKATE_FILMER_KIND }, + photographer: { label: 'Photographer', emoji: '📸', labKind: SKATE_PHOTOGRAPHER_KIND }, + editor: { label: 'Editor', emoji: '✂️', labKind: SKATE_EDITOR_KIND }, + coach: { label: 'Coach', emoji: '🎓', labKind: SKATE_COACH_KIND }, + builder: { label: 'Builder', emoji: '🔨', labKind: SKATE_BUILDER_KIND }, + artist: { label: 'Artist', emoji: '🎨', labKind: SKATE_ARTIST_KIND }, + graffiti: { label: 'Graffiti', emoji: '🖌️', labKind: SKATE_GRAFFITI_KIND }, + tattoo: { label: 'Tattoo', emoji: '💉', labKind: SKATE_TATTOO_KIND }, + trainer: { label: 'Trainer', emoji: '💪', labKind: SKATE_TRAINER_KIND }, + musician: { label: 'Musician', emoji: '🎵', labKind: SKATE_MUSICIAN_KIND }, + judge: { label: 'Judge', emoji: '⚖️', labKind: SKATE_JUDGE_KIND }, + manager: { label: 'Team Manager', emoji: '📋' }, + og: { label: 'OG', emoji: '👑' }, }; -/** All assignable crew roles, in display order. */ -export const CREW_ROLE_ORDER: CrewRole[] = ['filmer', 'photographer', 'editor', 'artist', 'manager', 'og']; +/** All assignable crew roles, in display order (media crafts → Lab crafts → crew-specific). */ +export const CREW_ROLE_ORDER: CrewRole[] = [ + 'filmer', 'photographer', 'editor', + 'coach', 'builder', 'artist', 'graffiti', 'tattoo', 'trainer', 'musician', 'judge', + 'manager', 'og', +]; const CREW_ROLE_SET = new Set(CREW_ROLE_ORDER);