Champagne

Member tags

Staff-only club tags on people and the people filter.

Each club keeps its own catalog of tags. A tag has a label, unique per club ignoring case, and a color from a fixed palette. Tags are applied to any person of the club (members, prospects, guests) and are visible to staff only: member and applicant sessions always read an empty tags list, and the member site never shows them.

Permissions

OperationPermission
personTagsAny staff of the club
createPersonTag, updatePersonTag, deletePersonTagtags_manage
setPersonTagstags_manage

Club administrators hold this permission. Staff accounts receive it individually from the team page.

List tags

query PersonTags($clubId: ID! = "51000000-0000-4000-8000-000000000051") {
  personTags(clubId: $clubId) {
    id
    label
    color
    personCount
  }
}

Tags are returned ordered by label, ignoring case. personCount is the number of people of the club carrying the tag. color is one of the 14 palette names: gray, red, orange, amber, yellow, lime, green, emerald, teal, cyan, blue, indigo, violet or pink.

Manage the catalog

mutation CreatePersonTag($input: CreatePersonTagInput!) {
  createPersonTag(input: $input) {
    tag {
      id
      label
      color
      personCount
    }
    error
  }
}
{
  "input": {
    "clubId": "51000000-0000-4000-8000-000000000051",
    "label": "VIP",
    "color": "orange"
  }
}

UpdatePersonTagInput takes clubId, id, label and color; renaming keeps every assignment. deletePersonTag(clubId, id) removes the tag from every person at once. Each result returns the tag or a user-facing error string:

  • Another tag already uses this label. — labels are compared trimmed and ignoring case.
  • This tag is unavailable. — the tag does not belong to the club or was deleted.

Labels contain 1–24 characters without line breaks; color defaults to gray.

Tag people

mutation SetPersonTags($input: SetPersonTagsInput!) {
  setPersonTags(input: $input) {
    person {
      id
      tags {
        id
        label
        color
      }
    }
    error
  }
}
{
  "input": {
    "clubId": "51000000-0000-4000-8000-000000000051",
    "personId": "00000000-0000-4000-8000-000000000001",
    "tagIds": ["7a000000-0000-4000-8000-000000000001"]
  }
}

setPersonTags replaces the complete tag list of one person and returns the refreshed PersonDetail. An unknown tag or a person outside the club returns an error and changes nothing. Every change is recorded in the staff activity as person.tags_updated with the previous and new tag labels. Tags are only edited from a person's profile; the people list displays them and filters on them.

Read tags on people

Person.tags and PersonDetail.tags return [PersonTagSummary!]! (id, label, color) ordered by label. peoplePage(tagIds: [ID!]) keeps the people carrying at least one of the given tags; it requires clubId and accepts up to 50 tags. The back office stores the filter in the URL as repeated tag parameters. peoplePage(untagged: true) keeps only people carrying no tag at all (URL untagged=1); combined with tagIds it matches nobody.

query TaggedPeople($clubId: ID!, $tagIds: [ID!]) {
  peoplePage(clubId: $clubId, tagIds: $tagIds, page: 1, pageSize: 10) {
    items {
      id
      firstName
      lastName
      tags {
        id
        label
        color
      }
    }
    total
  }
}

Validation errors

Invalid IDs, labels, colors and oversized tag or people lists are rejected with BAD_USER_INPUT before any write. Business outcomes such as duplicate labels or unavailable tags are returned in the error field with a null record.

On this page