Skip to content

Instantly share code, notes, and snippets.

@nelsonpecora
Created July 18, 2019 16:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nelsonpecora/1810dc50095e852a8dc585dc3bc40132 to your computer and use it in GitHub Desktop.
Save nelsonpecora/1810dc50095e852a8dc585dc3bc40132 to your computer and use it in GitHub Desktop.
"""
Content is the interface for all of our varied types of records.
When serving content over the API, only the Content ID is exposed, not
the internal IDs from concrete record tables.
"""
interface Content {
id: ID!
contentType: ContentType! # e.g. ARTICLE, BUNDLE, IMAGE, etc
memberOf: [Content!]!
# When records are members of another type of content, they have a
# position (stored in the join table). Using floats allows reordering
# between two other members up to about 50 times before we encounter
# floating point issues, which is more than enough for our purposes.
# In a more robust system, it might be wise to use something like a btree instead
position: Float
status: ContentStatus! # Derived from visibility and events
createdAt: DateTime!
createdBy: User!
updatedAt: DateTime! # derived from the timestamp of latest event
updatedBy: [User!]! # All users who have triggered events on this content.
events: [Event!]!
}
"""
CREATE, EDIT, PUBLISH, etc events are created when editing content.
In our system, only PUBLISH events trigger snapshot creation. This is
a relatively simplistic way to do versioning without creating a bunch
of (in practice) unnecessary duplicate data.
"""
type Event {
createdAt: DateTime!
createdBy: User!
event: EventName!
# This is denormalized JSON stored in the db, but served as
# proper GraphQL records so schema introspection and client shaping work
snapshot: Content
}
type Bundle implements Content {
id: ID!
# System fields
contentType: ContentType!
memberOf: [Content!]!
position: Float
status: ContentStatus!
createdAt: DateTime!
createdBy: User!
updatedAt: DateTime!
updatedBy: [User!]!
events: [Event!]!
# Bundle Fields
label: String!
title(format: TextFormat): RichText # JSON-serialized prosemirror data model
description(format: TextFormat): RichText
slug: String
members: [Content!]!
}
type Image implements Content {
id: ID!
# System fields
contentType: ContentType!
memberOf: [Content!]!
position: Float
status: ContentStatus!
createdAt: DateTime!
createdBy: User!
updatedAt: DateTime!
updatedBy: [User!]!
events: [Event!]!
# Image Fields
credit(format: TextFormat): RichText
url: String
width: Int
height: Int
altText: String
}
"""
We haven't implemented full articles in the new CMS, so
these are actually 'embeds' of articles from the old db
"""
type LegacyArticle implements Content {
id: ID!
# System fields
contentType: ContentType!
memberOf: [Content!]!
position: Float
status: ContentStatus!
createdAt: DateTime!
createdBy: User!
updatedAt: DateTime!
updatedBy: [User!]!
events: [Event!]!
# Legacy Article Fields
legacyId: Int
image: String
title: String
author: String,
url: String
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment