Skip to content

Commit 0a40f21

Browse files
authored
hotfix: refactor phase 1 (#112)
* Update router with refactors * Update article type with refactors * Update article resolver with latest public fields * Hotfix: Update findByID case * Fix: Refactor variables in router index * refactor(article mode): update content structure * chore(media model): add store and id field * chore(user model): add store field for picture * chore: add store field in issue model * fix: add ref value in role model * chore: add new role for PIC * chore: add store enum field * refactor: extract image type * chore: update admin roles * fix: update index name for user aggregation * refactor: change getTag to getTagByID per convention * fix: replace ids with searchTerm * fix: map id field in aggregation * wip: use getLatestSquiggle resolver * wip: use single id query in article type * wip: update content type for markdown * chore: remove completed TODO * chore: map id in article aggregations * refactor: update function names * fix: use conditional chaining to prevent null errors * chore: add tag.list.public permission * feat: add admin flag for tag autocomplete * fix: convert 2d to 1d array in permissions * fix: add missing return to squiggles * chore: update squiggle content structure * fix: incorrect function call in article resolver * fix: use getListOfArticles in issue type * fix: ids in article dataloader does not match * refactor: switch out mongodb find with dataloader * fix: convert IDs to string before checking equality * chore: allow createdAt, updatedAt, __typename fields in article resolver * fix: update type fields to prevent name clashes * fix: compensate for field name clashes * fix: update type fields to prevent name clashes
1 parent 613f6b3 commit 0a40f21

32 files changed

+219
-216
lines changed

.prettierignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/**/node_modules/
2-
/**/planning/
32
/**/.gitsecret/
43
/**/logs/
54
/**/out/

planning/v1/ROLES.md

+14-12
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@
4343

4444
### Article Roles
4545

46-
| Role Name | article.read.restricted | article.read.unpublished | article.read.admin | article.list.restricted | article.list.unpublished | article.write.new | article.write.self | user.write.all |
47-
| ---------------- | ----------------------- | ------------------------ | ------------------ | ----------------------- | ------------------------ | ----------------- | ------------------ | -------------- |
48-
| article.verified | Y | N | N | Y | N | N | N | N |
49-
| article.team | Y | Y | Y | Y | Y | N | Y | N |
50-
| article.author | Y | Y | Y | Y | Y | Y | Y | N |
51-
| article.admin | Y | Y | Y | Y | Y | Y | Y | Y |
52-
| | | | | | | | | |
46+
| Role Name | article.read.restricted | article.read.unpublished | article.read.admin | article.list.restricted | article.list.unpublished | article.write.new | article.write.self | article.write.all |
47+
| ---------------- | ----------------------- | ------------------------ | ------------------ | ----------------------- | ------------------------ | ----------------- | ------------------ | ----------------- |
48+
| article.verified | Y | N | N | Y | N | N | N | N |
49+
| article.pic | Y | Y | N | Y | Y | N | N | N |
50+
| article.team | Y | Y | Y | Y | Y | N | Y | N |
51+
| article.author | Y | Y | Y | Y | Y | Y | Y | N |
52+
| article.admin | Y | Y | Y | Y | Y | Y | Y | Y |
53+
| | | | | | | | | |
5354

5455
---
5556

@@ -82,17 +83,18 @@
8283
| Permission Name | Description |
8384
| ---------------- | ------------------------------------ |
8485
| tag.read.admin | Can read admin tags |
86+
| tag.list.public | Can list/search public tags |
8587
| tag.list.admin | Can list/search admin tags |
8688
| tag.write.public | Can create/update/delete public tags |
8789
| tag.write.admin | Can create/update/delete admin tags |
8890
| | |
8991

9092
### Tag Roles
9193

92-
| Role Name | tag.read.admin | tag.list.admin | tag.write.public | tag.write.admin |
93-
| --------- | -------------- | -------------- | ---------------- | --------------- |
94-
| tag.team | Y | Y | Y | N |
95-
| tag.admin | Y | Y | Y | Y |
96-
| | | | | |
94+
| Role Name | tag.read.admin | tag.list.public | tag.list.admin | tag.write.public | tag.write.admin |
95+
| --------- | -------------- | --------------- | -------------- | ---------------- | --------------- |
96+
| tag.team | Y | Y | N | Y | N |
97+
| tag.admin | Y | Y | Y | Y | Y |
98+
| | | | | | |
9799

98100
---

server/router/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212

1313
const express = require('express');
14-
const { CacheRoles } = require('../helpers/authorization');
14+
const { cache } = require('../utils/userAuth/role');
1515

1616
/**
1717
* @summary Express Router Object
@@ -23,10 +23,10 @@ const { CacheRoles } = require('../helpers/authorization');
2323
const router = express.Router();
2424

2525
/** Updates roles cache */
26-
router.use('/admin/roles/sync', async (_req, res) => res.send(await CacheRoles()));
26+
router.use('/admin/roles/sync', async (_req, res) => res.send(await cache()));
2727

2828
/** 404 Not Found - Default Response for Invalid Path */
29-
router.use((req, res) => {
29+
router.use((_req, res) => {
3030
res.json({
3131
error: true,
3232
code: 404,

server/schema/article/article.datasources.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ const findByID = () =>
3535
async (ids) => {
3636
try {
3737
const _articles = await ArticleModel.find({ _id: ids });
38-
return ids.map((id) => _articles.find((_u) => _u.id === id) || null);
38+
const _returnIds = ids.map((id) => _articles.find((_u) => _u.id.toString() === id.toString()) || null);
39+
return _returnIds;
3940
} catch (error) {
4041
throw APIError(null, error);
4142
}
@@ -89,6 +90,7 @@ const search = (keywords, allowRestricted, onlyPublished, limit, offset) =>
8990
},
9091
{
9192
$addFields: {
93+
id: '$_id',
9294
searchScore: {
9395
$meta: 'searchScore',
9496
},

server/schema/article/article.model.js

+2-74
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,9 @@ const ArticleSchema = new Schema(
123123
required: false,
124124
default: false,
125125
},
126-
// TODO: update content with final structure
127126
content: [
128127
{
129-
plaintext: {
128+
text: {
130129
type: String,
131130
required: true,
132131
},
@@ -138,6 +137,7 @@ const ArticleSchema = new Schema(
138137
/** Only for image type */
139138
media: {
140139
type: Schema.Types.ObjectId,
140+
ref: 'Media',
141141
required: false,
142142
},
143143
/**
@@ -206,78 +206,6 @@ const ArticleSchema = new Schema(
206206
max: 9,
207207
},
208208
},
209-
textFormatting: [
210-
{
211-
bold: {
212-
type: Boolean,
213-
required: false,
214-
},
215-
italic: {
216-
type: Boolean,
217-
required: false,
218-
},
219-
underline: {
220-
type: Boolean,
221-
required: false,
222-
},
223-
strikethrough: {
224-
type: Boolean,
225-
required: false,
226-
},
227-
subscript: {
228-
type: Boolean,
229-
required: false,
230-
},
231-
superscript: {
232-
type: Boolean,
233-
required: false,
234-
},
235-
size: {
236-
type: Number,
237-
required: false,
238-
min: 1,
239-
max: 48,
240-
},
241-
/** Index of list item or table cell */
242-
elementIndex: {
243-
type: String,
244-
required: false,
245-
},
246-
/** Zero based index of starting character (inclusive) */
247-
start: {
248-
type: Number,
249-
required: false,
250-
},
251-
/** Zero based index of ending character (inclusive) */
252-
end: {
253-
type: Number,
254-
required: false,
255-
},
256-
},
257-
],
258-
links: [
259-
{
260-
href: {
261-
type: String,
262-
required: false,
263-
},
264-
/** Index of list item or table cell */
265-
elementIndex: {
266-
type: String,
267-
required: false,
268-
},
269-
/** Zero based index of starting character (inclusive) */
270-
start: {
271-
type: Number,
272-
required: false,
273-
},
274-
/** Zero based index of ending character (inclusive) */
275-
end: {
276-
type: Number,
277-
required: false,
278-
},
279-
},
280-
],
281209
},
282210
],
283211
engagementCount: {

server/schema/article/article.resolver.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ const PUBLIC_FIELDS = [
1313
'photographers',
1414
'designers',
1515
'tech',
16+
'categoryNumbers',
1617
'categories',
18+
'tagNames',
1719
'tags',
1820
'coverMedia',
1921
'reactions',
@@ -23,6 +25,9 @@ const PUBLIC_FIELDS = [
2325
'hits',
2426
'readTime',
2527
'timeSpent',
28+
'createdAt',
29+
'updatedAt',
30+
'__typename',
2631
];
2732
const DEF_LIMIT = 10,
2833
DEF_OFFSET = 0;
@@ -42,7 +47,7 @@ const canUpdateArticle = async (id, mid, session, authToken, decodedToken, field
4247
});
4348
}
4449

45-
const _article = await Article.findById.load(id);
50+
const _article = await Article.findByID.load(id);
4651

4752
if (!_article) {
4853
throw APIError('NOT_FOUND', null, { reason: 'The requested was not found.' });
@@ -75,7 +80,7 @@ module.exports = {
7580
try {
7681
const _fields = getFieldNodes(fieldNodes);
7782

78-
const _article = await Article.findById.load(id);
83+
const _article = await Article.findByID.load(id);
7984

8085
if (!_article) {
8186
throw APIError('NOT_FOUND', null, { reason: 'The requested article was not found.' });
@@ -131,7 +136,7 @@ module.exports = {
131136
});
132137
}
133138

134-
const _articles = await Article.find({ _id: ids }, limit, offset);
139+
const _articles = await Promise.all(ids.slice(offset, offset + limit).map((id) => Article.findByID.load(id)));
135140

136141
if (!_articles || _articles.length <= 0) {
137142
throw APIError('NOT_FOUND', null, { reason: 'The requested article(s) were not found.' });
@@ -143,7 +148,7 @@ module.exports = {
143148
decodedToken,
144149
'article.read.unpublished'
145150
);
146-
const _restritedPermission = UserPermission(session, authToken, decodedToken, 'article.read.restricted');
151+
const _restritedPermission = UserPermission.exists(session, authToken, decodedToken, 'article.read.restricted');
147152

148153
// TODO: map the articles to return correct ones with errors instead of rejecting full output
149154
if (

server/schema/article/article.type.js

+28-31
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,17 @@ const { ArticleTypeEnumType, PublishStatusEnumType } = require('./article.enum.t
2626
const CategoryMapType = require('../categoryMap/categoryMap.type');
2727
const { getCategory } = require('../categoryMap/categoryMap.resolver');
2828
const TagType = require('../tag/tag.type');
29-
const { getTag } = require('../tag/tag.resolver');
29+
const { getTagByID } = require('../tag/tag.resolver');
3030
const MediaType = require('../media/media.type');
31-
const { getMedia } = require('../media/media.resolver');
31+
const { getMediaByID } = require('../media/media.resolver');
3232

3333
const ArticleCategoryType = new GraphQLObjectType({
3434
name: 'ArticleCategory',
3535
fields: () => ({
3636
number: { type: new GraphQLNonNull(GraphQLInt) },
37-
subcategory: { type: GraphQLBoolean },
38-
referenceID: {
39-
type: GraphQLID,
40-
resolve: (parent) => parent.reference,
41-
},
42-
reference: {
37+
isSubcategory: { type: GraphQLBoolean },
38+
reference: { type: GraphQLID },
39+
category: {
4340
type: CategoryMapType,
4441
resolve: (parent, _args, context, info) =>
4542
parent?.reference ? getCategory(parent, { id: parent.reference }, context, info) : null,
@@ -52,32 +49,29 @@ const ArticleTagType = new GraphQLObjectType({
5249
fields: () => ({
5350
name: { type: GraphQLString },
5451
isAdmin: { type: GraphQLBoolean },
55-
referenceID: {
56-
type: GraphQLID,
57-
resolve: (parent) => parent.reference,
58-
},
59-
reference: {
52+
reference: { type: GraphQLID },
53+
tag: {
6054
type: TagType,
6155
resolve: (parent, _args, context, info) =>
62-
parent?.reference ? getTag(parent, { id: parent.reference }, context, info) : null,
56+
parent?.reference ? getTagByID(parent, { id: parent.reference }, context, info) : null,
6357
},
6458
}),
6559
});
6660

6761
const CoverMediaType = new GraphQLObjectType({
6862
name: 'CoverMedia',
6963
fields: () => ({
70-
squareID: { type: GraphQLID, resolve: (parent) => parent.square },
64+
squareID: { type: GraphQLID, resolve: (parent) => parent?.square },
7165
square: {
7266
type: MediaType,
7367
resolve: (parent, _args, context, info) =>
74-
parent.square ? getMedia(parent, { id: parent.square }, context, info) : null,
68+
parent?.square ? getMediaByID(parent, { id: parent.square }, context, info) : null,
7569
},
76-
rectangleID: { type: GraphQLID, resolve: (parent) => parent.rectangle },
70+
rectangleID: { type: GraphQLID, resolve: (parent) => parent?.rectangle },
7771
rectangle: {
7872
type: MediaType,
7973
resolve: (parent, _args, context, info) =>
80-
parent.rectangle ? getMedia(parent, { id: parent.rectangle }, context, info) : null,
74+
parent?.rectangle ? getMediaByID(parent, { id: parent.rectangle }, context, info) : null,
8175
},
8276
}),
8377
});
@@ -93,28 +87,31 @@ const ArticleType = new GraphQLObjectType({
9387
content: { type: new GraphQLList(ContentType) },
9488
inshort: { type: GraphQLString },
9589

96-
authors: { type: new GraphQLList(UserDetailType), resolve: (parent) => parent.users.filter((u) => u.team === 0) },
90+
authors: { type: new GraphQLList(UserDetailType), resolve: (parent) => parent?.users.filter((u) => u.team === 0) },
9791
photographers: {
9892
type: new GraphQLList(UserDetailType),
99-
resolve: (parent) => parent.users.filter((u) => u.team === 1 || u.team === 5),
93+
resolve: (parent) => parent?.users.filter((u) => u.team === 1 || u.team === 5),
94+
},
95+
designers: {
96+
type: new GraphQLList(UserDetailType),
97+
resolve: (parent) => parent?.users.filter((u) => u.team === 2),
10098
},
101-
designers: { type: new GraphQLList(UserDetailType), resolve: (parent) => parent.users.filter((u) => u.team === 2) },
102-
tech: { type: new GraphQLList(UserDetailType), resolve: (parent) => parent.users.filter((u) => u.team === 3) },
99+
tech: { type: new GraphQLList(UserDetailType), resolve: (parent) => parent?.users.filter((u) => u.team === 3) },
103100

104101
categoryNumbers: {
105102
type: new GraphQLList(GraphQLInt),
106-
resolve: (parent) => parent.categories.map((_cat) => _cat.number),
103+
resolve: (parent) => parent?.categories.map((_cat) => _cat.number),
107104
},
108105
categories: { type: new GraphQLList(ArticleCategoryType) },
109106

110107
tagNames: {
111108
type: new GraphQLList(GraphQLString),
112-
resolve: (parent) => parent.tags.filter((_tag) => !_tag.isAdmin).map((_tag) => _tag.name),
109+
resolve: (parent) => parent?.tags.filter((_tag) => !_tag.isAdmin).map((_tag) => _tag.name),
113110
},
114-
tags: { type: new GraphQLList(ArticleTagType), resolve: (parent) => parent.tags.filter((_tag) => !_tag.isAdmin) },
111+
tags: { type: new GraphQLList(ArticleTagType), resolve: (parent) => parent?.tags.filter((_tag) => !_tag.isAdmin) },
115112
adminTags: {
116113
type: new GraphQLList(ArticleTagType),
117-
resolve: (parent) => parent.tags.filter((_tag) => _tag.isAdmin),
114+
resolve: (parent) => parent?.tags.filter((_tag) => _tag.isAdmin),
118115
},
119116

120117
coverMedia: { type: CoverMediaType },
@@ -123,11 +120,11 @@ const ArticleType = new GraphQLObjectType({
123120
publishStatus: { type: PublishStatusEnumType },
124121
isInstituteRestricted: { type: GraphQLBoolean },
125122

126-
reactions: { type: GraphQLInt, resolve: (parent) => parent.engagement.reactions },
127-
comments: { type: GraphQLInt, resolve: (parent) => parent.engagement.comments },
128-
bookmarks: { type: GraphQLInt, resolve: (parent) => parent.engagement.bookmarks },
129-
views: { type: GraphQLInt, resolve: (parent) => parent.engagement.views },
130-
hits: { type: GraphQLInt, resolve: (parent) => parent.engagement.hits },
123+
reactions: { type: GraphQLInt, resolve: (parent) => parent?.engagementCount?.reactions },
124+
comments: { type: GraphQLInt, resolve: (parent) => parent?.engagementCount?.comments },
125+
bookmarks: { type: GraphQLInt, resolve: (parent) => parent?.engagementCount?.bookmarks },
126+
views: { type: GraphQLInt, resolve: (parent) => parent?.engagementCount?.views },
127+
hits: { type: GraphQLInt, resolve: (parent) => parent?.engagementCount?.hits },
131128

132129
readTime: { type: GraphQLInt },
133130
timeSpent: { type: GraphQLInt },

server/schema/categoryMap/categoryMap.datasources.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const findByID = () =>
77
async (ids) => {
88
try {
99
const _categories = await CategoryMapModel.find({ _id: ids });
10-
return ids.map((id) => _categories.find((_u) => _u.id === id) || null);
10+
return ids.map((id) => _categories.find((_u) => _u.id.toString() === id.toString()) || null);
1111
} catch (error) {
1212
throw APIError(null, error);
1313
}

0 commit comments

Comments
 (0)