Back to Hip Hip

README

Hip Hip Groups & Sharing (P029)

Group-based list sharing for the Hip Hip todo app. Create groups, invite members via link, share todo lists with role-based access control.

Quick Start

Backend

bash
cd backend
docker compose up --build

Backend serves GraphQL at http://localhost:8080/query with playground at http://localhost:8080/.

Frontend

bash
cd frontend
npm install
npm run dev

Frontend dev server at http://localhost:5173, proxies GraphQL to backend.

Prerequisites

  • Go 1.25+
  • Node.js 20+
  • Docker & Docker Compose (for PostgreSQL)

Features

  • Groups: Create, update, delete groups with custom name, description, icon, and color
  • Invitations: Invite members via cryptographically secure link (7-day expiry)
  • Roles: Admin, Member, Viewer with enforced permission matrix
  • List Sharing: Share personal todo lists with groups; group members get access based on role
  • Dataloaders: Batch-loading prevents N+1 queries for group members and lists
  • Avatar Colors: Random color assignment from 8-color palette on registration

Architecture

Hexagonal architecture (ports & adapters) extending P026/P028:

shell
Domain → Ports → App Services → Adapters (PostgreSQL, GraphQL, JWT, bcrypt)

New Backend Components

ComponentPathDescription
Group domaininternal/domain/group.goGroup, GroupMembership, Invitation entities with validation
GroupServiceinternal/app/group_service.goBusiness logic for groups, invitations, memberships, sharing
GroupRepointernal/adapters/postgres/group_repo.goGroup CRUD
MembershipRepointernal/adapters/postgres/membership_repo.goMembership queries with batch loading
InvitationRepointernal/adapters/postgres/invitation_repo.goToken-based invitation management
Migrations 5-9internal/adapters/postgres/migrations/Groups, memberships, invitations, FK, avatar color

New Frontend Components

ComponentPathDescription
GroupCardsrc/components/GroupCard.tsxGroup preview card with member avatars
MemberListsrc/components/MemberList.tsxMember list with role management (admin view)
MemberAvatarsrc/components/MemberAvatar.tsxColored circle with user initials
InviteModalsrc/components/InviteModal.tsxEmail invite form with copy-link
GroupsPagesrc/pages/GroupsPage.tsxGrid of user's groups
GroupViewPagesrc/pages/GroupViewPage.tsxGroup detail with shared lists
GroupSettingsPagesrc/pages/GroupSettingsPage.tsxAdmin-only group settings
InvitationPagesrc/pages/InvitationPage.tsxAccept/decline invitation via token

GraphQL API

New Queries

  • myGroups: [Group!]! — All groups the user belongs to
  • group(id: ID!): Group! — Single group with members and lists
  • invitationInfo(token: String!): InvitationInfo! — Public invitation details (no auth required)

New Mutations

  • createGroup, updateGroup, deleteGroup — Group CRUD
  • inviteMember, acceptInvitation, declineInvitation — Invitation flow
  • removeMember, updateMemberRole — Membership management
  • shareList — Share a personal list with a group

Role-Based Authorization

OperationAdminMemberViewer
View group/lists/itemsYesYesYes
Update/delete groupYesNoNo
Invite/remove membersYesNoNo
Leave group (self-remove)YesYesYes
Share own listYesYesNo
Create/edit/delete itemsYesYesNo
Update/delete list metadataCreator or AdminCreator onlyNo

Running Tests

Backend

bash
cd backend
go test ./...          # All tests
go test ./... -v       # Verbose

Frontend

bash
cd frontend
npm test               # All tests
npm run test:watch     # Watch mode

Environment Variables

VariableRequiredDefaultDescription
DATABASE_URLYesPostgreSQL connection string
JWT_SECRETYesSecret for JWT token signing
PORTNo8080HTTP server port
VITE_API_URLNohttp://localhost:8080/queryGraphQL endpoint (frontend)

© 2026 Jonathan Leahy · v0.8.1-31-g196fa14