فهرست منبع

Merge branch 'master' into imprv/refactor-i18n

itizawa 6 سال پیش
والد
کامیت
4f467d3e72

+ 4 - 2
config/swagger-definition.js

@@ -1,14 +1,16 @@
 const pkg = require('../package.json');
 
+const apiVersion = process.env.API_VERSION || 3;
+
 module.exports = {
   openapi: '3.0.1',
   info: {
-    title: 'GROWI REST API v3',
+    title: `GROWI REST API v${apiVersion}`,
     version: pkg.version,
   },
   servers: [
     {
-      url: 'https://demo.growi.org/_api/v3/',
+      url: 'https://demo.growi.org',
     },
   ],
 };

+ 3 - 1
package.json

@@ -20,7 +20,9 @@
     "url": "https://github.com/weseek/growi/issues"
   },
   "scripts": {
-    "build:apiv3:jsdoc": "swagger-jsdoc -o tmp/swagger.json -d config/swagger-definition.js src/server/**/*.js",
+    "build:api:jsdoc": "swagger-jsdoc -o tmp/swagger.json -d config/swagger-definition.js \"src/server/**/*.js\"",
+    "build:apiv3:jsdoc": "cross-env API_VERSION=3 npm run build:api:jsdoc",
+    "build:apiv1:jsdoc": "cross-env API_VERSION=1 npm run build:api:jsdoc",
     "build:dev:app:watch": "npm run build:dev:app -- --watch",
     "build:dev:app": "env-cmd -f config/env.dev.js webpack --config config/webpack.dev.js --progress",
     "build:dev:watch": "npm run build:dev:app:watch",

+ 38 - 12
src/client/js/components/PageEditor/CodeMirrorEditor.jsx

@@ -648,13 +648,16 @@ export default class CodeMirrorEditor extends AbstractEditor {
 
   getNavbarItems() {
     return [
+      /* eslint-disable max-len */
       <Button
         key="nav-item-bold"
         bsSize="small"
         title="Bold"
         onClick={this.createReplaceSelectionHandler('**', '**')}
       >
-        <img src="/images/icons/editor/bold.svg" alt="icon-bold" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 10.9 14">
+          <path d="M0 0h5.6c3 0 4.7 1.1 4.7 3.4a3.1 3.1 0 0 1-2.5 3.1 3.7 3.7 0 0 1 3.1 3.5c0 2.9-1.4 4-4.2 4H0zm5.2 6.5c2.7 0 2.6-1.4 2.6-3.1S7.9.7 5.6.7H2.3v5.8zm-2.9 6.6h3.4c2.1 0 2.7-1.1 2.7-3.1s0-2.8-3.2-2.8H2.3z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-italic"
@@ -662,7 +665,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Italic"
         onClick={this.createReplaceSelectionHandler('*', '*')}
       >
-        <img src="/images/icons/editor/italic.svg" alt="icon-italic" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 8.6 13.9">
+          <path d="M8.1 0a.6.6 0 0 1 .5.6c0 .3-.2.6-.7.6H6.2L3.8 12.8h1.8c.2 0 .4.3.4.5a.7.7 0 0 1-.7.6H.5c-.3 0-.5-.4-.5-.6s.4-.6.7-.6h1.7L4.9 1.2H3.1a.5.5 0 0 1-.5-.5c0-.3.1-.7.8-.7z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-strikethrough"
@@ -670,7 +675,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Strikethrough"
         onClick={this.createReplaceSelectionHandler('~~', '~~')}
       >
-        <img src="/images/icons/editor/strikethrough.svg" alt="icon-strikethrough" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 19.5 14">
+          <path d="M5.8 6.2H9C7.2 5.7 6.3 5 6.3 3.8a2.2 2.2 0 0 1 .9-1.9 4.3 4.3 0 0 1 2.5-.7 4.3 4.3 0 0 1 2.5.7 3.1 3.1 0 0 1 1.1 1.6.7.7 0 0 0 .6.4h.3a.7.7 0 0 0 .4-.8A3.6 3.6 0 0 0 13.1 1a6.7 6.7 0 0 0-6-.5 3.1 3.1 0 0 0-1.7 1.3 3.6 3.6 0 0 0-.6 2 2.9 2.9 0 0 0 1 2.3zm7 2.5a2 2 0 0 1 .6 1.4 2.4 2.4 0 0 1-1 1.9 3.7 3.7 0 0 1-2.5.7 4.6 4.6 0 0 1-3-.8 3.7 3.7 0 0 1-1.2-2 .6.6 0 0 0-.6-.5h-.2a.7.7 0 0 0-.5.8 4.1 4.1 0 0 0 1.5 2.5A6 6 0 0 0 9.8 14a7.5 7.5 0 0 0 2.6-.5 4.9 4.9 0 0 0 1.8-1.4 4.3 4.3 0 0 0 .6-2.2 5 5 0 0 0-.2-1.2zM.4 7.9a.7.7 0 0 1-.4-.5.4.4 0 0 1 .4-.4h18.8a.4.4 0 0 1 .3.6c0 .1-.1.2-.2.3z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-header"
@@ -678,7 +685,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Heading"
         onClick={this.makeHeaderHandler}
       >
-        <img src="/images/icons/editor/header.svg" alt="icon-header" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 13.7 14">
+          <path d="M10.2 0h2.9a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-.8v11.6h.8a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-2.9a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6h.8V7.2H2.7v5.6h.8a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6H.6a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6h.7V1.2H.6A.6.6 0 0 1 0 .6.6.6 0 0 1 .6 0h2.9a.6.6 0 0 1 .6.6.6.6 0 0 1-.6.6h-.8v4.9H11V1.2h-.8a.6.6 0 0 1-.6-.6.6.6 0 0 1 .6-.6z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-code"
@@ -686,7 +695,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Inline Code"
         onClick={this.createReplaceSelectionHandler('`', '`')}
       >
-        <img src="/images/icons/editor/code.svg" alt="icon-code" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 18.1 14">
+          <path d="M17.8 7.9l-4 3.8a.5.5 0 0 1-.8 0 .5.5 0 0 1 0-.8L16.8 7 13 3.2a.6.6 0 0 1 0-.9.5.5 0 0 1 .8 0l4 3.8a1.3 1.3 0 0 1 0 1.8zM5.2 2.3a.7.7 0 0 1 0 .9L1.3 7l3.9 3.9a.6.6 0 0 1 0 .8.6.6 0 0 1-.9 0L.4 7.9a1.3 1.3 0 0 1 0-1.8l3.9-3.8a.6.6 0 0 1 .9 0zM11.5.8L7.8 13.6a.6.6 0 0 1-.7.4.6.6 0 0 1-.5-.8L10.3.4a.7.7 0 0 1 .8-.4.6.6 0 0 1 .4.8z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-quote"
@@ -694,7 +705,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Quote"
         onClick={this.createAddPrefixToEachLinesHandler('> ')}
       >
-        <img src="/images/icons/editor/quote.svg" alt="icon-quote" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 17 12">
+          <path d="M5 0H2a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h3a1.7 1.7 0 0 0 1-.3V10a.9.9 0 0 1-1 1H3v1h2a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 6H2a.9.9 0 0 1-1-1V2a.9.9 0 0 1 1-1h3a.9.9 0 0 1 1 1v3a.9.9 0 0 1-1 1zm10-6h-3a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h3a1.7 1.7 0 0 0 1-.3V10a.9.9 0 0 1-1 1h-2v1h2a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 6h-3a.9.9 0 0 1-1-1V2a.9.9 0 0 1 1-1h3a.9.9 0 0 1 1 1v3a.9.9 0 0 1-1 1z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-ul"
@@ -702,7 +715,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="List"
         onClick={this.createAddPrefixToEachLinesHandler('- ')}
       >
-        <img src="/images/icons/editor/list-ul.svg" alt="icon-list-ul" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 21.6 13.5">
+          <path d="M6.4 1.5h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zm0 6h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zm0 6h14.5a.7.7 0 0 0 .7-.7.7.7 0 0 0-.7-.7H6.4a.8.8 0 0 0-.8.7.8.8 0 0 0 .8.7zM.9 1.5h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.8h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.8zm0 6h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.8h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.8zm0 6h1a.8.8 0 0 0 .9-.7.8.8 0 0 0-.9-.7h-1a.8.8 0 0 0-.9.7.8.8 0 0 0 .9.7z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-ol"
@@ -710,7 +725,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Numbered List"
         onClick={this.createAddPrefixToEachLinesHandler('1. ')}
       >
-        <img src="/images/icons/editor/list-ol.svg" alt="icon-list-ol" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 23.7 16">
+          <path d="M23.7 2a.8.8 0 0 1-.8.8H6.6a.8.8 0 0 1-.7-.8.7.7 0 0 1 .7-.7h16.3a.7.7 0 0 1 .8.7zM6.6 8.7h16.3a.7.7 0 0 0 .8-.7.8.8 0 0 0-.8-.8H6.6a.8.8 0 0 0-.7.8.7.7 0 0 0 .7.7zm0 5.9h16.3a.7.7 0 0 0 .8-.7.7.7 0 0 0-.8-.7H6.6a.7.7 0 0 0-.7.7.7.7 0 0 0 .7.7zM1.5.5V4h.6V0h-.5L.7.5v.4l.8-.4zM.9 9.6l.3-.3c.9-.9 1.4-1.5 1.4-2.2a1.2 1.2 0 0 0-1.3-1.2h-.1a1.4 1.4 0 0 0-1.2.6l.3.4a1.2 1.2 0 0 1 .9-.5.6.6 0 0 1 .8.6v.2c0 .6-.4 1.1-1.5 2.1l-.4.4v.3h2.6v-.4zm.9 4.1a1 1 0 0 0 .7-.9 1 1 0 0 0-1.1-1 2 2 0 0 0-1.1.3v.4l.8-.2c.5 0 .8.2.8.6s-.5.7-.9.7H.7v.4H1c.6 0 1.1.2 1.1.8a.8.8 0 0 1-.9.8l-.9-.3-.2.4a2 2 0 0 0 1.1.3c1 0 1.5-.6 1.5-1.2a1.2 1.2 0 0 0-.9-1.1z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-checkbox"
@@ -718,7 +735,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Check List"
         onClick={this.createAddPrefixToEachLinesHandler('- [ ] ')}
       >
-        <img src="/images/icons/editor/check.svg" alt="icon-check" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 14.4 16">
+          <path d="M13.9 5.5a.5.5 0 0 1 .5.5v9a1.1 1.1 0 0 1-1.1 1H1a1.1 1.1 0 0 1-1-1V2.6a1.1 1.1 0 0 1 1-1h7.1a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5H1V15h12.3V6a.6.6 0 0 1 .6-.5zM3.6 8.3a.5.5 0 0 0 0 .7l2.5 2.5a.8.8 0 0 0 1.1 0h.1l7-10.7c.1-.2.1-.6-.2-.7a.5.5 0 0 0-.7.1L6.6 10.6 4.3 8.3a.5.5 0 0 0-.7 0z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-link"
@@ -726,7 +745,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Link"
         onClick={this.createReplaceSelectionHandler('[', ']()')}
       >
-        <img src="/images/icons/editor/link.svg" alt="icon-link" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 16 16">
+          <path d="M4.6 11.4l.4.2h.2v-.2l6.1-6.1a.4.4 0 0 0 .1-.3.5.5 0 0 0-.5-.5h-.3l-6 6.2a.6.6 0 0 0-.1.4c0 .1 0 .3.1.3zm2.8-1a2 2 0 0 1 0 1.1 4.1 4.1 0 0 1-.5.9l-2.1 1.9a1.9 1.9 0 0 1-1.5.7 2 2 0 0 1-1.6-.7 1.9 1.9 0 0 1-.7-1.5 2 2 0 0 1 .7-1.6l1.9-2.1a2 2 0 0 1 2.2-.5l.8-.8a3.2 3.2 0 0 0-1.4-.3 3.3 3.3 0 0 0-2.3.9L1 10.5A3.2 3.2 0 0 0 .9 15H1a2.9 2.9 0 0 0 2.3 1 3.2 3.2 0 0 0 2.3-1l2-1.9a4.6 4.6 0 0 0 .9-1.7 2.9 2.9 0 0 0-.3-1.8zM15 1a2.5 2.5 0 0 0-1-.8 3.1 3.1 0 0 0-3.5.8L8.4 2.9a3.1 3.1 0 0 0-.9 1.8 3.2 3.2 0 0 0 .3 1.9l.8-.8a2 2 0 0 1 0-1.1 2.2 2.2 0 0 1 .5-1.1l2.1-1.9.3-.3.4-.2.4-.2h.5a1.9 1.9 0 0 1 1.5.7 2 2 0 0 1 .7 1.6 1.9 1.9 0 0 1-.7 1.5l-2 2.1-.7.4a1.5 1.5 0 0 1-.9.2h-.4l-.8.8H12l1-.7 2-2.1A3 3 0 0 0 15 1z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-image"
@@ -734,7 +755,9 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Image"
         onClick={this.createReplaceSelectionHandler('![', ']()')}
       >
-        <img src="/images/icons/editor/picture.svg" alt="icon-picture" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 19 16">
+          <path d="M17.8 0H1.2A1.2 1.2 0 0 0 0 1.2v13.6A1.2 1.2 0 0 0 1.2 16h16.6a1.2 1.2 0 0 0 1.2-1.2V1.2a1.4 1.4 0 0 0-.2-.6.8.8 0 0 0-.4-.4zm0 14.8H1.2v-3.5l4.7-4.6 5 4.9.3.2.5-.2 2.1-1.9 3.9 4h.1v1.1zm0-2.8l-3.5-3.5-.4-.2h-.4l-2.2 2-4.9-4.8-.4-.2c-.2 0-.4 0-.5.2L1.2 9.7V1.2h16.6V12zm-4.2-6.1h.6a1.1 1.1 0 0 0 .6-1.1 1.2 1.2 0 0 0-1.2-1.1 1.3 1.3 0 0 0-1.2 1.2 1.2 1.2 0 0 0 .4.8 1.1 1.1 0 0 0 .8.3z" />
+        </svg>
       </Button>,
       <Button
         key="nav-item-table"
@@ -742,8 +765,11 @@ export default class CodeMirrorEditor extends AbstractEditor {
         title="Table"
         onClick={this.showHandsonTableHandler}
       >
-        <img src="/images/icons/editor/table.svg" alt="icon-table" height="13" />
+        <svg xmlns="http://www.w3.org/2000/svg" height="13" viewBox="0 0 20.3 16">
+          <path d="M19.1 16H1.2A1.2 1.2 0 0 1 0 14.8V1.2A1.2 1.2 0 0 1 1.2 0h17.9a1.2 1.2 0 0 1 1.2 1.2v13.6a1.2 1.2 0 0 1-1.2 1.2zm-5.2-4.3v3.2h5.3v-3.2zm-6.4 0v3.2h5.3v-3.2zm-6.4 0v3.2h5.3v-3.2zm12.8-4.2v3.2h5.3V7.5zm-6.4 0v3.2h5.3V7.5zm-6.4 0v3.2h5.3V7.5zm12.8-4.3v3.2h5.3V3.2zm-6.4 0v3.2h5.3V3.2zm-6.4 0v3.2h5.3V3.2z" />
+        </svg>
       </Button>,
+      /* eslint-able max-len */
     ];
   }
 

+ 4 - 0
src/client/styles/agile-admin/inverse/colors/blue-night.scss

@@ -47,3 +47,7 @@ $inline-code-bg: #0a121b;
     }
   }
 }
