3daa8746ef04a1c4784ca9ee2f661c94b3251c2b — Conrad Hoffmann 1 year, 3 months ago a88a6b7
Start adding bits and pieces to the GQL schema

It's all preliminary for now, just to get an idea of some of the stuff
we'll need to implement.
1 files changed, 94 insertions(+), 4 deletions(-)

M api/graph/schema.graphqls
M api/graph/schema.graphqls => api/graph/schema.graphqls +94 -4
@@ 69,6 69,32 @@ type Version {
  deprecationDate: Time

# loosely modeled after https://api.enom.com/docs/contacts#input-parameters
enum ContactKind {

# loosely modeled after https://api.enom.com/docs/contacts#input-parameters
type Contact {
  id: Int!
  firstName: String!
  lastName: String!
  organizationName: String! # TODO required, but what is it?
  address: String!
  addressAdditional: String
  city: String!
  # TODO state/province?
  postalCode: String!
  country: String!
  email: String! # TODO infer from profile?
  "Required format is +CountryCode.PhoneNumber, where CountryCode and PhoneNumber use only numeric characters"
  phone: String! 
  extendedAttributes: String! # TODO figure this out: Country codes data required by the Registry for some ccTLD domains. Use "GetExtAttributes" to determine whether this TLD requires extended attributes.

type Name {
  id: Int!
  created: Time!

@@ 78,8 104,14 @@ type Name {
  "The extension of the domain. Can have multiple levels (e.g. 'com' or 'co.uk')."
  extension: String!

  # TODO ...
  whoisOwner: Contact!
  whoisAdmin: Contact!
  whoisTech: Contact!
  whoisBilling: Contact!

  expires: Time!

  # TODO ...


@@ 94,6 126,18 @@ type NameCursor {
  cursor: Cursor

A cursor for enumerating contacts

If there are additional results available, the cursor object may be passed
back into the same endpoint to retrieve another page. If the cursor is null,
there are no remaining results to return.
type ContactCursor {
  results: [Contact!]!
  cursor: Cursor

type OAuthClient {
  uuid: String!

@@ 199,11 243,28 @@ type Query {
  #"Returns a specific user."
  #user(username: String!): User @access(scope: PROFILE, kind: RO)

  "Returns a list of pastes created by the authenticated user."
  "Returns a list of names created by the authenticated user."
  names(cursor: Cursor): NameCursor @access(scope: NAMES, kind: RO)

  "Returns a paste by its ID."
  name(id: String!): Name @access(scope: NAMES, kind: RO)
  "Returns a name by its domain name and extension"
  name(name: String!, extension: String!): Name @access(scope: NAMES, kind: RO)

  # TODO do we need by Id?

  "Returns a list of contacts created by the authenticated user."
  contacts(cursor: Cursor): ContactCursor @access(scope: NAMES, kind: RO)

  # TODO: what to return here?
  "Check for availability of a domain"
  check(name: String!, extension: String!): Boolean @access(scope: NAMES, kind: RO)

  transferLock(domainId: Int!) Boolean @access(scope: NAMES, kind: RO)

  domainContact(domainId: Int!, kind: ContactKind!) Contact! @access(scope: NAMES, kind: RO)

  nameservers(domainId: Int!) [String!] @access(scope: NAMES, kind: RO)

  # TODO ...

  Returns a list of user webhook subscriptions. For clients

@@ 231,7 292,36 @@ input UserWebhookInput {
  query: String!

input UpdateWhoisContacts {
  contact: Contact!
  kind: ContactKind!

type Mutation {
  # TODO: what to return here?
  "Register a domain"
  register(name: String!, extension: String!): Boolean @access(scope: NAMES, kind: RW)

  # TODO: what to return here?
  "Renew a domain"
  renew(domainId: Int!, years: Int!): Boolean @access(scope: NAMES, kind: RW)

  # TODO
  #transfer(domainId: Int!, ...)

  # TODO flesh this out. Also: should every profile have a 'default' contact maybe?
  #deleteContact(contactId: Int!)
  #updateContact(contactId: Int!, ...)

  # TODO
  updateWhois(domainId: Int!, contactId: Int!, kind: ContactKind!) Boolean @access(scope: NAMES, kind: RW)

  # TODO
  updateNameservers(domainId: Int!, nameservers: [String!]) Boolean @access(scope: NAMES, kind: RW)

  # TODO
  setTransferLock(domainId: Int!, enabled: Boolean) Boolean @access(scope: NAMES, kind: RW)

  # TODO ...