How to Improve Unique Constraints in Schema?

Looking for a possible way to improve a portion of my schema while it is young. I have notes and allow users to add reactions to the notes. Users are linked to contacts to hide user info while showing contact names.

What I am looking for is a better way to only allow any one reaction to be made once for any one contact on any one post. So in essence, a three edge unique constraint.

There was this somewhat similar post a few days ago. I helped @chewxy with that one some and wanted to build upon it to show the need for such a feature or maybe realize an existing solution that I am missing.

If this was stack overflow I would offer a bounty for the best answer here :wink: [Maybe someone wants to build that extension for discuss?]

Example Schema:

type User {
  username: String @id
  isContact: Contact! @hasInverse(field: isUser)
}
type Contact {
  id: ID
  isUser: User
  name: String!
  madeReactions: [Reaction] @hasInverse(field: by)
}
type Note {
  id: ID
  content: String!
  author: Contact
  reactions: [Reaction] @hasInverse(field: onNote)
}
type Reaction {
  id: ID
  at: DateTime! @search
  reaction: Reactions! @search
  by: Contact!
  onNote: Note
}
enum Reactions {
  PLUS
  MINUS
  # ...
}

What I don’t want to do is break out every reaction to its own edge. I would rather keep the reactions in an enum. This makes the queries and mutations easier to maintain.

I also did reduce down this schema greatly. I am using the Reaction type on to manage reactions on multiple content types such as posts, comments, and messages which explains why the Reactions.onNote edge is not required. This allows me to pull up a list of a users last reactions across various content types and show them in a feed like manner. I also figure that later on I can do some advanced algorithms to help connect users together by comparing similar reactions if they are stored in a single type.

The problem though is that with this schema, there is no way to limit a user (on the database side) from repeating the same reaction to the same content. This allows a repeat of the following mutation over and over again unless controlled from the client application side.

mutation addReaction {
  addReaction(input: [{
    at: "2020-11-06T03:05:00Z"
    reaction: PLUS
    by: { id: "0x353037" }
    onNote: { id: "0x3432" }
  }]) { numUids }
}

I really want to make this control on the database side. And I would love to do it with GraphQL only without DQL upserts. :pray:

Thinking if we can fix this problem, we can make a graph database by the next election and count votes instantly—come on Nevada! :rofl:

Hey @amaster507

So is the expectation here that if a Reaction exists on a note by a user, then the following addReaction mutations by the same user and same note should error out?

Whether it errors out or does some kind of replacement anything other than creating a duplicate entry.