+
+.editor-container .navbar-editor svg {
+  fill: $bodytext;
+}

+ 4 - 0
src/client/styles/agile-admin/inverse/colors/default-dark.scss

@@ -25,5 +25,9 @@ $active-navbar-border: darken($border, 3%);
 $btn-default-bgcolor: darken($basecolor, 10%);
 $inline-code-bg: darken($bodycolor, 5%);
 
+.editor-container .navbar-editor svg {
+  fill: $bodytext;
+}
+
 @import 'apply-colors';
 @import 'apply-colors-dark';

+ 4 - 0
src/client/styles/agile-admin/inverse/colors/future.scss

@@ -35,3 +35,7 @@ $inline-code-bg: darken($bodycolor, 5%);
     border-bottom: 1px solid rgb(131, 228, 215);
   }
 }
+
+.editor-container .navbar-editor svg {
+  fill: $bodytext;
+}

+ 4 - 0
src/client/styles/agile-admin/inverse/colors/halloween.scss

@@ -74,6 +74,10 @@ $inline-code-bg: #0a121b;
   background-color: rgba(0, 0, 0, 0.3);
 }
 
+.editor-container .navbar-editor svg {
+  fill: $bodytext;
+}
+
 /*
  * Tabs
  */

+ 31 - 0
src/server/models/openapi/paginate-result.js

@@ -5,6 +5,7 @@
  *  components:
  *    schemas:
  *      PaginateResult:
+ *        description: PaginateResult
  *        type: object
  *        properties:
  *          docs:
@@ -45,4 +46,34 @@
  *          meta:
  *            type: number
  *            description: Object of pagination meta data (Default false).
+ *
+ */
+
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *      V1PaginateResult:
+ *        description: Paginate result v1
+ *        type: object
+ *        properties:
+ *          meta:
+ *            type: object
+ *            properties:
+ *              total:
+ *                type: integer
+ *                description: Total number of documents in collection that match a query
+ *                example: 35
+ *              limit:
+ *                type: integer
+ *                description: Limit that was used
+ *                example: 10
+ *              offset:
+ *                type: integer
+ *                description: Only if specified or default page/offset values were used
+ *                example: 20
+ *          data:
+ *            type: object
+ *            description: Object of pagination meta data.
  */

+ 19 - 0
src/server/models/openapi/v1-response.js

@@ -0,0 +1,19 @@
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *      V1Response:
+ *        description: Response v1
+ *        type: object
+ *        properties:
+ *          ok:
+ *            type: boolean
+ *            description: API is succeeded
+ *            example: true
+ *    responses:
+ *      403:
+ *        description: 'Forbidden'
+ *      500:
+ *        description: 'Internal Server Error'
+ */

+ 51 - 32
src/server/routes/apiv3/app-settings.js

@@ -23,68 +23,75 @@ const ErrorV3 = require('../../models/vo/error-apiv3');
  *  components:
  *    schemas:
  *      AppSettingParams:
+ *        description: AppSettingParams
  *        type: object
  *        properties:
  *          title:
- *            type: String
+ *            type: string
  *            description: site name show on page header and tilte of HTML
  *          confidential:
- *            type: String
+ *            type: string
  *            description: confidential show on page header
  *          globalLang:
- *            type: String
+ *            type: string
  *            description: language set when create user
  *          fileUpload:
  *            type: boolean
  *            description: enable upload file except image file
