From 0804d54759fb1454689084c78bff38f332c4ceca Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 24 Feb 2021 12:28:08 -0500 Subject: [PATCH] spec: schema docs for new ACP dashboard subpage routes --- .../components/schemas/TopicObject.yaml | 4 +- .../components/schemas/UserObject.yaml | 1 + .../components/schemas/admin/dashboard.yaml | 47 ++++++++++++++++ public/openapi/read.yaml | 6 ++ public/openapi/read/admin/dashboard.yaml | 34 +----------- .../openapi/read/admin/dashboard/logins.yaml | 55 +++++++++++++++++++ .../openapi/read/admin/dashboard/topics.yaml | 34 ++++++++++++ .../openapi/read/admin/dashboard/users.yaml | 34 ++++++++++++ public/openapi/write.yaml | 2 + public/openapi/write/admin/analytics/set.yaml | 46 ++++++++++++++++ src/controllers/admin/dashboard.js | 4 +- test/api.js | 6 +- 12 files changed, 235 insertions(+), 38 deletions(-) create mode 100644 public/openapi/components/schemas/admin/dashboard.yaml create mode 100644 public/openapi/read/admin/dashboard/logins.yaml create mode 100644 public/openapi/read/admin/dashboard/topics.yaml create mode 100644 public/openapi/read/admin/dashboard/users.yaml create mode 100644 public/openapi/write/admin/analytics/set.yaml diff --git a/public/openapi/components/schemas/TopicObject.yaml b/public/openapi/components/schemas/TopicObject.yaml index db8259b70e..3cb76088aa 100644 --- a/public/openapi/components/schemas/TopicObject.yaml +++ b/public/openapi/components/schemas/TopicObject.yaml @@ -168,8 +168,6 @@ TopicObject: items: type: string description: HTML injected into the theme - index: - type: number - type: object description: Optional properties that may or may not be present (except for `tid`, which is always present, and is only here as a hack to pass validation) properties: @@ -184,6 +182,8 @@ TopicObject: pinExpiryISO: type: string description: "`pinExpiry` rendered as an ISO 8601 format" + index: + type: number required: - tid TopicObjectSlim: diff --git a/public/openapi/components/schemas/UserObject.yaml b/public/openapi/components/schemas/UserObject.yaml index d1621e13df..383828b900 100644 --- a/public/openapi/components/schemas/UserObject.yaml +++ b/public/openapi/components/schemas/UserObject.yaml @@ -127,6 +127,7 @@ UserObject: groupTitle: type: string example: '["administrators","Staff"]' + nullable: true groupTitleArray: type: array example: diff --git a/public/openapi/components/schemas/admin/dashboard.yaml b/public/openapi/components/schemas/admin/dashboard.yaml new file mode 100644 index 0000000000..54a2b51a93 --- /dev/null +++ b/public/openapi/components/schemas/admin/dashboard.yaml @@ -0,0 +1,47 @@ +Stats: + type: object + properties: + stats: + type: array + items: + allOf: + - type: object + properties: + yesterday: + type: number + today: + type: number + lastweek: + type: number + thisweek: + type: number + lastmonth: + type: number + thismonth: + type: number + alltime: + type: number + dayIncrease: + type: string + dayTextClass: + type: string + weekIncrease: + type: string + weekTextClass: + type: string + monthIncrease: + type: string + monthTextClass: + type: string + name: + type: string + - type: object + description: Optional properties that may or may not be present (except for `cid`, which is always present, and is only here as a hack to pass validation) + properties: + name: + type: string + href: + type: string + description: Relative path to dashboard analytics sub-page, if applicable. + required: + - name \ No newline at end of file diff --git a/public/openapi/read.yaml b/public/openapi/read.yaml index f849b2a995..0058822c63 100644 --- a/public/openapi/read.yaml +++ b/public/openapi/read.yaml @@ -63,6 +63,12 @@ paths: $ref: 'read/admin.yaml' /api/admin/dashboard: $ref: 'read/admin/dashboard.yaml' + /api/admin/dashboard/logins: + $ref: 'read/admin/dashboard/logins.yaml' + /api/admin/dashboard/users: + $ref: 'read/admin/dashboard/users.yaml' + /api/admin/dashboard/topics: + $ref: 'read/admin/dashboard/topics.yaml' "/api/admin/settings/{term}": $ref: 'read/admin/settings/term.yaml' /api/admin/settings/languages: diff --git a/public/openapi/read/admin/dashboard.yaml b/public/openapi/read/admin/dashboard.yaml index 296a8c6b61..a281150473 100644 --- a/public/openapi/read/admin/dashboard.yaml +++ b/public/openapi/read/admin/dashboard.yaml @@ -40,39 +40,6 @@ get: type: string required: - done - stats: - type: array - items: - type: object - properties: - yesterday: - type: number - today: - type: number - lastweek: - type: number - thisweek: - type: number - lastmonth: - type: number - thismonth: - type: number - alltime: - type: number - dayIncrease: - type: string - dayTextClass: - type: string - weekIncrease: - type: string - weekTextClass: - type: string - monthIncrease: - type: string - monthTextClass: - type: string - name: - type: string canRestart: type: boolean lastrestart: @@ -93,4 +60,5 @@ get: description: An ISO 8601 formatted date string (complementing `timestamp`) showSystemControls: type: boolean + - $ref: ../../components/schemas/admin/dashboard.yaml#/Stats - $ref: ../../components/schemas/CommonProps.yaml#/CommonProps \ No newline at end of file diff --git a/public/openapi/read/admin/dashboard/logins.yaml b/public/openapi/read/admin/dashboard/logins.yaml new file mode 100644 index 0000000000..2b3280eed3 --- /dev/null +++ b/public/openapi/read/admin/dashboard/logins.yaml @@ -0,0 +1,55 @@ +get: + tags: + - admin + summary: Get detailed login analytics + responses: + "200": + description: A JSON object containing more detailed analytics related to user login sessions. + content: + application/json: + schema: + allOf: + - type: object + properties: + set: + type: string + description: The analytics set that is being queried + query: + additionalProperties: + description: An object containing the query string parameters, if any + summary: + type: object + properties: + day: + type: number + week: + type: number + month: + type: number + sessions: + type: array + items: + type: object + properties: + ip: + type: string + uuid: + type: string + datetime: + type: number + platform: + type: string + browser: + type: string + version: + type: string + current: + type: boolean + datetimeISO: + type: string + user: + $ref: ../../../components/schemas/UserObj.yaml#/UserObj + loginDays: + type: number + - $ref: ../../../components/schemas/admin/dashboard.yaml#/Stats + - $ref: ../../../components/schemas/CommonProps.yaml#/CommonProps \ No newline at end of file diff --git a/public/openapi/read/admin/dashboard/topics.yaml b/public/openapi/read/admin/dashboard/topics.yaml new file mode 100644 index 0000000000..2a787893c1 --- /dev/null +++ b/public/openapi/read/admin/dashboard/topics.yaml @@ -0,0 +1,34 @@ +get: + tags: + - admin + summary: Get detailed user registration analytics + responses: + "200": + description: A JSON object containing more detailed analytics related to user registrations. + content: + application/json: + schema: + allOf: + - type: object + properties: + set: + type: string + description: The analytics set that is being queried + query: + additionalProperties: + description: An object containing the query string parameters, if any + summary: + type: object + properties: + day: + type: number + week: + type: number + month: + type: number + topics: + type: array + items: + $ref: ../../../components/schemas/TopicObject.yaml#/TopicObject + - $ref: ../../../components/schemas/admin/dashboard.yaml#/Stats + - $ref: ../../../components/schemas/CommonProps.yaml#/CommonProps \ No newline at end of file diff --git a/public/openapi/read/admin/dashboard/users.yaml b/public/openapi/read/admin/dashboard/users.yaml new file mode 100644 index 0000000000..67c101d943 --- /dev/null +++ b/public/openapi/read/admin/dashboard/users.yaml @@ -0,0 +1,34 @@ +get: + tags: + - admin + summary: Get detailed user registration analytics + responses: + "200": + description: A JSON object containing more detailed analytics related to user registrations. + content: + application/json: + schema: + allOf: + - type: object + properties: + set: + type: string + description: The analytics set that is being queried + query: + additionalProperties: + description: An object containing the query string parameters, if any + summary: + type: object + properties: + day: + type: number + week: + type: number + month: + type: number + users: + type: array + items: + $ref: ../../../components/schemas/UserObject.yaml#/UserObject + - $ref: ../../../components/schemas/admin/dashboard.yaml#/Stats + - $ref: ../../../components/schemas/CommonProps.yaml#/CommonProps \ No newline at end of file diff --git a/public/openapi/write.yaml b/public/openapi/write.yaml index daefcc856f..274ef5ea76 100644 --- a/public/openapi/write.yaml +++ b/public/openapi/write.yaml @@ -122,5 +122,7 @@ paths: $ref: 'write/posts/pid/diffs/timestamp.yaml' /admin/settings/{setting}: $ref: 'write/admin/settings/setting.yaml' + /admin/analytics/{set}: + $ref: 'write/admin/analytics/set.yaml' /files/: $ref: 'write/files.yaml' \ No newline at end of file diff --git a/public/openapi/write/admin/analytics/set.yaml b/public/openapi/write/admin/analytics/set.yaml new file mode 100644 index 0000000000..31f63467f1 --- /dev/null +++ b/public/openapi/write/admin/analytics/set.yaml @@ -0,0 +1,46 @@ +get: + tags: + - admin + summary: get analytics data + description: This operation retrieves analytics data from NodeBB. It is only accessible to administrators. + parameters: + - in: path + name: set + schema: + type: string + required: true + description: analytics set to retrieve + example: topics + - in: query + name: units + schema: + type: string + enum: [hours, days] + description: Whether to display dashboard data segmented daily or hourly + example: days + - in: query + name: until + schema: + type: number + description: A UNIX timestamp denoting the end of the analytics reporting period + example: '' + - in: query + name: count + schema: + type: number + description: The number of entries to return (e.g. if `units` is `hourly`, and `count` is `24`, the result set will contain 24 hours' worth of analytics) + example: 20 + responses: + '200': + description: Analytics set retrieved + content: + application/json: + schema: + type: object + properties: + status: + $ref: ../../../components/schemas/Status.yaml#/Status + response: + type: array + items: + type: number \ No newline at end of file diff --git a/src/controllers/admin/dashboard.js b/src/controllers/admin/dashboard.js index d4a75cfa27..3f85be56a1 100644 --- a/src/controllers/admin/dashboard.js +++ b/src/controllers/admin/dashboard.js @@ -174,7 +174,7 @@ async function getStatsFromAnalytics(set, field) { const sum = arr => arr.reduce((memo, cur) => memo + cur, 0); const results = { yesterday: sum(data.slice(-2)), - today: data.slice(-1), + today: data.slice(-1)[0], lastweek: sum(data.slice(-14)), thisweek: sum(data.slice(-7)), lastmonth: sum(data.slice(0)), // entire set @@ -282,7 +282,7 @@ dashboardController.getUsers = async (req, res) => { const end = parseInt(req.query.until, 10) || Date.now(); const start = end - (1000 * 60 * 60 * (req.query.units === 'days' ? 24 : 1) * (req.query.count || (req.query.units === 'days' ? 30 : 24))); const uids = await db.getSortedSetRangeByScore('users:joindate', 0, 500, start, end); - const users = await user.getUsersFields(uids, ['uid', 'username', 'email', 'joindate']); + const users = await user.getUsersData(uids); res.render('admin/dashboard/users', { set: 'registrations', diff --git a/test/api.js b/test/api.js index d2aca84943..b1c513175e 100644 --- a/test/api.js +++ b/test/api.js @@ -486,7 +486,11 @@ describe('API', async () => { if (obj.allOf) { obj = { properties: flattenAllOf(obj.allOf) }; } else { - required = required.concat(obj.required ? obj.required : Object.keys(obj.properties)); + try { + required = required.concat(obj.required ? obj.required : Object.keys(obj.properties)); + } catch (e) { + assert.fail(`Syntax error re: allOf, perhaps you allOf'd an array? (path: ${method} ${path}, context: ${context})`); + } } return { ...memo, ...obj.properties };