World Conquest Chronicles

World Conquest Chronicles

VK Group Stats, v1.1.0, alpha 2

Group list

Service for a collecting of a VK groups stats.

Second alpha of a release. Add a name and a photo to a group, support an addition of a group via its URL.

Change Log

  • Closed issues:
    • Display new group fields in the client if they are available #20
    • Support a group update on a counter addition in the client #19
    • Support a counter addition on a group addition in the client #18
    • Support a group URL as a group screen name #17
    • Save new group fields and add a counter on a group addition #16
    • Update new group fields on a counter addition #15
    • Extend the group model: add a name and a photo #14

Features

  • back-end:
    • authentication:
      • an authentication via VK;
      • support of a skipping of an authentication;
    • users:
      • data:
        • MongoDB ObjectId;
        • VK ID;
      • operations:
        • getting of a current user;
        • automatically addition on an authentication;
      • support of a fake user on a skipping of an authentication;
    • groups:
      • data:
        • MongoDB ObjectId;
        • user ObjectId;
        • VK photo;
        • VK name;
        • VK screen name;
      • operations (for a current user):
        • getting of all;
        • addition of one:
          • by VK screen name;
          • by VK URL;
        • deletion of one;
    • counters:
      • data:
        • MongoDB ObjectId;
        • group ObjectId;
        • addition timestamp;
        • group members counter;
      • operations (for a specified group):
        • getting of all in a descending order;
        • getting of all in a descending order beginning with a specified timestamp;
        • addition of one (automatically via VK API);
        • deletion of all;
    • automatically addition of counters via VK API for all added groups by schedule;
  • front-end:
    • design:
      • adaptive;
      • material:
        • dark;
        • light;
    • group list:
      • displays:
        • groups;
      • states:
        • fetching;
        • success;
        • failure;
      • for every group:
        • displays:
          • VK photo;
          • VK name;
          • VK screen name;
          • counters for a last day;
        • states:
          • fetching;
          • success;
          • failure;
        • for every counter:
          • displays:
            • timestamp;
            • number of subscribers;
            • delta compared to a previous;
    • dialogs:
      • add group dialog;
      • about app dialog;
    • group list refreshing;
    • authentication:
      • login;
      • logout.

API

API description in the Swagger format:

swagger: '2.0'
info:
  title: vk-group-stats
  version: 1.0.0
basePath: /api/v1
schemes:
- http
- https
consumes:
- application/x-www-form-urlencoded
- application/json
produces:
- application/json
paths:
  /groups:
    get:
      responses:
        200:
          description: OK
          schema:
            type: object
            properties:
              data:
                type: array
                items:
                  $ref: '#/definitions/group'
            required:
            - data
        401:
          description: Unauthorized
          schema:
            $ref: '#/definitions/error'
        500:
          description: Internal Server Error
          schema:
            $ref: '#/definitions/error'
    post:
      parameters:
      - $ref: '#/parameters/group_form'
      responses:
        200:
          description: OK
          schema:
            type: object
            properties:
              data:
                type: object
                properties:
                  group:
                    $ref: '#/definitions/group'
                  counter:
                    $ref: '#/definitions/counter'
                required:
                - group
                - counter
            required:
            - data
        400:
          description: Bad Request
          schema:
            $ref: '#/definitions/error'
        401:
          description: Unauthorized
          schema:
            $ref: '#/definitions/error'
        500:
          description: Internal Server Error
          schema:
            $ref: '#/definitions/error'
  /groups/{group_id}:
    parameters:
    - $ref: '#/parameters/group_id'
    delete:
      responses:
        200:
          description: OK
          schema:
            $ref: '#/definitions/ok'
        400:
          description: Bad Request
          schema:
            $ref: '#/definitions/error'
        401:
          description: Unauthorized
          schema:
            $ref: '#/definitions/error'
        500:
          description: Internal Server Error
          schema:
            $ref: '#/definitions/error'
  /groups/{group_id}/counters:
    parameters:
    - $ref: '#/parameters/group_id'
    get:
      parameters:
      - $ref: '#/parameters/start_timestamp'
      responses:
        200:
          description: OK
          schema:
            type: object
            properties:
              data:
                type: array
                items:
                  $ref: '#/definitions/counter'
            required:
            - data
        400:
          description: Bad Request
          schema:
            $ref: '#/definitions/error'
        401:
          description: Unauthorized
          schema:
            $ref: '#/definitions/error'
        500:
          description: Internal Server Error
          schema:
            $ref: '#/definitions/error'
    post:
      responses:
        200:
          description: OK
          schema:
            type: object
            properties:
              data:
                type: object
                properties:
                  group:
                    $ref: '#/definitions/group'
                  counter:
                    $ref: '#/definitions/counter'
                required:
                - group
                - counter
            required:
            - data
        400:
          description: Bad Request
          schema:
            $ref: '#/definitions/error'
        401:
          description: Unauthorized
          schema:
            $ref: '#/definitions/error'
        500:
          description: Internal Server Error
          schema:
            $ref: '#/definitions/error'
  /users/me:
    get:
      responses:
        200:
          description: OK
          schema:
            type: object
            properties:
              data:
                $ref: '#/definitions/user'
            required:
            - data
        500:
          description: Internal Server Error
          schema:
            $ref: '#/definitions/error'
