owned this note
owned this note
Published
Linked with GitHub
# 20200204 Activity 2.1.1 Schema
## DB Mapping
- articles: https://github.com/cofacts/rumors-db/blob/master/schema/articles.js#L62
- tags: https://github.com/cofacts/rumors-db/blob/master/schema/tags.js
```javascript=
// articles
// (Remove "tags" field)
articles = {
articleCategories: {
type: 'nested',
properties: {
// Who connected the replyId with the article.
// Empty if the category is added by AI
userId: { type: 'keyword' },
appId: { type: 'keyword' },
// exists only for AI tags
aiModel: {type: 'keyword'},
aiConfidence: { type: 'double' },
// Counter cache for feedbacks
positiveFeedbackCount: { type: 'long' },
negativeFeedbackCount: { type: 'long' },
// Foreign key
categoryId: { type: 'keyword' },
status: { type: 'keyword' }, // NORMAL, DELETED
createdAt: { type: 'date' },
updatedAt: { type: 'date' },
},
},
}
articlecategoryfeedbacks = {
// The article ID and reply ID is used in calculating replyrequests' ID.
articleId: { type: 'keyword' },
categoryId: { type: 'keyword' },
// Auth
userId: { type: 'keyword' },
// The user submits the feedback with which client.
// Should be one of backend APP ID, 'BOT_LEGACY', 'RUMORS_LINE_BOT' or 'WEBSITE'
appId: { type: 'keyword' },
score: { type: 'byte' }, // 1, -1
comment: { type: 'text', analyzer: 'cjk_url_email' }, // user comment for the article category
createdAt: { type: 'date' },
updatedAt: { type: 'date' },
}
// categories
categories = {
properties: {
title: { type: 'text', analyzer: 'cjk' },
description: { type: 'text', analyzer: 'cjk' },
createdAt: { type: 'date' },
updatedAt: { type: 'date' },
}
};
```
## GraphQL
看 `# [[NEW]]` 的
```graphql
# [[NEW]]
type Category {
id: String
title: String
description: String
createdAt: String
updatedAt: String
}
type Article {
id: String
text: String
createdAt: String
updatedAt: String
""" [[NEW]] Number of normal article categories"""
categoryCount: Int
# [[NEW]]
articleCategories(
"""
When specified, returns only article category with the specified status
"""
status: ArticleCategoryStatusEnum
): [ArticleCategory]
"""Number of normal article replies"""
replyCount: Int
"""
Connections between this article and replies. Sorted by the logic described in
https://github.com/cofacts/rumors-line-bot/issues/78.
"""
articleReplies(
"""
When specified, returns only article replies with the specified status
"""
status: ArticleReplyStatusEnum
): [ArticleReply]
}
"""The linkage between an Article and a Reply"""
type ArticleReply {
replyId: String
reply: Reply
articleId: String
article: Article
"""The user who conencted this reply and this article."""
user: User
canUpdateStatus: Boolean
feedbackCount: Int
positiveFeedbackCount: Int
negativeFeedbackCount: Int
feedbacks: [ArticleReplyFeedback]
"""
The feedback of current user. null when not logged in or not voted yet.
"""
ownVote: FeedbackVote
status: ArticleReplyStatusEnum
createdAt: String
updatedAt: String
}
"""[[NEW]] The linkage between an Article and a Category"""
type ArticleCategory {
categoryId: String
category: Category
articleId: String
article: Article
"""The user who conencted this category and this article."""
user: User
aiModel: String
aiConfidence: Float
canUpdateStatus: Boolean
feedbackCount: Int
positiveFeedbackCount: Int
negativeFeedbackCount: Int
feedbacks: [ArticleCategoryFeedback]
"""
The feedback of current user. null when not logged in or not voted yet.
"""
ownVote: FeedbackVote
status: ArticleCategoryStatusEnum
createdAt: String
updatedAt: String
}
"""User feedback to an ArticleReply"""
type ArticleReplyFeedback {
id: String
user: User
comment: String
"""
One of 1, 0 and -1. Representing upvote, neutral and downvote, respectively
[[NEW]] Breaking change for UI
"""
score: FeedbackVote
}
"""[[NEW]] User feedback to an ArticleCategory"""
type ArticleCategoryFeedback {
id: String
user: User
comment: String
"""
One of 1, 0 and -1. Representing upvote, neutral and downvote, respectively
"""
score: FeedbackVote
}
enum ArticleReplyStatusEnum {
NORMAL
DELETED
}
# [[NEW]]
enum ArticleCategoryStatusEnum {
NORMAL
DELETED
}
enum FeedbackVote {
UPVOTE
NEUTRAL
DOWNVOTE
}
input ListArticleFilter {
"""List only the articles whose number of replies matches the criteria."""
replyCount: ListArticleReplyCountExpr
# [[NEW]]
categoryCount: ListArticleReplyCountExpr
# [[NEW]] Articles with more matching categories will come to front
categoryIds: [String]
"""List all articles related to a given string."""
moreLikeThis: ListArticleMoreLikeThisInput
"""List only the articles whose number of replies matches the criteria."""
replyRequestCount: ListArticleReplyRequestCountExpr
"""Use with userId to show only articles from a specific user."""
appId: String
"""Use with appId to show only articles from a specific user."""
userId: String
"""
Specify an articleId here to show only articles from the sender of that specified article.
When specified, it overrides the settings of appId and userId.
"""
fromUserOfArticleId: String
}
input ListArticleMoreLikeThisInput {
"""The text string to query."""
like: String
minimumShouldMatch: String
}
"""
An entry of orderBy argument. Specifies field name and the sort order. Only one field name is allowd per entry.
"""
input ListArticleOrderBy {
_score: SortOrderEnum
updatedAt: SortOrderEnum
createdAt: SortOrderEnum
replyRequestCount: SortOrderEnum
replyCount: SortOrderEnum
lastRequestedAt: SortOrderEnum
}
input ListArticleReplyCountExpr {
LT: Int
GT: Int
EQ: Int
}
input ListArticleReplyRequestCountExpr {
LT: Int
GT: Int
EQ: Int
}
type ListReplyConnection {
"""
The total count of the entire collection, regardless of "before", "after".
"""
totalCount: Int
edges: [ListReplyConnectionEdges]
pageInfo: ListReplyConnectionPageInfo
}
type ListReplyConnectionEdges {
node: Reply
cursor: String
score: Float
}
type ListReplyConnectionPageInfo {
"""
The cursor pointing to the last node of the entire collection, regardless of
"before" and "after". Can be used to determine if is in the last page.
"""
lastCursor: String
"""
The cursor pointing to the first node of the entire collection, regardless of
"before" and "after". Can be used to determine if is in first page.
"""
firstCursor: String
}
input ListReplyFilter {
moreLikeThis: ListReplyMoreLikeThisInput
"""List the replies created by the requester themselves"""
selfOnly: Boolean
"""List the replies of certain types"""
type: ReplyTypeEnum
}
input ListReplyMoreLikeThisInput {
like: String
minimumShouldMatch: String
}
"""
An entry of orderBy argument. Specifies field name and the sort order. Only one field name is allowd per entry.
"""
input ListReplyOrderBy {
_score: SortOrderEnum
createdAt: SortOrderEnum
}
type Mutation {
"""Create an article and/or a replyRequest"""
CreateArticle(
text: String!
reference: ArticleReferenceInput!
"""
The reason why the user want to submit this article. Mandatory for 1st sender
"""
reason: String
): MutationResult
"""Create a reply that replies to the specified article."""
CreateReply(articleId: String!, text: String!, type: ReplyTypeEnum!, reference: String): MutationResult
"""Connects specified reply and specified article."""
CreateArticleReply(articleId: String!, replyId: String!): [ArticleReply]
"""[[NEW]] Connects specified reply and specified article."""
CreateArticleCategory(articleId: String!, categoryId: String!): [ArticleCategory]
"""Create or update a feedback on an article-reply connection"""
CreateOrUpdateArticleReplyFeedback(articleId: String!, replyId: String!, vote: FeedbackVote!, comment: String): ArticleReply
"""[[NEW]] Create or update a feedback on an article-reply connection"""
CreateOrUpdateArticleCategoryFeedback(articleId: String!, categoryId: String!, vote: FeedbackVote!, comment: String): ArticleCategory
"""Change status of specified articleReplies"""
UpdateArticleReplyStatus(articleId: String!, replyId: String!, status: ArticleReplyStatusEnum!): [ArticleReply]
"""[[NEW]] Change status of specified articleCategories"""
UpdateArticleCategoryStatus(articleId: String!, categoryId: String!, status: ArticleCategoryStatusEnum!): [ArticleCategory]
}
type Query {
GetArticle(id: String): Article
ListArticles(
filter: ListArticleFilter
orderBy: [ListArticleOrderBy]
"""Returns only first <first> results"""
first: Int = 10
"""
Specify a cursor, returns results after this cursor. cannot be used with "before".
"""
after: String
"""
Specify a cursor, returns results before this cursor. cannot be used with "after".
"""
before: String
): ArticleConnection
}
```