- *     SiteUrlSettingParams:
+ *      SiteUrlSettingParams:
+ *        description: SiteUrlSettingParams
  *        type: object
  *        properties:
  *          siteUrl:
- *            type: String
+ *            type: string
  *            description: Site URL. e.g. https://example.com, https://example.com:8080
  *          envSiteUrl:
- *            type: String
+ *            type: string
  *            description: environment variable 'APP_SITE_URL'
- *     MailSettingParams:
+ *      MailSettingParams:
+ *        description: MailSettingParams
  *        type: object
  *        properties:
  *          fromAddress:
- *            type: String
+ *            type: string
  *            description: e-mail address used as from address of mail which sent from GROWI app
  *          smtpHost:
- *            type: String
+ *            type: string
  *            description: host name of client's smtp server
  *          smtpPort:
- *            type: String
+ *            type: string
  *            description: port of client's smtp server
  *          smtpUser:
- *            type: String
+ *            type: string
  *            description: user name of client's smtp server
  *          smtpPassword:
- *            type: String
+ *            type: string
  *            description: password of client's smtp server
  *      AwsSettingParams:
+ *        description: AwsSettingParams
  *        type: object
+ *        properties:
  *          region:
- *            type: String
+ *            type: string
  *            description: region of AWS S3
  *          customEndpoint:
- *            type: String
+ *            type: string
  *            description: custom endpoint of AWS S3
  *          bucket:
- *            type: String
+ *            type: string
  *            description: AWS S3 bucket name
  *          accessKeyId:
- *            type: String
+ *            type: string
  *            description: accesskey id for authentification of AWS
  *          secretKey:
- *            type: String
+ *            type: string
  *            description: secret key for authentification of AWS
  *      PluginSettingParams:
+ *        description: PluginSettingParams
  *        type: object
+ *        properties:
  *          isEnabledPlugins:
- *            type: String
+ *            type: string
  *            description: enable use plugins
  */
 
@@ -129,9 +136,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /app-settings/:
+   *    /_api/v3/app-settings:
    *      get:
-   *        tags: [AppSettings]
+   *        tags: [AppSettings, apiv3]
+   *        operationId: getAppSettings
+   *        summary: /_api/v3/app-settings
    *        description: get app setting params
    *        responses:
    *          200:
@@ -172,9 +181,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /app-settings/app-setting:
+   *    /_api/v3/app-settings/app-setting:
    *      put:
-   *        tags: [AppSettings]
+   *        tags: [AppSettings, apiv3]
+   *        summary: /_api/v3/app-settings/app-setting
+   *        operationId: updateAppSettings
    *        description: Update app setting
    *        requestBody:
    *          required: true
@@ -219,9 +230,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /app-settings/site-url-setting:
+   *    /_api/v3/app-settings/site-url-setting:
    *      put:
-   *        tags: [AppSettings]
+   *        tags: [AppSettings, apiv3]
+   *        operationId: updateAppSettingSiteUrlSetting
+   *        summary: /_api/v3/app-settings/site-url-setting
    *        description: Update site url setting
    *        requestBody:
    *          required: true
@@ -309,10 +322,12 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /app-settings/site-url-setting:
+   *    /_api/v3/app-settings/mail-setting:
    *      put:
-   *        tags: [AppSettings]
-   *        description: Update site url setting
+   *        tags: [AppSettings, apiv3]
+   *        operationId: updateAppSettingMailSetting
+   *        summary: /_api/v3/app-settings/site-url-setting
+   *        description: Update mail setting
    *        requestBody:
    *          required: true
    *          content:
@@ -321,7 +336,7 @@ module.exports = (crowi) => {
    *                $ref: '#/components/schemas/MailSettingParams'
    *        responses:
    *          200:
-   *            description: Succeeded to update site url setting
+   *            description: Succeeded to update mail setting
    *            content:
    *              application/json:
    *                schema:
@@ -369,9 +384,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /app-settings/aws-setting:
+   *    /_api/v3/app-settings/aws-setting:
    *      put:
-   *        tags: [AppSettings]
+   *        tags: [AppSettings, apiv3]
+   *        operationId: updateAppSettingAwsSetting
+   *        summary: /_api/v3/app-settings/aws-setting
    *        description: Update aws setting
    *        requestBody:
    *          required: true
@@ -418,9 +435,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /app-settings/plugin-setting:
+   *    /_api/v3/app-settings/plugin-setting:
    *      put:
-   *        tags: [AppSettings]
+   *        tags: [AppSettings, apiv3]
+   *        operationId: updateAppSettingPluginSetting
+   *        summary: /_api/v3/app-settings/plugin-setting
    *        description: Update plugin setting
    *        requestBody:
    *          required: true

+ 100 - 74
src/server/routes/apiv3/customize-setting.js

@@ -22,6 +22,7 @@ const ErrorV3 = require('../../models/vo/error-apiv3');
  *  components:
  *    schemas:
  *      CustomizeLayoutTheme:
+ *        description: CustomizeLayoutTheme
  *        type: object
  *        properties:
  *          layoutType:
@@ -29,11 +30,13 @@ const ErrorV3 = require('../../models/vo/error-apiv3');
  *          themeType:
  *            type: string
  *      CustomizeBehavior:
+ *        description: CustomizeBehavior
  *        type: object
  *        properties:
  *          behaviorType:
  *            type: string
  *      CustomizeFunction:
+ *        description: CustomizeFunction
  *        type: object
  *        properties:
  *          isEnabledTimeline:
@@ -47,6 +50,7 @@ const ErrorV3 = require('../../models/vo/error-apiv3');
  *          isEnabledStaleNotification:
  *            type: boolean
  *      CustomizeHighlight:
+ *        description: CustomizeHighlight
  *        type: object
  *        properties:
  *          styleName:
@@ -54,21 +58,25 @@ const ErrorV3 = require('../../models/vo/error-apiv3');
  *          styleBorder:
  *            type: boolean
  *      CustomizeTitle:
+ *        description: CustomizeTitle
  *        type: object
  *        properties:
  *          customizeTitle:
  *            type: string
  *      CustomizeHeader:
+ *        description: CustomizeHeader
  *        type: object
  *        properties:
  *          customizeHeader:
  *            type: string
  *      CustomizeCss:
+ *        description: CustomizeCss
  *        type: object
  *        properties:
  *          customizeCss:
  *            type: string
  *      CustomizeScript:
+ *        description: CustomizeScript
  *        type: object
  *        properties:
  *          customizeScript:
@@ -123,9 +131,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/:
+   *    /_api/v3/customize-setting:
    *      get:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: getCustomizeSetting
+   *        summary: /_api/v3/customize-setting
    *        description: Get customize paramators
    *        responses:
    *          200:
@@ -163,23 +173,25 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/layoutTheme:
+   *    /_api/v3/customize-setting/layoutTheme:
    *      put:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: updateLayoutThemeCustomizeSetting
+   *        summary: /_api/v3/customize-setting/layoutTheme
    *        description: Update layout and theme
    *        requestBody:
    *          required: true
    *          content:
    *            application/json:
-   *              schama:
-   *                $ref: '#/components/schemas/CustomizeLayoutTheme'
-   *      responses:
-   *        200:
-   *          description: Succeeded to update layout and theme
-   *          content:
-   *            application/json:
    *              schema:
    *                $ref: '#/components/schemas/CustomizeLayoutTheme'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update layout and theme
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/CustomizeLayoutTheme'
    */
   router.put('/layoutTheme', loginRequiredStrictly, adminRequired, csrf, validator.layoutTheme, ApiV3FormValidator, async(req, res) => {
     const requestParams = {
@@ -205,23 +217,25 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/behavior:
+   *    /_api/v3/customize-setting/behavior:
    *      put:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: updateBehaviorCustomizeSetting
+   *        summary: /_api/v3/customize-setting/behavior
    *        description: Update behavior
    *        requestBody:
    *          required: true
    *          content:
    *            application/json:
-   *              schama:
-   *                $ref: '#/components/schemas/CustomizeBehavior'
-   *      responses:
-   *        200:
-   *          description: Succeeded to update behavior
-   *          content:
-   *            application/json:
    *              schema:
    *                $ref: '#/components/schemas/CustomizeBehavior'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update behavior
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/CustomizeBehavior'
    */
   router.put('/behavior', loginRequiredStrictly, adminRequired, csrf, validator.behavior, ApiV3FormValidator, async(req, res) => {
     const requestParams = {
@@ -245,23 +259,25 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/function:
+   *    /_api/v3/customize-setting/function:
    *      put:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: updateFunctionCustomizeSetting
+   *        summary: /_api/v3/customize-setting/function
    *        description: Update function
    *        requestBody:
    *          required: true
    *          content:
    *            application/json:
-   *              schama:
-   *                $ref: '#/components/schemas/CustomizeFunction'
-   *      responses:
-   *        200:
-   *          description: Succeeded to update function
-   *          content:
-   *            application/json:
    *              schema:
    *                $ref: '#/components/schemas/CustomizeFunction'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update function
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/CustomizeFunction'
    */
   router.put('/function', loginRequiredStrictly, adminRequired, csrf, validator.function, ApiV3FormValidator, async(req, res) => {
     const requestParams = {
@@ -293,23 +309,25 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/highlight:
+   *    /_api/v3/customize-setting/highlight:
    *      put:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: updateHighlightCustomizeSetting
+   *        summary: /_api/v3/customize-setting/highlight
    *        description: Update highlight
    *        requestBody:
    *          required: true
    *          content:
    *            application/json:
-   *              schama:
-   *                $ref: '#/components/schemas/CustomizeHighlight'
-   *      responses:
-   *        200:
-   *          description: Succeeded to update highlight
-   *          content:
-   *            application/json:
    *              schema:
    *                $ref: '#/components/schemas/CustomizeHighlight'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update highlight
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/CustomizeHighlight'
    */
   router.put('/highlight', loginRequiredStrictly, adminRequired, csrf, validator.highlight, ApiV3FormValidator, async(req, res) => {
     const requestParams = {
@@ -335,9 +353,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/customizeTitle:
+   *    /_api/v3/customize-setting/customizeTitle:
    *      put:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: updateCustomizeTitleCustomizeSetting
+   *        summary: /_api/v3/customize-setting/customizeTitle
    *        description: Update customizeTitle
    *        requestBody:
    *          required: true
@@ -345,13 +365,13 @@ module.exports = (crowi) => {
    *            application/json:
    *              schema:
    *                $ref: '#/components/schemas/CustomizeTitle'
-   *      responses:
-   *        200:
-   *          description: Succeeded to update customizeTitle
-   *          content:
-   *            application/json:
-   *              schema:
-   *                $ref: '#/components/schemas/CustomizeTitle'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update customizeTitle
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/CustomizeTitle'
    */
   router.put('/customize-title', loginRequiredStrictly, adminRequired, csrf, validator.customizeTitle, ApiV3FormValidator, async(req, res) => {
     const requestParams = {
@@ -376,23 +396,25 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/customizeHeader:
+   *    /_api/v3/customize-setting/customizeHeader:
    *      put:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: updateCustomizeHeaderCustomizeSetting
+   *        summary: /_api/v3/customize-setting/customizeHeader
    *        description: Update customizeHeader
    *        requestBody:
    *          required: true
    *          content:
    *            application/json:
-   *              schama:
-   *                $ref: '#/components/schemas/CustomizeHeader'
-   *      responses:
-   *        200:
-   *          description: Succeeded to update customize header
-   *          content:
-   *            application/json:
    *              schema:
    *                $ref: '#/components/schemas/CustomizeHeader'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update customize header
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/CustomizeHeader'
    */
   router.put('/customize-header', loginRequiredStrictly, adminRequired, csrf, validator.customizeHeader, ApiV3FormValidator, async(req, res) => {
     const requestParams = {
@@ -415,23 +437,25 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/customizeCss:
+   *    /_api/v3/customize-setting/customizeCss:
    *      put:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: updateCustomizeCssCustomizeSetting
+   *        summary: /_api/v3/customize-setting/customizeCss
    *        description: Update customizeCss
    *        requestBody:
    *          required: true
    *          content:
    *            application/json:
-   *              schama:
-   *                $ref: '#/components/schemas/CustomizeCss'
-   *      responses:
-   *        200:
-   *          description: Succeeded to update customize css
-   *          content:
-   *            application/json:
    *              schema:
    *                $ref: '#/components/schemas/CustomizeCss'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update customize css
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/CustomizeCss'
    */
   router.put('/customize-css', loginRequiredStrictly, adminRequired, csrf, validator.customizeCss, ApiV3FormValidator, async(req, res) => {
     const requestParams = {
@@ -455,23 +479,25 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /customize-setting/customizeScript:
+   *    /_api/v3/customize-setting/customizeScript:
    *      put:
-   *        tags: [CustomizeSetting]
+   *        tags: [CustomizeSetting, apiv3]
+   *        operationId: updateCustomizeScriptCustomizeSetting
+   *        summary: /_api/v3/customize-setting/customizeScript
    *        description: Update customizeScript
    *        requestBody:
    *          required: true
    *          content:
    *            application/json:
-   *              schama:
-   *                $ref: '#/components/schemas/CustomizeScript'
-   *      responses:
-   *        200:
-   *          description: Succeeded to update customize script
-   *          content:
-   *            application/json:
    *              schema:
    *                $ref: '#/components/schemas/CustomizeScript'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update customize script
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/CustomizeScript'
    */
   router.put('/customize-script', loginRequiredStrictly, adminRequired, csrf, validator.customizeScript, ApiV3FormValidator, async(req, res) => {
     const requestParams = {

+ 13 - 6
src/server/routes/apiv3/export.js

@@ -19,6 +19,7 @@ const router = express.Router();
  *  components:
  *    schemas:
  *      ExportStatus:
+ *        description: ExportStatus
  *        type: object
  *        properties:
  *          zipFileStats:
@@ -61,9 +62,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /export/status:
+   *  /_api/v3/export/status:
    *    get:
-   *      tags: [Export]
+   *      tags: [Export, apiv3]
+   *      operationId: getExportStatus
+   *      summary: /_api/v3/export/status
    *      description: get properties of stored zip files for export
    *      responses:
    *        200:
@@ -88,9 +91,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /export:
+   *  /_api/v3/export:
    *    post:
-   *      tags: [Export]
+   *      tags: [Export, apiv3]
+   *      operationId: createExport
+   *      summary: /_api/v3/export
    *      description: generate zipped jsons for collections
    *      responses:
    *        200:
@@ -124,9 +129,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /export/{fileName}:
+   *  /_api/v3/export/{fileName}:
    *    delete:
-   *      tags: [Export]
+   *      tags: [Export, apiv3]
+   *      operationId: deleteExport
+   *      summary: /_api/v3/export/{fileName}
    *      description: delete the file
    *      parameters:
    *        - name: fileName

+ 4 - 2
src/server/routes/apiv3/healthcheck.js

@@ -18,9 +18,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /healthcheck:
+   *  /_api/v3/healthcheck:
    *    get:
-   *      tags: [Healthcheck]
+   *      tags: [Healthcheck, apiv3]
+   *      operationId: getHealthcheck
+   *      summary: /_api/v3/healthcheck
    *      description: Check whether the server is healthy or not
    *      parameters:
    *        - name: connectToMiddlewares

+ 17 - 8
src/server/routes/apiv3/import.js

@@ -24,6 +24,7 @@ const router = express.Router();
  *  components:
  *    schemas:
  *      ImportStatus:
+ *        description: ImportStatus
  *        type: object
  *        properties:
  *          zipFileStat:
@@ -100,9 +101,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /import/status:
+   *  /_api/v3/import/status:
    *    get:
-   *      tags: [Import]
+   *      tags: [Import, apiv3]
+   *      operationId: getImportStatus
+   *      summary: /_api/v3/import/status
    *      description: Get properties of stored zip files for import
    *      responses:
    *        200:
@@ -127,9 +130,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /import:
+   *  /_api/v3/import:
    *    post:
-   *      tags: [Import]
+   *      tags: [Import, apiv3]
+   *      operationId: executeImport
+   *      summary: /_api/v3/import
    *      description: import a collection from a zipped json
    *      requestBody:
    *        required: true
@@ -236,9 +241,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /import/upload:
+   *  /_api/v3/import/upload:
    *    post:
-   *      tags: [Import]
+   *      tags: [Import, apiv3]
+   *      operationId: uploadImport
+   *      summary: /_api/v3/import/upload
    *      description: upload a zip file
    *      responses:
    *        200:
@@ -281,9 +288,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /import/all:
+   *  /_api/v3/import/all:
    *    delete:
-   *      tags: [Import]
+   *      tags: [Import, apiv3]
+   *      operationId: deleteImportAll
+   *      summary: /_api/v3/import/all
    *      description: Delete all zip files
    *      responses:
    *        200:

+ 19 - 8
src/server/routes/apiv3/markdown-setting.js

@@ -39,6 +39,7 @@ const validator = {
  *  components:
  *    schemas:
  *      LineBreakParams:
+ *        description: LineBreakParams
  *        type: object
  *        properties:
  *          isEnabledLinebreaks:
@@ -48,6 +49,7 @@ const validator = {
  *            type: boolean
  *            description: enable lineBreak in comment
  *      PresentationParams:
+ *        description: PresentationParams
  *        type: object
  *        properties:
  *          pageBreakSeparator:
@@ -57,6 +59,7 @@ const validator = {
  *            type: string
  *            description: string of pageBreakCustomSeparator
  *      XssParams:
+ *        description: XssParams
  *        type: object
  *        properties:
  *          isEnabledPrevention:
@@ -89,9 +92,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /markdown-setting/:
+   *    /_api/v3/markdown-setting:
    *      get:
-   *        tags: [MarkDownSettind]
+   *        tags: [MarkDownSetting, apiv3]
+   *        operationId: getMarkdownSetting
+   *        summary: /_api/v3/markdown-setting
    *        description: Get markdown paramators
    *        responses:
    *          200:
@@ -122,9 +127,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /markdown-setting/lineBreak:
+   *    /_api/v3/markdown-setting/lineBreak:
    *      put:
-   *        tags: [MarkDownSetting]
+   *        tags: [MarkDownSetting, apiv3]
+   *        operationId: updateLineBreakMarkdownSetting
+   *        summary: /_api/v3/markdown-setting/lineBreak
    *        description: Update lineBreak setting
    *        requestBody:
    *          required: true
@@ -166,9 +173,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /markdown-setting/presentation:
+   *    /_api/v3/markdown-setting/presentation:
    *      put:
-   *        tags: [MarkDownSetting]
+   *        tags: [MarkDownSetting, apiv3]
+   *        operationId: updatePresentationMarkdownSetting
+   *        summary: /_api/v3/markdown-setting/presentation
    *        description: Update presentation
    *        requestBody:
    *          required: true
@@ -213,9 +222,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *    /markdown-setting/xss:
+   *    /_api/v3/markdown-setting/xss:
    *      put:
-   *        tags: [MarkDownSetting]
+   *        tags: [MarkDownSetting, apiv3]
+   *        operationId: updateXssMarkdownSetting
+   *        summary: /_api/v3/markdown-setting/xss
    *        description: Update xss
    *        requestBody:
    *          required: true

+ 4 - 2
src/server/routes/apiv3/mongo.js

@@ -17,9 +17,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /mongo/collections:
+   *  /_api/v3/mongo/collections:
    *    get:
-   *      tags: [Mongo]
+   *      tags: [Mongo, apiv3]
+   *      operationId: getMongoCollections
+   *      summary: /_api/v3/mongo/collections
    *      description: get mongodb collections names
    *      responses:
    *        200:

+ 4 - 2
src/server/routes/apiv3/statistics.js

@@ -83,9 +83,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *
-   *  /statistics/user:
+   *  /_api/v3/statistics/user:
    *    get:
-   *      tags: [Statistics]
+   *      tags: [Statistics, apiv3]
+   *      operationId: getStatisticsUser
+   *      summary: /_api/v3/statistics/user
    *      description: Get statistics for user
    *      responses:
    *        200:

+ 4 - 2
src/server/routes/apiv3/user-group-relation.js

@@ -23,9 +23,11 @@ module.exports = (crowi) => {
   /**
    * @swagger
    *  paths:
-   *    /user-group-relations:
+   *    /_api/v3/user-group-relations:
    *      get:
-   *        tags: [UserGroupRelation]
+   *        tags: [UserGroupRelation, apiv3]
+   *        operationId: listUserGroupRelations
+   *        summary: /_api/v3/user-group-relations
    *        description: Gets the user group relations
    *        responses:
    *          200:

+ 40 - 20
src/server/routes/apiv3/user-group.js

@@ -43,9 +43,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups:
+   *    /_api/v3/user-groups:
    *      get:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: getUserGroup
+   *        summary: /_api/v3/user-groups
    *        description: Get usergroups
    *        responses:
    *          200:
@@ -81,9 +83,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups:
+   *    /_api/v3/user-groups:
    *      post:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: createUserGroup
+   *        summary: /_api/v3/user-groups
    *        description: Adds userGroup
    *        requestBody:
    *          required: true
@@ -131,9 +135,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups/{id}:
+   *    /_api/v3/user-groups/{id}:
    *      delete:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: deleteUserGroup
+   *        summary: /_api/v3/user-groups/{id}
    *        description: Deletes userGroup
    *        parameters:
    *          - name: id
@@ -191,9 +197,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups/{id}:
+   *    /_api/v3/user-groups/{id}:
    *      put:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: updateUserGroups
+   *        summary: /_api/v3/user-groups/{id}
    *        description: Update userGroup
    *        parameters:
    *          - name: id
@@ -246,9 +254,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups/{id}/users:
+   *    /_api/v3/user-groups/{id}/users:
    *      get:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: getUsersUserGroups
+   *        summary: /_api/v3/user-groups/{id}/users
    *        description: Get users related to the userGroup
    *        parameters:
    *          - name: id
@@ -294,9 +304,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups/{id}/unrelated-users:
+   *    /_api/v3/user-groups/{id}/unrelated-users:
    *      get:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: getUnrelatedUsersUserGroups
+   *        summary: /_api/v3/user-groups/{id}/unrelated-users
    *        description: Get users unrelated to the userGroup
    *        parameters:
    *          - name: id
@@ -350,9 +362,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups/{id}/users:
+   *    /_api/v3/user-groups/{id}/users:
    *      post:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: addUserUserGroups
+   *        summary: /_api/v3/user-groups/{id}/users
    *        description: Add a user to the userGroup
    *        parameters:
    *          - name: id
@@ -417,9 +431,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups/{id}/users:
+   *    /_api/v3/user-groups/{id}/users:
    *      delete:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: deleteUsersUserGroups
+   *        summary: /_api/v3/user-groups/{id}/users
    *        description: remove a user from the userGroup
    *        parameters:
    *          - name: id
@@ -477,9 +493,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups/{id}/user-group-relations:
+   *    /_api/v3/user-groups/{id}/user-group-relations:
    *      get:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: getUserGroupRelationsUserGroups
+   *        summary: /_api/v3/user-groups/{id}/user-group-relations
    *        description: Get the user group relations for the userGroup
    *        parameters:
    *          - name: id
@@ -529,9 +547,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /user-groups/{id}/pages:
+   *    /_api/v3/user-groups/{id}/pages:
    *      get:
-   *        tags: [UserGroup]
+   *        tags: [UserGroup, apiv3]
+   *        operationId: getPagesUserGroups
+   *        summary: /_api/v3/user-groups/{id}/pages
    *        description: Get closed pages for the userGroup
    *        parameters:
    *          - name: id

+ 71 - 10
src/server/routes/apiv3/users.js

@@ -21,6 +21,49 @@ const validator = {};
  *    name: Users
  */
 
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *      User:
+ *        description: User
+ *        type: object
+ *        properties:
+ *          _id:
+ *            type: string
+ *            description: user ID
+ *            example: 5ae5fccfc5577b0004dbd8ab
+ *          lang:
+ *            type: string
+ *            description: language
+ *            example: 'en-US'
+ *          status:
+ *            type: integer
+ *            description: status
+ *            example: 0
+ *          admin:
+ *            type: boolean
+ *            description: whether the admin
+ *            example: false
+ *          email:
+ *            type: string
+ *            description: E-Mail address
+ *            example: alice@aaa.aaa
+ *          username:
+ *            type: string
+ *            description: username
+ *            example: alice
+ *          name:
+ *            type: string
+ *            description: full name
+ *            example: Alice
+ *          createdAt:
+ *            type: string
+ *            description: date created at
+ *            example: 2010-01-01T00:00:00.000Z
+ */
+
 module.exports = (crowi) => {
   const loginRequiredStrictly = require('../../middleware/login-required')(crowi);
   const adminRequired = require('../../middleware/admin-required')(crowi);
@@ -40,7 +83,9 @@ module.exports = (crowi) => {
    *  paths:
    *    /_api/v3/users:
    *      get:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: listUsers
+   *        summary: /_api/v3/users
    *        description: Get users
    *        responses:
    *          200:
@@ -90,7 +135,9 @@ module.exports = (crowi) => {
    *  paths:
    *    /_api/v3/users/invite:
    *      post:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: inviteUser
+   *        summary: /_api/v3/users/invite
    *        description: Create new users and send Emails
    *        parameters:
    *          - name: shapedEmailList
@@ -133,7 +180,9 @@ module.exports = (crowi) => {
    *  paths:
    *    /_api/v3/users/{id}/giveAdmin:
    *      put:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: giveAdminUser
+   *        summary: /_api/v3/users/{id}/giveAdmin
    *        description: Give user admin
    *        parameters:
    *          - name: id
@@ -172,7 +221,9 @@ module.exports = (crowi) => {
    *  paths:
    *    /_api/v3/users/{id}/removeAdmin:
    *      put:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: removeAdminUser
+   *        summary: /_api/v3/users/{id}/removeAdmin
    *        description: Remove user admin
    *        parameters:
    *          - name: id
@@ -211,7 +262,9 @@ module.exports = (crowi) => {
    *  paths:
    *    /_api/v3/users/{id}/activate:
    *      put:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: activateUser
+   *        summary: /_api/v3/users/{id}/activate
    *        description: Activate user
    *        parameters:
    *          - name: id
@@ -258,7 +311,9 @@ module.exports = (crowi) => {
    *  paths:
    *    /_api/v3/users/{id}/deactivate:
    *      put:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: deactivateUser
+   *        summary: /_api/v3/users/{id}/deactivate
    *        description: Deactivate user
    *        parameters:
    *          - name: id
@@ -297,7 +352,9 @@ module.exports = (crowi) => {
    *  paths:
    *    /_api/v3/users/{id}/remove:
    *      delete:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: removeUser
+   *        summary: /_api/v3/users/{id}/remove
    *        description: Delete user
    *        parameters:
    *          - name: id
@@ -338,9 +395,11 @@ module.exports = (crowi) => {
    * @swagger
    *
    *  paths:
-   *    /_api/v3/users:
+   *    /_api/v3/users/external-accounts:
    *      get:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: listExternalAccountsUsers
+   *        summary: /_api/v3/users/external-accounts
    *        description: Get external-account
    *        responses:
    *          200:
@@ -372,7 +431,9 @@ module.exports = (crowi) => {
    *  paths:
    *    /_api/v3/users/external-accounts/{id}/remove:
    *      delete:
-   *        tags: [Users]
+   *        tags: [Users, apiv3]
+   *        operationId: removeExternalAccountUser
+   *        summary: /_api/v3/users/external-accounts/{id}/remove
    *        description: Delete ExternalAccount
    *        parameters:
    *          - name: id

+ 192 - 0
src/server/routes/attachment.js

@@ -7,6 +7,65 @@ const fs = require('fs');
 
 const ApiResponse = require('../util/apiResponse');
 
+/**
+ * @swagger
+ *  tags:
+ *    name: Attachments
+ */
+
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *      Attachment:
+ *        description: Attachment
+ *        type: object
+ *        properties:
+ *          _id:
+ *            type: string
+ *            description: attachment ID
+ *            example: 5e0734e072560e001761fa67
+ *          __v:
+ *            type: number
+ *            description: attachment version
+ *            example: 0
+ *          fileFormat:
+ *            type: string
+ *            description: file format in MIME
+ *            example: text/plain
+ *          fileName:
+ *            type: string
+ *            description: file name
+ *            example: 601b7c59d43a042c0117e08dd37aad0aimage.txt
+ *          originalName:
+ *            type: string
+ *            description: original file name
+ *            example: file.txt
+ *          filePath:
+ *            type: string
+ *            description: file path
+ *            example: attachment/5e07345972560e001761fa63/6b0b3facf3628699263d760e18efd446.txt
+ *          creator:
+ *            $ref: '#/components/schemas/User'
+ *          page:
+ *            type: string
+ *            description: page ID attached at
+ *            example: 5e07345972560e001761fa63
+ *          createdAt:
+ *            type: string
+ *            description: date created at
+ *            example: 2010-01-01T00:00:00.000Z
+ *          fileSize:
+ *            type: number
+ *            description: file size
+ *            example: 3494332
+ *          url:
+ *            type: string
+ *            description: attachment URL
+ *            example: http://localhost/files/5e0734e072560e001761fa67
+ */
+
 module.exports = function(crowi, app) {
   const Attachment = crowi.model('Attachment');
   const User = crowi.model('User');
@@ -185,6 +244,40 @@ module.exports = function(crowi, app) {
     return responseForAttachment(req, res, attachment);
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/attachments.list:
+   *      get:
+   *        tags: [Attachments, apiv1]
+   *        operationId: listAttachments
+   *        summary: /_api/attachments.list
+   *        description: Get list of attachments in page
+   *        parameters:
+   *          - in: query
+   *            name: page_id
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/_id'
+   *            required: true
+   *        responses:
+   *          200:
+   *            description: Succeeded to get list of attachments.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    attachments:
+   *                      type: array
+   *                      items:
+   *                        $ref: '#/components/schemas/Attachment'
+   *                      description: attachment list
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /attachments.list Get attachments of the page
    * @apiName ListAttachments
@@ -219,6 +312,73 @@ module.exports = function(crowi, app) {
     return res.json(ApiResponse.success(await fileUploader.checkLimit(fileSize)));
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/attachments.add:
+   *      post:
+   *        tags: [Attachments, apiv1]
+   *        operationId: addAttachment
+   *        summary: /_api/attachments.add
+   *        description: Add attachment to the page
+   *        requestBody:
+   *          content:
+   *            "multipart/form-data":
+   *              schema:
+   *                properties:
+   *                  page_id:
+   *                    nullable: true
+   *                    type: string
+   *                  path:
+   *                    nullable: true
+   *                    type: string
+   *                  file:
+   *                    type: string
+   *                    format: binary
+   *                    description: attachment data
+   *              encoding:
+   *                path:
+   *                  contentType: application/x-www-form-urlencoded
+   *            "*\/*":
+   *              schema:
+   *                properties:
+   *                  page_id:
+   *                    nullable: true
+   *                    type: string
+   *                  path:
+   *                    nullable: true
+   *                    type: string
+   *                  file:
+   *                    type: string
+   *                    format: binary
+   *                    description: attachment data
+   *              encoding:
+   *                path:
+   *                  contentType: application/x-www-form-urlencoded
+   *        responses:
+   *          200:
+   *            description: Succeeded to add attachment.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    page:
+   *                      $ref: '#/components/schemas/Page'
+   *                    attachment:
+   *                      $ref: '#/components/schemas/Attachment'
+   *                    url:
+   *                      $ref: '#/components/schemas/Attachment/properties/url'
+   *                    pageCreated:
+   *                      type: boolean
+   *                      description: whether the page was created
+   *                      example: false
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /attachments.add Add attachment to the page
    * @apiName AddAttachments
@@ -320,6 +480,38 @@ module.exports = function(crowi, app) {
     return res.json(ApiResponse.success(result));
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/attachments.remove:
+   *      post:
+   *        tags: [Attachments, apiv1]
+   *        operationId: removeAttachment
+   *        summary: /_api/attachments.remove
+   *        description: Remove attachment
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  attachment_id:
+   *                    $ref: '#/components/schemas/Attachment/properties/_id'
+   *                required:
+   *                  - attachment_id
+   *        responses:
+   *          200:
+   *            description: Succeeded to remove attachment.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /attachments.remove Remove attachments
    * @apiName RemoveAttachments

+ 163 - 0
src/server/routes/bookmark.js

@@ -1,3 +1,36 @@
+/**
+ * @swagger
+ *  tags:
+ *    name: Bookmarks
+ */
+
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *      Bookmark:
+ *        description: Bookmark
+ *        type: object
+ *        properties:
+ *          _id:
+ *            type: string
+ *            description: page ID
+ *            example: 5e07345972560e001761fa63
+ *          __v:
+ *            type: number
+ *            description: DB record version
+ *            example: 0
+ *          createdAt:
+ *            type: string
+ *            description: date created at
+ *            example: 2010-01-01T00:00:00.000Z
+ *          page:
+ *            $ref: '#/components/schemas/Page/properties/_id'
+ *          user:
+ *            $ref: '#/components/schemas/User/properties/_id'
+ */
+
 module.exports = function(crowi, app) {
   const debug = require('debug')('growi:routes:bookmark');
   const Bookmark = crowi.model('Bookmark');
@@ -7,6 +40,37 @@ module.exports = function(crowi, app) {
   const actions = {};
   actions.api = {};
 
+  /**
+   * @swagger
+   *
+   *    /_api/bookmarks.get:
+   *      get:
+   *        tags: [Bookmarks, apiv1]
+   *        operationId: getBookmark
+   *        summary: /_api/bookmarks.get
+   *        description: Get bookmark of the page with the user
+   *        parameters:
+   *          - in: query
+   *            name: page_id
+   *            required: true
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/_id'
+   *        responses:
+   *          200:
+   *            description: Succeeded to get bookmark of the page with the user.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    bookmark:
+   *                      $ref: '#/components/schemas/Bookmark'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /bookmarks.get Get bookmark of the page with the user
    * @apiName GetBookmarks
@@ -30,8 +94,44 @@ module.exports = function(crowi, app) {
       });
   };
 
+
   /**
+   * @swagger
    *
+   *    /_api/bookmarks.list:
+   *      get:
+   *        tags: [Bookmarks, apiv1]
+   *        operationId: listBookmarks
+   *        summary: /_api/bookmarks.list
+   *        description: Get bookmark list of the page with the user
+   *        parameters:
+   *          - in: query
+   *            name: limit
+   *            schema:
+   *              $ref: '#/components/schemas/V1PaginateResult/properties/meta/properties/limit'
+   *          - in: query
+   *            name: offset
+   *            schema:
+   *              $ref: '#/components/schemas/V1PaginateResult/properties/meta/properties/offset'
+   *        responses:
+   *          200:
+   *            description: Succeeded to get bookmark of the page with the user.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    meta:
+   *                      $ref: '#/components/schemas/V1PaginateResult/properties/meta'
+   *                    data:
+   *                      type: array
+   *                      items:
+   *                        $ref: '#/components/schemas/V1PaginateResult/properties/meta'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
    */
   actions.api.list = function(req, res) {
     const paginateOptions = ApiPaginate.parseOptions(req.query);
@@ -46,6 +146,37 @@ module.exports = function(crowi, app) {
       });
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/bookmarks.add:
+   *      post:
+   *        tags: [Bookmarks, apiv1]
+   *        operationId: addBookmark
+   *        summary: /_api/bookmarks.add
+   *        description: Add bookmark of the page
+   *        parameters:
+   *          - in: query
+   *            name: page_id
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/_id'
+   *            required: true
+   *        responses:
+   *          200:
+   *            description: Succeeded to add bookmark of the page.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    bookmark:
+   *                      $ref: '#/components/schemas/Bookmark'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /bookmarks.add Add bookmark of the page
    * @apiName AddBookmark
@@ -70,6 +201,38 @@ module.exports = function(crowi, app) {
     return res.json(ApiResponse.success(result));
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/bookmarks.remove:
+   *      post:
+   *        tags: [Bookmarks, apiv1]
+   *        operationId: removeBookmark
+   *        summary: /_api/bookmarks.remove
+   *        description: Remove bookmark of the page
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  page_id:
+   *                    $ref: '#/components/schemas/Page/properties/_id'
+   *                required:
+   *                  - page_id
+   *        responses:
+   *          200:
+   *            description: Succeeded to remove bookmark of the page.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /bookmarks.remove Remove bookmark of the page
    * @apiName RemoveBookmark

+ 202 - 0
src/server/routes/comment.js

@@ -1,3 +1,46 @@
+/**
+ * @swagger
+ *  tags:
+ *    name: Comments
+ */
+
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *      Comment:
+ *        description: Comment
+ *        type: object
+ *        properties:
+ *          _id:
+ *            type: string
+ *            description: revision ID
+ *            example: 5e079a0a0afa6700170a75fb
+ *          __v:
+ *            type: number
+ *            description: DB record version
+ *            example: 0
+ *          page:
+ *            $ref: '#/components/schemas/Page/properties/_id'
+ *          creator:
+ *            $ref: '#/components/schemas/User/properties/_id'
+ *          revision:
+ *            $ref: '#/components/schemas/Revision/properties/_id'
+ *          comment:
+ *            type: string
+ *            description: comment
+ *            example: good
+ *          commentPosition:
+ *            type: number
+ *            description: comment position
+ *            example: 0
+ *          createdAt:
+ *            type: string
+ *            description: date created at
+ *            example: 2010-01-01T00:00:00.000Z
+ */
+
 module.exports = function(crowi, app) {
   const logger = require('@alias/logger')('growi:routes:comment');
   const Comment = crowi.model('Comment');
@@ -16,6 +59,42 @@ module.exports = function(crowi, app) {
   actions.api = api;
   api.validators = {};
 
+  /**
+   * @swagger
+   *
+   *    /_api/comments.get:
+   *      get:
+   *        tags: [Comments, apiv1]
+   *        operationId: getComments
+   *        summary: /_api/comments.get
+   *        description: Get comments of the page of the revision
+   *        parameters:
+   *          - in: query
+   *            name: page_id
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/_id'
+   *          - in: query
+   *            name: revision_id
+   *            schema:
+   *              $ref: '#/components/schemas/Revision/properties/_id'
+   *        responses:
+   *          200:
+   *            description: Succeeded to get comments of the page of the revision.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    comments:
+   *                      type: array
+   *                      items:
+   *                        $ref: '#/components/schemas/Comment'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /comments.get Get comments of the page of the revision
    * @apiName GetComments
@@ -74,6 +153,49 @@ module.exports = function(crowi, app) {
     return validator;
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/comments.add:
+   *      post:
+   *        tags: [Comments, apiv1]
+   *        operationId: addComment
+   *        summary: /_api/comments.add
+   *        description: Post comment for the page
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  commentForm:
+   *                    type: object
+   *                    properties:
+   *                      page_id:
+   *                        $ref: '#/components/schemas/Page/properties/_id'
+   *                      revision_id:
+   *                        $ref: '#/components/schemas/Revision/properties/_id'
+   *                      comment:
+   *                        $ref: '#/components/schemas/Comment/properties/comment'
+   *                      comment_position:
+   *                        $ref: '#/components/schemas/Comment/properties/commentPosition'
+   *                required:
+   *                  - commentForm
+   *        responses:
+   *          200:
+   *            description: Succeeded to post comment for the page.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    comment:
+   *                      $ref: '#/components/schemas/Comment'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /comments.add Post comment for the page
    * @apiName PostComment
@@ -160,6 +282,52 @@ module.exports = function(crowi, app) {
     }
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/comments.update:
+   *      post:
+   *        tags: [Comments, apiv1]
+   *        operationId: updateComment
+   *        summary: /_api/comments.update
+   *        description: Update comment dody
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  form:
+   *                    type: object
+   *                    properties:
+   *                      commentForm:
+   *                        type: object
+   *                        properties:
+   *                          page_id:
+   *                            $ref: '#/components/schemas/Page/properties/_id'
+   *                          revision_id:
+   *                            $ref: '#/components/schemas/Revision/properties/_id'
+   *                          comment:
+   *                            $ref: '#/components/schemas/Comment/properties/comment'
+   *                          comment_position:
+   *                            $ref: '#/components/schemas/Comment/properties/commentPosition'
+   *                required:
+   *                  - form
+   *        responses:
+   *          200:
+   *            description: Succeeded to update comment dody.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    comment:
+   *                      $ref: '#/components/schemas/Comment'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /comments.update Update comment dody
    * @apiName UpdateComment
@@ -206,6 +374,40 @@ module.exports = function(crowi, app) {
     // process notification if needed
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/comments.remove:
+   *      post:
+   *        tags: [Comments, apiv1]
+   *        operationId: removeComment
+   *        summary: /_api/comments.remove
+   *        description: Remove specified comment
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  comment_id:
+   *                    $ref: '#/components/schemas/Comment/properties/_id'
+   *                required:
+   *                  - comment_id
+   *        responses:
+   *          200:
+   *            description: Succeeded to remove specified comment.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    comment:
+   *                      $ref: '#/components/schemas/Comment'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /comments.remove Remove specified comment
    * @apiName RemoveComment

+ 466 - 0
src/server/routes/page.js

@@ -1,3 +1,133 @@
+/**
+ * @swagger
+ *  tags:
+ *    name: Pages
+ */
+
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *      Page:
+ *        description: Page
+ *        type: object
+ *        properties:
+ *          _id:
+ *            type: string
+ *            description: page ID
+ *            example: 5e07345972560e001761fa63
+ *          __v:
+ *            type: number
+ *            description: DB record version
+ *            example: 0
+ *          commentCount:
+ *            type: number
+ *            description: count of comments
+ *            example: 3
+ *          createdAt:
+ *            type: string
+ *            description: date created at
+ *            example: 2010-01-01T00:00:00.000Z
+ *          creator:
+ *            $ref: '#/components/schemas/User'
+ *          extended:
+ *            type: object
+ *            description: extend data
+ *            example: {}
+ *          grant:
+ *            type: number
+ *            description: grant
+ *            example: 1
+ *          grantedUsers:
+ *            type: array
+ *            description: granted users
+ *            items:
+ *              type: string
+ *              description: user ID
+ *            example: ["5ae5fccfc5577b0004dbd8ab"]
+ *          lastUpdateUser:
+ *            $ref: '#/components/schemas/User'
+ *          liker:
+ *            type: array
+ *            description: granted users
+ *            items:
+ *              type: string
+ *              description: user ID
+ *            example: []
+ *          path:
+ *            type: string
+ *            description: page path
+ *            example: /
+ *          redirectTo:
+ *            type: string
+ *            description: redirect path
+ *            example: ""
+ *          revision:
+ *            $ref: '#/components/schemas/Revision'
+ *          seenUsers:
+ *            type: array
+ *            description: granted users
+ *            items:
+ *              type: string
+ *              description: user ID
+ *            example: ["5ae5fccfc5577b0004dbd8ab"]
+ *          status:
+ *            type: string
+ *            description: status
+ *            enum:
+ *              - 'wip'
+ *              - 'published'
+ *              - 'deleted'
+ *              - 'deprecated'
+ *            example: published
+ *          updatedAt:
+ *            type: string
+ *            description: date updated at
+ *            example: 2010-01-01T00:00:00.000Z
+ *
+ *      UpdatePost:
+ *        description: UpdatePost
+ *        type: object
+ *        properties:
+ *          _id:
+ *            type: string
+ *            description: update post ID
+ *            example: 5e0734e472560e001761fa68
+ *          __v:
+ *            type: number
+ *            description: DB record version
+ *            example: 0
+ *          pathPattern:
+ *            type: string
+ *            description: path pattern
+ *            example: /test
+ *          patternPrefix:
+ *            type: string
+ *            description: patternPrefix prefix
+ *            example: /
+ *          patternPrefix2:
+ *            type: string
+ *            description: path
+ *            example: test
+ *          channel:
+ *            type: string
+ *            description: channel
+ *            example: general
+ *          provider:
+ *            type: string
+ *            description: provider
+ *            enum:
+ *              - slack
+ *            example: slack
+ *          creator:
+ *            $ref: '#/components/schemas/User'
+ *          createdAt:
+ *            type: string
+ *            description: date created at
+ *            example: 2010-01-01T00:00:00.000Z
+ */
+
 /* eslint-disable no-use-before-define */
 module.exports = function(crowi, app) {
   const debug = require('debug')('growi:routes:page');
@@ -512,6 +642,47 @@ module.exports = function(crowi, app) {
   const api = {};
   actions.api = api;
 
+  /**
+   * @swagger
+   *
+   *    /_api/pages.list:
+   *      get:
+   *        tags: [Pages, apiv1]
+   *        operationId: listPages
+   *        summary: /_api/pages.list
+   *        description: Get list of pages
+   *        parameters:
+   *          - in: query
+   *            name: path
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/path'
+   *          - in: query
+   *            name: user
+   *            schema:
+   *              $ref: '#/components/schemas/User/properties/username'
+   *          - in: query
+   *            name: offset
+   *            schema:
+   *              $ref: '#/components/schemas/V1PaginateResult/properties/meta/properties/offset'
+   *        responses:
+   *          200:
+   *            description: Succeeded to get list of pages.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    pages:
+   *                      type: array
+   *                      items:
+   *                        $ref: '#/components/schemas/Page'
+   *                      description: page list
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /pages.list List pages by user
    * @apiName ListPage
@@ -561,6 +732,45 @@ module.exports = function(crowi, app) {
     }
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/pages.create:
+   *      post:
+   *        tags: [Pages, apiv1]
+   *        operationId: createPage
+   *        summary: /_api/pages.create
+   *        description: Create page
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  body:
+   *                    $ref: '#/components/schemas/Revision/properties/body'
+   *                  path:
+   *                    $ref: '#/components/schemas/Page/properties/path'
+   *                  grant:
+   *                    $ref: '#/components/schemas/Page/properties/grant'
+   *                required:
+   *                  - body
+   *                  - path
+   *        responses:
+   *          200:
+   *            description: Succeeded to create page.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    page:
+   *                      $ref: '#/components/schemas/Page'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /pages.create Create new page
    * @apiName CreatePage
@@ -631,6 +841,47 @@ module.exports = function(crowi, app) {
     }
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/pages.update:
+   *      post:
+   *        tags: [Pages, apiv1]
+   *        operationId: updatePage
+   *        summary: /_api/pages.update
+   *        description: Update page
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  body:
+   *                    $ref: '#/components/schemas/Revision/properties/body'
+   *                  page_id:
+   *                    $ref: '#/components/schemas/Page/properties/_id'
+   *                  revision_id:
+   *                    $ref: '#/components/schemas/Revision/properties/_id'
+   *                  grant:
+   *                    $ref: '#/components/schemas/Page/properties/grant'
+   *                required:
+   *                  - body
+   *                  - page_id
+   *        responses:
+   *          200:
+   *            description: Succeeded to update page.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    page:
+   *                      $ref: '#/components/schemas/Page'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /pages.update Update page
    * @apiName UpdatePage
@@ -718,6 +969,44 @@ module.exports = function(crowi, app) {
     }
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/pages.get:
+   *      get:
+   *        tags: [Pages, apiv1]
+   *        operationId: getPage
+   *        summary: /_api/pages.get
+   *        description: Get page data
+   *        parameters:
+   *          - in: query
+   *            name: page_id
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/_id'
+   *          - in: query
+   *            name: path
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/path'
+   *          - in: query
+   *            name: revision_id
+   *            schema:
+   *              $ref: '#/components/schemas/Revision/properties/_id'
+   *        responses:
+   *          200:
+   *            description: Succeeded to get page data.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    page:
+   *                      $ref: '#/components/schemas/Page'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /pages.get Get page data
    * @apiName GetPage
@@ -804,6 +1093,40 @@ module.exports = function(crowi, app) {
     return res.json(ApiResponse.success(result));
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/pages.seen:
+   *      post:
+   *        tags: [Pages, apiv1]
+   *        operationId: seenPage
+   *        summary: /_api/pages.seen
+   *        description: Mark as seen user
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  page_id:
+   *                    $ref: '#/components/schemas/Page/properties/_id'
+   *                required:
+   *                  - page_id
+   *        responses:
+   *          200:
+   *            description: Succeeded to be page seen.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    seenUser:
+   *                      $ref: '#/components/schemas/Page/properties/seenUsers'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /pages.seen Mark as seen user
    * @apiName SeenPage
@@ -839,6 +1162,40 @@ module.exports = function(crowi, app) {
     return res.json(ApiResponse.success(result));
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/likes.add:
+   *      post:
+   *        tags: [Pages, apiv1]
+   *        operationId: addLike
+   *        summary: /_api/likes.add
+   *        description: Like page
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  page_id:
+   *                    $ref: '#/components/schemas/Page/properties/_id'
+   *                required:
+   *                  - page_id
+   *        responses:
+   *          200:
+   *            description: Succeeded to be page liked.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    page:
+   *                      $ref: '#/components/schemas/Page'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /likes.add Like page
    * @apiName LikePage
@@ -881,6 +1238,40 @@ module.exports = function(crowi, app) {
     }
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/likes.remove:
+   *      post:
+   *        tags: [Pages, apiv1]
+   *        operationId: removeLike
+   *        summary: /_api/likes.remove
+   *        description: Unlike page
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  page_id:
+   *                    $ref: '#/components/schemas/Page/properties/_id'
+   *                required:
+   *                  - page_id
+   *        responses:
+   *          200:
+   *            description: Succeeded to not be page liked.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    page:
+   *                      $ref: '#/components/schemas/Page'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /likes.remove Unlike page
    * @apiName UnlikePage
@@ -915,6 +1306,36 @@ module.exports = function(crowi, app) {
     return res.json(ApiResponse.success(result));
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/pages.updatePost:
+   *      get:
+   *        tags: [Pages, apiv1]
+   *        operationId: getUpdatePostPage
+   *        summary: /_api/pages.updatePost
+   *        description: Get UpdatePost setting list
+   *        parameters:
+   *          - in: query
+   *            name: path
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/path'
+   *        responses:
+   *          200:
+   *            description: Succeeded to get UpdatePost setting list.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    updatePost:
+   *                      $ref: '#/components/schemas/UpdatePost'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /pages.updatePost
    * @apiName Get UpdatePost setting list
@@ -1053,6 +1474,51 @@ module.exports = function(crowi, app) {
     return res.json(ApiResponse.success(result));
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/pages.rename:
+   *      post:
+   *        tags: [Pages, apiv1]
+   *        operationId: renamePage
+   *        summary: /_api/pages.rename
+   *        description: Rename page
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  page_id:
+   *                    $ref: '#/components/schemas/Page/properties/_id'
+   *                  path:
+   *                    $ref: '#/components/schemas/Page/properties/path'
+   *                  revision_id:
+   *                    $ref: '#/components/schemas/Revision/properties/_id'
+   *                  new_path:
+   *                    type: string
+   *                    description: new path
+   *                    example: /user/alice/new_test
+   *                  create_redirect:
+   *                    type: boolean
+   *                    description: whether redirect page
+   *                required:
+   *                  - page_id
+   *        responses:
+   *          200:
+   *            description: Succeeded to rename page.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    page:
+   *                      $ref: '#/components/schemas/Page'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {post} /pages.rename Rename page
    * @apiName RenamePage

+ 153 - 0
src/server/routes/revision.js

@@ -1,3 +1,49 @@
+/**
+ * @swagger
+ *  tags:
+ *    name: Revisions
+ */
+
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *      Revision:
+ *        description: Revision
+ *        type: object
+ *        properties:
+ *          _id:
+ *            type: string
+ *            description: revision ID
+ *            example: 5e0734e472560e001761fa68
+ *          __v:
+ *            type: number
+ *            description: DB record version
+ *            example: 0
+ *          author:
+ *            $ref: '#/components/schemas/User/properties/_id'
+ *          body:
+ *            type: string
+ *            description: content body
+ *            example: |
+ *              # test
+ *
+ *              test
+ *          format:
+ *            type: string
+ *            description: format
+ *            example: markdown
+ *          path:
+ *            type: string
+ *            description: path
+ *            example: /user/alice/test
+ *          createdAt:
+ *            type: string
+ *            description: date created at
+ *            example: 2010-01-01T00:00:00.000Z
+ */
+
 module.exports = function(crowi, app) {
   const debug = require('debug')('growi:routes:revision');
   const logger = require('@alias/logger')('growi:routes:revision');
@@ -9,6 +55,42 @@ module.exports = function(crowi, app) {
   const actions = {};
   actions.api = {};
 
+  /**
+   * @swagger
+   *
+   *    /_api/revisions.get:
+   *      get:
+   *        tags: [Revisions, apiv1]
+   *        operationId: /_api/revisions.get
+   *        summary: /_api/revisions.get
+   *        description: Get revision
+   *        parameters:
+   *          - in: query
+   *            name: page_id
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/_id'
+   *            required: true
+   *          - in: query
+   *            name: revision_id
+   *            schema:
+   *              $ref: '#/components/schemas/Revision/properties/_id'
+   *            required: true
+   *        responses:
+   *          200:
+   *            description: Succeeded to get revision.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    revision:
+   *                      $ref: '#/components/schemas/Revision'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /revisions.get Get revision
    * @apiName GetRevision
@@ -41,6 +123,39 @@ module.exports = function(crowi, app) {
     }
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/revisions.ids:
+   *      get:
+   *        tags: [Revisions, apiv1]
+   *        operationId: /_api/revisions.ids
+   *        summary: /_api/revisions.ids
+   *        description: Get revision id list of the page
+   *        parameters:
+   *          - in: query
+   *            name: page_id
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/_id'
+   *            required: true
+   *        responses:
+   *          200:
+   *            description: Succeeded to get revision id list of the page.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    revisions:
+   *                      type: array
+   *                      items:
+   *                        $ref: '#/components/schemas/Revision'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /revisions.ids Get revision id list of the page
    * @apiName ids
@@ -69,6 +184,44 @@ module.exports = function(crowi, app) {
     }
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/revisions.list:
+   *      get:
+   *        tags: [Revisions, apiv1]
+   *        operationId: /_api/revisions.list
+   *        summary: /_api/revisions.list
+   *        description: Get revisions
+   *        parameters:
+   *          - in: query
+   *            name: page_id
+   *            schema:
+   *              $ref: '#/components/schemas/Page/properties/_id'
+   *          - in: query
+   *            name: revision_ids
+   *            schema:
+   *              type: string
+   *              description: revision ids
+   *              example: 5e0734e472560e001761fa68,5e079a0a0afa6700170a75fb
+   *        responses:
+   *          200:
+   *            description: Succeeded to get revisions.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    revisions:
+   *                      type: array
+   *                      items:
+   *                        $ref: '#/components/schemas/Revision'
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /revisions.list Get revisions
    * @apiName ListRevision

+ 35 - 0
src/server/routes/user.js

@@ -36,6 +36,41 @@ module.exports = function(crowi, app) {
       });
   };
 
+  /**
+   * @swagger
+   *
+   *    /_api/users.list:
+   *      get:
+   *        tags: [Users, apiv1]
+   *        operationId: listUsersV1
+   *        summary: /_api/users.list
+   *        description: Get list of users
+   *        parameters:
+   *          - in: query
+   *            name: user_ids
+   *            schema:
+   *              type: string
+   *              description: user IDs
+   *              example: 5e06fcc7516d64004dbf4da6,5e098d53baa2ac004e7d24ad
+   *        responses:
+   *          200:
+   *            description: Succeeded to get list of users.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    ok:
+   *                      $ref: '#/components/schemas/V1Response/properties/ok'
+   *                    users:
+   *                      type: array
+   *                      items:
+   *                        $ref: '#/components/schemas/User'
+   *                      description: user list
+   *          403:
+   *            $ref: '#/components/responses/403'
+   *          500:
+   *            $ref: '#/components/responses/500'
+   */
   /**
    * @api {get} /users.list Get user list
    * @apiName GetUserList