parameters:
  group_id:
    name: group_id
    in: path
    required: true
    type: string
    format: mongodb-objectid
    pattern: ^[0-9A-Fa-f]+$
    minLength: 24
    maxLength: 24
  group_form:
    name: body
    in: body
    required: true
    schema:
      $ref: '#/definitions/group_form'
  start_timestamp:
    name: start_timestamp
    in: query
    type: string
    format: iso8601-timestamp
    pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$
definitions:
  group_form:
    type: object
    properties:
      screen_name:
        type: string
    required:
    - screen_name
  group:
    type: object
    properties:
      _id:
        $ref: '#/definitions/mongodb-objectid'
      user_id:
        $ref: '#/definitions/mongodb-objectid'
      photo:
        type: string
      name:
        type: string
      screen_name:
        type: string
    required:
    - _id
    - user_id
    - screen_name
  counter:
    type: object
    properties:
      _id:
        $ref: '#/definitions/mongodb-objectid'
      group_id:
        $ref: '#/definitions/mongodb-objectid'
      timestamp:
        type: string
        description: date and time in ISO 8601 format
        pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$
      value:
        type: integer
        minimum: 0
    required:
    - _id
    - group_id
    - timestamp
    - value
  user:
    type: object
    description: may be null
    properties:
      _id:
        $ref: '#/definitions/mongodb-objectid'
      vk_id:
        type: integer
        minimum: 0
    required:
    - _id
    - vk_id
  ok:
    type: object
    properties:
      data:
        type: boolean
        description: always true
    required:
    - data
  error:
    type: object
    properties:
      errors:
        type: array
        minItems: 1
        items:
          type: object
          properties:
            message:
              type: string
            field:
              type: string
          required:
          - message
    required:
    - errors
  mongodb-objectid:
    type: string
    pattern: ^[0-9A-Fa-f]+$
    minLength: 24
    maxLength: 24

Redux state

Redux state in the JSON Schema format:

{
  "type": "object",
  "properties": {
    "login": {
      "type": "object",
      "properties": {
        "state": {
          "$ref": "#/definitions/state"
        },
        "isLogged": {
          "type": "boolean"
        }
      },
      "required": [
        "state",
        "isLogged"
      ]
    },
    "appDialog": {
      "$ref": "#/definitions/dialog"
    },
    "groupDialog": {
      "$ref": "#/definitions/dialog"
    },
    "groups": {
      "type": "object",
      "properties": {
        "state": {
          "$ref": "#/definitions/state"
        },
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "state": {
                "$ref": "#/definitions/state"
              },
              "data": {
                "$ref": "#/definitions/group"
              },
              "counters": {
                "type": "object",
                "properties": {
                  "state": {
                    "$ref": "#/definitions/state"
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "$ref": "#/definitions/counter"
                    }
                  }
                },
                "required": [
                  "state",
                  "items"
                ]
              }
            },
            "required": [
              "state",
              "data",
              "counters"
            ]
          }
        }
      },
      "required": [
        "state",
        "items"
      ]
    }
  },
  "required": [
    "appDialog",
    "groupDialog",
    "groups"
  ],
  "definitions": {
    "dialog": {
      "type": "object",
      "properties": {
        "open": {
          "type": "boolean"
        }
      },
      "required": [
        "open"
      ]
    },
    "state": {
      "type": "string",
      "enum": [
        "fetching",
        "success",
        "failure"
      ],
      "default": "success"
    },
    "group": {
      "type": "object",
      "properties": {
        "_id": {
          "$ref": "#/definitions/mongodb-objectid"
        },
        "photo": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "screen_name": {
          "type": "string"
        }
      },
      "required": [
        "_id",
        "screen_name"
      ]
    },
    "counter": {
      "type": "object",
      "properties": {
        "_id": {
          "$ref": "#/definitions/mongodb-objectid"
        },
        "timestamp": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d{3}Z$"
        },
        "value": {
          "type": "integer",
          "minimum": 0
        },
        "delta": {
          "type": "integer"
        }
      },
      "required": [
        "_id",
        "timestamp",
        "value"
      ]
    },
    "mongodb-objectid": {
      "type": "string",
      "pattern": "^[0-9A-Fa-f]+$",
      "minLength": 24,
      "maxLength": 24
    }
  }
}

Repository

Link: https://github.com/thewizardplusplus/vk-group-stats/tree/v1.1.0-alpha.2.

Content: code.

License: MIT.

Screenshots

GET /groups

GET /groups

POST /groups

POST /groups

POST /groups/{group_id}/counters

POST /groups/{group_id}/counters

Add group dialog

Add group dialog