Skip to content

Epic 9 — Groups


BE-GROUPS-001 — Full groups model (membership, messaging stubs)

  • [x] Implemented

Files:

  • Edit: prisma/schema.prisma — add GroupMembership, expand TalentGroup
  • Edit: src/graphql/schema/index.ts — add full Groups API
  • Edit: src/graphql/resolvers/index.ts
  • Create: src/graphql/resolvers/groups.ts

Schema additions:

prisma
model GroupMembership {
  id        String   @id @default(cuid())
  groupId   String
  group     TalentGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
  talentId  String
  role      GroupRole @default(MEMBER)
  joinedAt  DateTime @default(now())
  @@unique([groupId, talentId])
  @@map("group_memberships")
}
enum GroupRole { ADMIN MODERATOR MEMBER }

Add to TalentGroup: ownerId String, coverImageUrl String?, tags String[], memberships GroupMembership[]

Mutations: joinGroup(id), leaveGroup(id), inviteToGroup(groupId, talentId), removeMember(groupId, talentId), updateGroup(id, input)
Queries: myGroups: [TalentGroup!]!, discoverGroups(query?, tags?): [TalentGroup!]!, groupMembers(groupId): [GroupMembership!]!


FE-GROUPS-001 — Groups pages

  • [x] Implemented

Files:

  • Create: apps/app/src/pages/groups/GroupsPage.tsx — my groups + discover
  • Create: apps/app/src/pages/groups/GroupDetailPage.tsx
  • Create: apps/app/src/pages/groups/CreateGroupPage.tsx
  • Create: apps/app/src/lib/queries/groups.ts
  • Create: apps/app/src/hooks/useGroups.ts
  • Edit: apps/app/src/App.tsx — add routes

Description: Groups home: tabs "My Groups" and "Discover". Group card shows cover image, name, member count, tags. Group detail: members list (with Avatar), description, join/leave button. Create group form: name, description, tags, privacy setting. Uses DS components throughout.


BE-GROUPS-002 — Group extended spec: activity feed, announcements, events, portfolio, group hiring

  • [x] Implemented

Files:

  • Edit: prisma/schema.prisma — add GroupPost, GroupEvent, GroupPortfolioItem models; extend TalentGroup
  • Run: pnpm db:migrate
  • Edit: src/graphql/schema/index.ts
  • Edit: src/graphql/resolvers/groups.ts

Schema additions:

prisma
// Extend TalentGroup
missionStatement    String?
categories          String[]  @default([])
portfolioItems      GroupPortfolioItem[]
posts               GroupPost[]
events              GroupEvent[]
featuredAt          DateTime?   // set by admin to feature the group on the platform

model GroupPost {
  id          String   @id @default(cuid())
  groupId     String
  group       TalentGroup @relation(...)
  authorId    String   // TalentProfile
  body        String
  pinned      Boolean  @default(false)
  mediaUrls   String[] @default([])
  createdAt   DateTime @default(now())
  @@map("group_posts")
}

model GroupEvent {
  id          String   @id @default(cuid())
  groupId     String
  group       TalentGroup @relation(...)
  title       String
  type        String   // "AUDITION" | "REHEARSAL" | "PROJECT"
  scheduledAt DateTime
  location    String?
  isOnline    Boolean  @default(false)
  createdAt   DateTime @default(now())
  @@map("group_events")
}

model GroupPortfolioItem {
  id        String   @id @default(cuid())
  groupId   String
  group     TalentGroup @relation(...)
  type      String   // "VIDEO" | "IMAGE" | "TESTIMONIAL"
  url       String?
  caption   String?
  createdAt DateTime @default(now())
  @@map("group_portfolio_items")
}

Group hiring: add applyGroupToJob(groupId: ID!, jobId: ID!, talentIds: [ID!]!): [Application!]! — bulk-applies selected group members to a job. Reuses Application model. Requires the caller to be a group admin.

Featured groups: adminFeatureGroup(groupId: ID!): TalentGroup! (admin only) — sets featuredAt. featuredGroups: [TalentGroup!]! query for the Discover Groups page.

Mutations: createGroupPost(groupId, body, mediaUrls?), pinGroupPost(postId), createGroupEvent(groupId, input), addGroupPortfolioItem(groupId, input), applyGroupToJob(groupId, jobId, talentIds)


FE-GROUPS-002 — Groups activity feed, events, portfolio, group apply

  • [x] Implemented

Files:

  • Edit: apps/app/src/pages/groups/GroupDetailPage.tsx — add tabs: Feed / Members / Portfolio / Events
  • Create: apps/app/src/pages/groups/GroupFeedTab.tsx
  • Create: apps/app/src/pages/groups/GroupEventsTab.tsx
  • Create: apps/app/src/pages/groups/GroupPortfolioTab.tsx
  • Create: apps/app/src/components/groups/GroupApplyModal.tsx
  • Edit: apps/app/src/hooks/useGroups.ts

Description:

  • Feed tab: chronological list of group posts. Admins/moderators can pin posts (shows pin icon at top). "New post" composer (text + optional media upload). Pinned posts appear first.
  • Events tab: upcoming events list (audition/rehearsal/project). Each event card shows type badge, date, location, online indicator. "Add event" for admins.
  • Portfolio tab: media gallery (photos, videos, testimonials). Grid layout. "Add item" for admins.
  • Group apply modal: producers browsing a group profile see an "Apply Group to Job" button. Opens a modal to select a job and which members to include, then calls applyGroupToJob.
  • Featured groups appear in the "Discover" tab with a Featured badge.