Compare commits

...

112 Commits

Author SHA1 Message Date
18b63bed21 dhs-testing stubs
All checks were successful
platform/multy-stub/pipeline/head This commit looks good
2024-12-14 10:33:28 +03:00
707c3be3ec Merge pull request 'feat: freetracker dashboard-performer stubs' (#46) from feat/freetracker into master
Reviewed-on: #46
2024-12-13 22:07:47 +03:00
3d52ef9d4c feat: freetracker dashboard-performer stubs
All checks were successful
platform/multy-stub/pipeline/head This commit looks good
2024-12-13 22:05:42 +03:00
42944af2d3 Merge pull request 'feat: add dry wash json' (#44) from feature/dry-wash-arm into master
Reviewed-on: #44
2024-12-08 11:52:50 +03:00
f0f6b78cd0 feat: add dry wash json 2024-12-08 11:50:39 +03:00
WlfromB
7c35f17008 fix require server.index.js 2024-12-07 09:55:00 +03:00
WlfromB
0208e29ae3 old edateam stubs 2024-12-07 09:49:53 +03:00
Primakov Alexandr Alexandrovich
4d5cd104ad Merge branch 'master' of ssh://85.143.175.152:222/bro-students/multy-stub 2024-12-01 21:55:32 +03:00
Primakov Alexandr Alexandrovich
6702473053 up mongo version 2024-12-01 21:47:55 +03:00
52083097a2 Merge pull request 'dogsitter-finder' (#43) from dogsitter-finder into master
Reviewed-on: #43
2024-11-30 16:06:15 +03:00
f7ac265e3b Replace users.json to users/ folder
All checks were successful
platform/multy-stub/pipeline/head This commit looks good
2024-11-30 16:04:59 +03:00
d46841c21f Update paths to json files 2024-11-30 14:54:07 +03:00
c95b015094 Merge pull request 'Update stubs DogsittersFinder' (#42) from dogsitter-finder into master
Reviewed-on: #42
2024-11-30 14:40:32 +03:00
940349af29 Update stubs DogsittersFinder 2024-11-30 12:16:27 +03:00
268824c108 Added multy stub for project kazan-explore 2024-11-26 19:49:01 +03:00
Primakov Alexandr Alexandrovich
550554a7a5 docker compose by tag 2024-11-25 22:40:47 +03:00
f5a8585845 Merge pull request 'Перемещена папка dogsitters-finder в routes. Добавлен путь в index.js' (#41) from dogsitters-finder-3 into master
Reviewed-on: #41
2024-11-25 21:22:24 +03:00
1e67f25066 Перемещена папка dogsitters-finder в routes. Добавлен путь в index.js 2024-11-25 20:42:38 +03:00
bbc315e270 Merge pull request 'get count by modelname' (#38) from feature/check-jenkins into master
Reviewed-on: #38
2024-10-16 11:57:57 +03:00
Primakov Alexandr Alexandrovich
fbb5d26c8f get count by modelname
All checks were successful
platform/multy-stub/pipeline/head This commit looks good
2024-10-16 11:55:42 +03:00
9d3edcf0dd Merge pull request 'check' (#37) from feature/check-jenkins into master
Reviewed-on: #37
2024-10-16 11:38:09 +03:00
Primakov Alexandr Alexandrovich
57eb548d6c verbose 2024-10-16 11:37:47 +03:00
Primakov Alexandr Alexandrovich
34d2889c1d fix 2024-10-16 11:24:59 +03:00
Primakov Alexandr Alexandrovich
afc782f50f check 2024-10-16 11:15:18 +03:00
Primakov Alexandr Alexandrovich
ff6e688206 fix 2024-10-16 11:12:16 +03:00
Primakov Alexandr Alexandrovich
4b0d9b4dbc mongoose + tests 2024-10-16 11:06:23 +03:00
2cfcd7347b Merge pull request 'fix plantsRouter' (#35) from nekitboy1998-patch-1 into master
Reviewed-on: #35
2024-10-15 14:43:38 +03:00
c1fe275532 fix plantsRouter 2024-10-15 14:43:06 +03:00
de46e9bf50 Merge pull request 'eecliptica' (#34) from eecliptica into master
Reviewed-on: #34
2024-10-15 14:11:57 +03:00
bogap
76558a7eef remove imports 2024-10-15 14:08:47 +03:00
bogap
4bf3d662ec a 2024-10-15 13:38:49 +03:00
bogap
637939e9af corrected 2024-10-15 13:36:13 +03:00
bogap
02891fe301 corrected 2024-10-12 23:03:52 +03:00
6015bce32f Merge pull request 'Cats backend routes' (#30) from cats into master
Reviewed-on: #30
2024-10-12 13:23:38 +03:00
528b37246b Const file for token 2024-10-12 13:23:16 +03:00
0c693e1bac Cats backend routes 2024-10-12 13:04:51 +03:00
c77aa76645 Merge pull request 'fixed a route for epja-2024-1' (#29) from enterfront into master
Reviewed-on: #29
2024-10-12 12:08:41 +03:00
Nikolai Petukhov
8a0ea25029 fixed a route for epja-2024-1 2024-10-12 12:06:52 +03:00
6fb3f3f921 Merge pull request 'enterfront' (#28) from enterfront into master
Reviewed-on: #28
2024-10-12 11:33:43 +03:00
Nikolai Petukhov
89c9d7f901 fixed error code 2024-10-12 11:21:47 +03:00
Nikolai Petukhov
b215e22f53 fixed const key, logs, deleted example 2024-10-12 11:17:21 +03:00
Nikolai Petukhov
f13ae33cb4 added a route for epja-2024-1 2024-10-10 13:06:58 +03:00
Nikolai Petukhov
18a1095cf0 enterfront 2024-10-10 12:02:52 +03:00
Primakov Alexandr Alexandrovich
3e27c0110c docker compose up script fix 2024-08-23 16:38:07 +03:00
c2ada9072f Merge pull request 'school-stage stubs' (#27) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/27
2024-06-03 23:26:56 +03:00
1bd1d2b279 school-stage stubs 2024-06-03 23:26:23 +03:00
7b1ce2ae83 Merge pull request 'school-stage stubs' (#26) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/26
2024-06-03 23:20:29 +03:00
de22881c28 school-stage stubs 2024-06-03 23:19:56 +03:00
20d370f120 Merge pull request 'school-stage stubs' (#25) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/25
2024-06-03 19:02:09 +03:00
85986d1844 school-stage stubs 2024-06-03 19:00:44 +03:00
dccf769477 Merge pull request 'school-stage stubs' (#24) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/24
2024-06-02 20:31:21 +03:00
d088ef7af8 school-stage stubs 2024-06-02 20:30:51 +03:00
fad8cdfe08 Merge pull request 'school-stage stubs' (#23) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/23
2024-06-02 20:26:27 +03:00
a55e6d2ab2 school-stage stubs 2024-06-02 20:25:51 +03:00
eb6da8aa1b Merge pull request 'school-stage stubs' (#22) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/22
2024-06-02 20:16:40 +03:00
19a55f57c0 school-stage stubs 2024-06-02 20:15:01 +03:00
b649e86a43 Merge pull request 'stubs-kazan-explore' (#21) from stubs-kazan-explore into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/21
2024-06-02 15:28:00 +03:00
guzelkha
c53f016eec Merge branch 'stubs-kazan-explore' of ssh://85.143.175.152:222/bro-students/multy-stub into stubs-kazan-explore 2024-06-02 15:23:45 +03:00
guzelkha
0a7cbc3434 stubs-kazan-explore change 2024-06-02 15:23:16 +03:00
Liliya Vasilova
279650db25 change stubs kazan-explore 2024-06-02 15:15:34 +03:00
2d45b4af72 Change trip schedule stub 2024-06-02 14:15:35 +03:00
bd4de9d7ba Merge pull request 'Add trip schedule stubs kazan-explore' (#20) from stubs-kazan-explore into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/20
2024-06-02 13:20:37 +03:00
10dbe5c147 Add trip schedule stubs kazan-explore 2024-06-02 13:18:35 +03:00
435f17ee22 Merge pull request 'Add stubs kazan-explore' (#19) from stubs-kazan-explore into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/19
2024-06-01 20:40:27 +03:00
677dc3dc29 Add stubs kazan-explore 2024-06-01 20:37:32 +03:00
88e3fe4172 Merge pull request 'Add stubs kazan-explore' (#18) from stubs-kazan-explore into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/18
2024-06-01 20:34:05 +03:00
21dcc8bbec Add stubs kazan-explore 2024-06-01 20:32:45 +03:00
4778dba7ed Merge pull request 'stubs-kazan-explore' (#17) from stubs-kazan-explore into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/17
2024-06-01 20:25:16 +03:00
07a02ade1f Add stubs kazan-explore 2024-06-01 20:22:43 +03:00
311846f92d Add stubs kazan-explore 2024-06-01 19:53:28 +03:00
ebd561098f Merge pull request 'small changes' (#16) from dhs-testing into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/16
2024-06-01 14:14:00 +03:00
b4372eb53a small changes 2024-06-01 14:12:54 +03:00
bdb6b4ca3e Merge pull request 'schoo;-stage stubs' (#15) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/15
2024-06-01 09:54:28 +03:00
426cb70eb6 schoo;-stage stubs 2024-06-01 09:53:26 +03:00
61441e21b8 Merge pull request 'school-stage stubs' (#14) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/14
2024-06-01 09:51:42 +03:00
a6f61ba033 school-stage stubs 2024-06-01 09:51:14 +03:00
8588a7fa38 Merge pull request 'school-stage stubs' (#13) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/13
2024-06-01 00:40:16 +03:00
c35185ea32 school-stage stubs 2024-06-01 00:39:43 +03:00
78a332732d Merge pull request 'api' (#12) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/12
2024-06-01 00:01:29 +03:00
5f54355b97 api 2024-06-01 00:00:00 +03:00
4efbb56905 Merge pull request 'school-stage stubs' (#10) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/10
2024-05-31 23:56:37 +03:00
50c6286190 Merge pull request 'edit tests data' (#11) from dhs-testing into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/11
2024-05-31 23:32:50 +03:00
de29da93ba edit tests data 2024-05-31 23:31:21 +03:00
7cdd7e790f school-stage stubs 2024-05-31 22:04:23 +03:00
569b1b0d9e Merge pull request 'school-stage stubs' (#9) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/9
2024-05-31 18:03:52 +03:00
272961c583 school-stage stubs 2024-05-31 18:01:50 +03:00
63284d6c08 Merge pull request 'school-stage-branch' (#8) from school-stage-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/8
2024-05-31 16:49:59 +03:00
cb56e2dd2c school-stage stubs 2024-05-31 16:38:40 +03:00
325e2f125b school-stage stubs 2024-05-31 16:28:05 +03:00
786085d4d0 Merge pull request 'dhs-testing stubs' (#7) from dhs-testing into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/7
2024-05-30 18:51:51 +03:00
c95a00fb19 fixed json 2024-05-30 18:29:26 +03:00
95373069da dhs-testing stubs 2024-05-30 17:39:33 +03:00
b8275a4c8f Merge pull request 'add-dogsitters-finder' (#6) from add-dogsitters-finder into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/6
Reviewed-by: primakov <primakovpro@gmail.com>
2024-05-27 18:12:19 +03:00
fb868bfefc Change path to json 2024-05-26 16:29:12 +03:00
086c94c58a Update json/users.json 2024-05-26 16:28:54 +03:00
812a95dd85 Merge pull request 'my-project stubs' (#4) from my into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/4
Reviewed-by: primakov <primakovpro@gmail.com>
2024-05-25 12:50:19 +03:00
85ee64e92b Merge pull request 'back add' (#5) from edateam_branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/5
Reviewed-by: primakov <primakovpro@gmail.com>
2024-05-25 12:50:05 +03:00
nothingnowhere1
eb87f400ee edit json files 2024-05-25 12:44:44 +03:00
92cabfa048 Add dogsitters-finder to server/index.json and server/routers 2024-05-25 11:12:21 +03:00
NewPerson
b2a853e183 back add 2024-05-25 00:10:46 +03:00
nothingnowhere1
0a6d50cb60 stubs 2024-05-24 05:04:31 +03:00
7809806b83 Merge pull request 'webstar-project stubs api' (#3) from webstar-branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/3
Reviewed-by: primakov <primakovpro@gmail.com>
2024-05-22 22:47:01 +03:00
Deolys
1aa0c36c84 post login fixed 2024-05-22 22:42:58 +03:00
Deolys
7c3132c54b webstar-project stubs api 2024-05-22 15:11:46 +03:00
8fc85a7de8 Merge pull request 'fix problems with edateam stubs index.js' (#2) from edateam_branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/2
Reviewed-by: primakov <primakovpro@gmail.com>
2024-05-19 21:14:14 +03:00
NewPerson
cb8b2cc5aa fix problems with edateam stubs index.js 2024-05-19 21:07:33 +03:00
6651215eeb a bit refresh deployment 2024-05-19 20:50:15 +03:00
80f8cef142 Merge pull request 'edateam_branch' (#1) from edateam_branch into master
Reviewed-on: https://git.inno-js.ru/bro-students/multy-stub/pulls/1
Reviewed-by: primakov <primakovpro@gmail.com>
2024-05-19 12:48:51 +03:00
WlfromB
5a57291523 index.js + edateam app use 2024-05-19 03:04:19 +03:00
WlfromB
39ab269f07 edateam stubs add 2024-05-19 03:01:32 +03:00
7cb23080bf search examples 2024-05-18 15:31:34 +03:00
d74e4a8624 r-and-m jsons 2024-05-18 13:40:25 +03:00
1320 changed files with 9501 additions and 1750 deletions

View File

@@ -1,45 +0,0 @@
module.exports = {
env: {
browser: true,
commonjs: true,
es2021: true,
},
extends: [
'airbnb-base',
],
parserOptions: {
ecmaVersion: 12,
},
rules: {
indent: ['error', 4],
semi: ['warn', 'never'],
'object-curly-newline': ['warn', {
ObjectExpression: 'always',
ObjectPattern: {
multiline: true,
},
ImportDeclaration: 'never',
ExportDeclaration: {
multiline: true, minProperties: 3,
},
}],
'consistent-return': [0],
'prefer-const': [0],
'no-unused-vars': [0],
'no-console': [0],
'global-require': [0],
'no-plusplus': [0],
'no-underscore-dangle': [0],
'import/no-dynamic-require': [0],
'no-shadow': ['warn'],
'no-restricted-syntax': ['warn'],
'max-len': ['warn'],
'linebreak-style': [0],
'prefer-destructuring': [0],
'imoprt-order': [0],
'no-param-reassign': [1],
'no-await-in-loop': [1],
'no-return-assign': [1],
'spaced-comment': [1],
},
}

3
.gitignore vendored
View File

@@ -1,3 +1,4 @@
node_modules/
.env
.idea
.idea
coverage/

1
.npmrc
View File

@@ -1 +0,0 @@
package-lock=true

View File

@@ -1,5 +1,5 @@
module.exports = {
port: 8044,
port: process.env.PORT ?? 8044,
mongoAddr: process.env.MONGO_ADDR || 'localhost',
mongoPort: 27017,
}

View File

@@ -1,14 +1,16 @@
FROM 'node:18'
FROM node:20
RUN mkdir -p /usr/src/app/server/
WORKDIR /usr/src/app/
COPY ./server /usr/src/app/server
COPY ./package.json /usr/src/app/package.json
COPY ./package-lock.json /usr/src/app/package-lock.json
COPY ./.serverrc.js /usr/src/app/.serverrc.js
# COPY ./.env /usr/src/app/.env
RUN npm i --only=prod
# RUN npm i --omit=dev
RUN npm ci
EXPOSE 8044
CMD ["npm", "run", "up:prod"]

16
Jenkinsfile vendored
View File

@@ -1,7 +1,7 @@
pipeline {
agent {
docker {
image 'node:18'
image 'node:20'
}
}
@@ -10,7 +10,7 @@ pipeline {
steps {
sh 'node -v'
sh 'npm -v'
sh 'npm install'
sh 'npm ci'
}
}
@@ -22,16 +22,16 @@ pipeline {
stage('test') {
steps {
sh 'npm run test:start'
sh 'npm run test'
}
}
stage('clean-all') {
stage('archiving') {
steps {
sh 'rm -rf .[!.]*'
sh 'rm -rf ./*'
sh 'ls -a'
script {
archiveArtifacts artifacts: 'coverage/*/**'
}
}
}
}
}
}

View File

@@ -3,4 +3,4 @@
docker stop ms-mongo
docker volume remove ms_volume
docker volume create ms_volume
docker run --rm -v ms_volume:/data/db --name ms-mongo -p 27017:27017 -d mongo:4.4.13
docker run --rm -v ms_volume:/data/db --name ms-mongo -p 27017:27017 -d mongo:8.0.3

View File

@@ -1,18 +1,19 @@
version: "3"
volumes:
ms_volume:
ms_volume8:
services:
mongoDb:
image: mongo:4.4.13
image: mongo:8.0.3
volumes:
- ms_volume:/data/db
- ms_volume8:/data/db
restart: always
# ports:
# - 27017:27017
multy-stubs:
build: .
# build: .
image: bro.js/ms/bh:$TAG
restart: always
ports:
- 8044:8044

16
eslint.config.mjs Normal file
View File

@@ -0,0 +1,16 @@
import globals from "globals";
import pluginJs from "@eslint/js";
export default [
{ ignores: ['server/routers/old/*'] },
{ files: ["**/*.js"], languageOptions: { sourceType: "commonjs" } },
{ languageOptions: { globals: globals.node } },
pluginJs.configs.recommended,
{
rules: {
semi: ['warn', 'never'],
'no-unused-vars': [0],
}
}
];

201
jest.config.js Normal file
View File

@@ -0,0 +1,201 @@
/**
* For a detailed explanation regarding each configuration property, visit:
* https://jestjs.io/docs/configuration
*/
/** @type {import('jest').Config} */
const config = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "C:\\Users\\alex\\AppData\\Local\\Temp\\jest",
// Automatically clear mock calls, instances, contexts and results before every test
clearMocks: true,
// Indicates whether the coverage information should be collected while executing the test
collectCoverage: true,
// An array of glob patterns indicating a set of files for which coverage information should be collected
collectCoverageFrom: [
"<rootDir>/server/routers/**/*.js"
],
// The directory where Jest should output its coverage files
coverageDirectory: "coverage",
// An array of regexp pattern strings used to skip coverage collection
coveragePathIgnorePatterns: [
"\\\\node_modules\\\\",
"<rootDir>/server/routers/old"
],
// Indicates which provider should be used to instrument code for coverage
coverageProvider: "v8",
// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
// "json",
// "text",
// "lcov",
// "clover"
// ],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: undefined,
// A path to a custom dependency extractor
// dependencyExtractor: undefined,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// The default configuration for fake timers
// fakeTimers: {
// "enableGlobally": false
// },
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: undefined,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: undefined,
// A set of global variables that need to be available in all test environments
// globals: {},
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "mjs",
// "cjs",
// "jsx",
// "ts",
// "tsx",
// "json",
// "node"
// ],
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
// moduleNameMapper: {},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
// preset: undefined,
// Run tests from one or more projects
// projects: undefined,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state before every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: undefined,
// Automatically restore mock state and implementation before every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: undefined,
// A list of paths to directories that Jest should use to search for files in
// roots: [
// "<rootDir>"
// ],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],
// The test environment that will be used for testing
// testEnvironment: "jest-environment-node",
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
// testMatch: [
// "**/__tests__/**/*.[jt]s?(x)",
// "**/?(*.)+(spec|test).[tj]s?(x)"
// ],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "\\\\node_modules\\\\"
// ],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: undefined,
// This option allows use of a custom test runner
// testRunner: "jest-circus/runner",
// A map from regular expressions to paths to transformers
// transform: undefined,
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
// transformIgnorePatterns: [
// "\\\\node_modules\\\\",
// "\\.pnp\\.[^\\\\]+$"
// ],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
verbose: true,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
};
module.exports = config;

5441
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,16 +4,15 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "npx nodemon ./server",
"start": "cross-env PORT=8033 npx nodemon ./server",
"up:prod": "cross-env NODE_ENV=\"production\" node ./server",
"deploy:d:stop": "docker-compose down",
"deploy:d:build": "docker-compose build",
"deploy:d:up": "docker-compose up -d",
"deploy:d:stop": "docker compose down",
"deploy:d:build": "docker compose build",
"deploy:d:up": "docker compose up -d",
"redeploy": "npm run deploy:d:stop && npm run deploy:d:build && npm run deploy:d:up",
"eslint": "npx eslint ./server",
"eslint:fix": "npx eslint ./server --fix",
"test": "echo \"test complete\"",
"test:start": "start-server-and-test up:prod 8044 test"
"test": "jest"
},
"repository": {
"type": "git",
@@ -24,6 +23,7 @@
"license": "MIT",
"homepage": "https://bitbucket.org/online-mentor/multi-stub#readme",
"dependencies": {
"axios": "^1.7.7",
"bcrypt": "^5.1.0",
"body-parser": "^1.19.0",
"cookie-parser": "^1.4.5",
@@ -37,17 +37,19 @@
"jsdom": "^22.1.0",
"jsonwebtoken": "^8.5.1",
"mongodb": "^3.6.8",
"mysql": "^2.18.1",
"mongoose": "^8.7.1",
"pbkdf2-password": "^1.2.1",
"socket.io": "^4.7.1",
"start-server-and-test": "^1.13.1",
"uuid": "^9.0.0"
},
"devDependencies": {
"@eslint/js": "^9.12.0",
"@types/node": "18.17.1",
"eslint": "8.46.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-import": "2.28.0",
"nodemon": "3.0.1"
"eslint": "^9.12.0",
"globals": "^15.11.0",
"jest": "^29.7.0",
"mockingoose": "^2.16.2",
"nodemon": "3.0.1",
"supertest": "^7.0.0"
}
}
}

View File

@@ -0,0 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`todo list app get list 1`] = `
{
"body": [
{
"_id": "670f69b5796ce7a9069da2f7",
"created": "2024-10-16T07:22:29.042Z",
"id": "670f69b5796ce7a9069da2f7",
"items": [],
"title": "qqq",
},
],
"success": true,
}
`;

View File

@@ -0,0 +1,34 @@
const { describe, it, expect } = require('@jest/globals')
const request = require('supertest')
const express = require('express')
const mockingoose = require('mockingoose')
const { ListModel } = require('../data/model/todo/list')
const todo = require('../routers/todo/routes')
const app = express()
app.use(todo)
const listExample = {
"title": "qqq",
"items": [],
"_id": "670f69b5796ce7a9069da2f7",
"created": "2024-10-16T07:22:29.042Z",
"id": "670f69b5796ce7a9069da2f7"
}
describe('todo list app', () => {
it('get list', (done) => {
mockingoose(ListModel)
.toReturn([listExample], 'find')
.toReturn(listExample, 'create')
request(app)
.get('/list')
.expect(200)
.then((response) => {
expect(response.body).toMatchSnapshot()
done()
})
})
})

2
server/data/const.js Normal file
View File

@@ -0,0 +1,2 @@
exports.TODO_LIST_MODEL_NAME = 'TODO_LIST'
exports.TODO_ITEM_MODEL_NAME = 'TODO_ITEM'

View File

@@ -0,0 +1,23 @@
const { Schema, model } = require('mongoose')
const { TODO_ITEM_MODEL_NAME } = require('../../const')
const schema = new Schema({
title: String,
done: { type: Boolean, default: false },
closed: Date,
created: {
type: Date, default: () => new Date().toISOString(),
},
})
schema.set('toJSON', {
virtuals: true,
versionKey: false,
})
schema.virtual('id').get(function () {
return this._id.toHexString()
})
exports.ItemModel = model(TODO_ITEM_MODEL_NAME, schema)

View File

@@ -0,0 +1,27 @@
const { Schema, model } = require('mongoose')
const { TODO_LIST_MODEL_NAME, TODO_ITEM_MODEL_NAME } = require('../../const')
const schema = new Schema({
title: String,
created: {
type: Date, default: () => new Date().toISOString(),
},
items: [{ type: Schema.Types.ObjectId, ref: TODO_ITEM_MODEL_NAME }],
})
schema.set('toJSON', {
virtuals: true,
versionKey: false,
})
schema.virtual('id').get(function () {
return this._id.toHexString()
})
schema.method('addItem', async function (itemObjectId) {
this.items.push(itemObjectId)
await this.save()
})
exports.ListModel = model(TODO_LIST_MODEL_NAME, schema)

View File

@@ -7,6 +7,8 @@ const app = express()
const cors = require('cors')
require('dotenv').config()
exports.app = app
const config = require('../.serverrc')
const { setIo } = require('./io')
@@ -40,26 +42,14 @@ app.use(require('./root'))
/**
* Добавляйте сюда свои routers.
*/
app.use('/lobsters', require('./routers/lobsters'))
app.use('/example', require('./routers/example'))
// app.use('/coder', require('./routers/coder'))
//app.use('/stc-21-03', require('./routers/stc-21-03'))
//app.use('/stc-21', require('./routers/stc'))
//app.use('/stc-22-24', require('./routers/stc-22-24'))
// app.use('/bushou-api', require('./routers/bushou'))
// app.use('/uryndyklar-api', require('./routers/uryndyklar'))
// app.use('/neptunium', require('./routers/neptunium'))
// app.use('/music-learn', require('./routers/music-learn'))
// app.use('/publicium', require('./routers/publicium'))
// app.use('/task-boss', require('./routers/task-boss'))
// app.use('/car-wash', require('./routers/car-wash'))
app.use('/zoom-bar', require('./routers/zoom-bar'))
//app.use('/basket', require('./routers/basket'))
//app.use('/easy-project', require('./routers/easy-project'))
//app.use('/sugarbun', require('./routers/sugarbun'))
app.use('/epja-2023-2', require('./routers/epja-2023-2'))
require('./routers/hub-video')
app.use('/epja-2024-1', require('./routers/epja-2024-1'))
app.use('/todo', require('./routers/todo/routes'))
app.use('/dogsitters-finder', require('./routers/dogsitters-finder'))
app.use('/kazan-explore', require('./routers/kazan-explore'))
app.use('/edateam', require('./routers/edateam-legacy'))
app.use('/dry-wash', require('./routers/dry-wash'))
app.use('/freetracker', require('./routers/freetracker'))
app.use('/dhs-testing', require('./routers/dhs-testing'))
app.use(require('./error'))

View File

@@ -1,17 +1,32 @@
const router = require('express').Router()
const fs = require('fs')
const path = require('path')
const router = require('express').Router()
const mongoose = require('mongoose')
const pkg = require('../package.json')
require('./utils/mongoose')
const folderPath = path.resolve(__dirname, './routers')
const folders = fs.readdirSync(folderPath)
router.get('/', (req, res) => {
res.send(`
router.get('/', async (req, res) => {
res.send(`
<h1>multy stub is working v${pkg.version}</h1>
<ul>
${folders.map((f) => `<li>${f}</li>`).join('')}
</ul>
<h2>models</h2>
<ul>${
(await Promise.all(
(
await mongoose.modelNames()).map(async (name) => {
const count = await mongoose.model(name).countDocuments()
return `<li>${name} - ${count}</li>`
}
)
)).map(t => t).join(' ')
}</ul>
`)
})

View File

@@ -0,0 +1,35 @@
const { response } = require('express');
const router = require('express').Router();
router.get('/tests-data', (request, response) => {
response.send(require('./json/tests-data/success.json'))
})
router.get("/users-data", (request, response) => {
response.send(require("./json/users-data/success.json"))
})
router.get('/results-data', (request, response) => {
response.send(require('./json/results-data/results.json'))
})
router.get('/records-data', (request, response) => {
response.send(require('./json/records-data/records.json'))
})
router.post('/submit-enter', (request, response) => {
const data = request.body;
response.send({ success: true, message: "Вы успешно вошли в аккаунт!" });
});
router.post('/submit-reg', (request, response) => {
const data = request.body;
response.send({ success: true, message: "Регистрация прошла успешно!" });
});
router.post('/submit-record', (request, response) => {
const formData = request.body;
response.send({ success: true, message: "Record submitted successfully" });
});
module.exports = router;

View File

@@ -0,0 +1,13 @@
{
"dates":
[
{ "date": "2024-01-06T18:00:00"},
{ "date": "2024-01-05T16:00:00"},
{ "date": "2024-01-07T12:00:00"}
],
"specialists":
[{"name": "Петрова Анна"},
{"name": "Сидорова Елена"},
{"name": "Иванов Олег"}]
}

View File

@@ -0,0 +1,17 @@
{
"titles":
[
{ "id": 1, "name": "Тест на самооценку", "flag":1 },
{ "id": 2, "name": "Какой у Вас тип мышления?", "flag":1 },
{ "id": 3, "name": "Экспресс IQ-тест", "flag":1 },
{ "id": 4, "name": "Определение уровня депрессии", "flag":0},
{ "id": 5, "name": "Есть ли у Вас РПП?", "flag":0 },
{ "id": 6, "name": "Тест на скрытый нарциссизм", "flag":0 },
{ "id": 7, "name": "Диагностика выгорания", "flag":0 },
{ "id": 8, "name": "Тест на уверенность в себе", "flag":0 },
{ "id": 9, "name": "Диагностика ОКР", "flag":0 },
{ "id": 10, "name": "Насколько Вы тревожны?", "flag":0 },
{ "id": 11, "name": "Тест на СДВГ", "flag":0 },
{ "id": 12, "name": "Ваш тип привязанности", "flag":0 }
]
}

View File

@@ -0,0 +1,18 @@
{
"formData":[
{
"name": "Имя1",
"phone": "89997776655",
"date": "2024-01-06",
"time": "12:00",
"specialist": "Иванов"
},
{
"name": "Имя2",
"phone": "89997776654",
"date": "2024-01-06",
"time": "15:00",
"specialist": "Иванов"
}
]
}

View File

@@ -0,0 +1,248 @@
{
"tests":
[
{
"questions":
["Мне кажется, что другие выглядят лучше, чем я",
"Я боюсь выступать перед большой аудиторией",
"Я чувствую себя неловко, находясь в центре внимания",
"Я часто чувствую себя напряженным",
"Я хочу, чтобы мои действия одобрялись другими людьми",
"Мне не хочется выглядеть глупым",
"Я прихожу к мысли, что моя жизнь бессмысленна",
"Я думаю о том, чего ждут от меня другие люди"
],
"results": [{
"title":"Ваш результат - заниженная самооценка",
"description":"Если в детстве критика и похвала родителей были нечеткими, пространными, ребенок не понимает, что конкретно означает быть хорошим или плохим. Так бывает, когда мы слышим от взрослых что-то вроде: «Что за негодный ребенок мне достался!» или «У Петровых дочь умница, не то что ты» вместо конструктивной критики за конкретный поступок. Тогда в будущем мы можем стать зависимыми от чужого одобрения, постоянно доказывать, что мы нужны — точно так же, как в детстве пытались заслужить признание взрослого. Человек, у которого не было достаточного опыта любви со стороны родителей, не может «просто полюбить» себя. Он будет искать «повод» для этой любви вовне, пристально наблюдая, как к нему относятся окружающие: уважают ли они его? Считают ли «достаточно хорошим»? Вечные спутники такого человека — болезненное восприятие критики, беспричинная ревность к партнеру, отношение к любой неудаче как к тотальному провалу. Если это про вас, попробуйте взглянуть на себя с сочувствием — не как строгий учитель, а как заботливый и внимательный взрослый смотрит на своего ребенка."
},
{ "title":"Ваша результат - средняя самооценка",
"description":"Люди со средней самооценкой обычно имеют здоровое чувство уверенности в себе, но при этом они не склонны к высокомерию или недооценке своих способностей. Они могут быть целеустремленными, умеющими принимать критику и стремящимися к самосовершенствованию. Такие люди часто открыты новым идеям и опытам, готовы рисковать и пробовать что-то новое, но при этом они сохраняют здравый рассудок и реалистичные ожидания от себя и окружающих."
},
{"title":"Ваш результат - высокая самооценка",
"description":"Люди с высокой самооценкой обычно имеют сильное чувство уверенности в себе и своих способностях. Они часто стремятся к достижению высоких целей, уверены в своих решениях и способны принимать ответственность за свои действия. Люди с высокой самооценкой часто проявляют лидерские качества, умеют влиять на окружающих и эффективно решать проблемы. Они обычно отличаются открытостью к новым идеям, готовностью к риску и стремлением к саморазвитию. В то же время, люди с высокой самооценкой могут быть склонны к высокомерию, недостаточно внимательны к мнению других и не всегда готовы принимать критику. Высокая самооценка - это уверенность в своих способностях и ценности как личности. Люди с высокой самооценкой обычно имеют позитивное отношение к себе, верят в свои собственные силы и способны принимать жизненные вызовы с оптимизмом. Они обладают уверенностью в собственных решениях и способны эффективно справляться с трудностями. Однако важно отметить, что высокая самооценка не должна переходить в высокомерие или недостаток уважения к другим."}
]
},
{
"questions":
["Я часто использую символические метафоры для выражения мыслей",
"Мне кажется, что работа сценаристаили писателя очень интересна",
"Я очень увлечен, когда читаю стихи и рассказы вслух",
"Я без труда излагаю свои мысли в устной и письменной форме.",
"В школе мне не очень нравились уроки по технологии труда",
"Меня абсолютно не интересуют языки программирования",
"Одной из самых любимых игрушек в детстве у меня был конструктор",
"Я всегда был увлечен изучением иностранных языков"
],
"results": [{
"title":"Ваш результат - образное мышление",
"description":"Отделено от предмета в пространстве и времени. Преобразование информации осуществляется с помощью действий с образами. Нет физических ограниченийна преобразование. Операции можно осуществлять последовательно и одновременно. Результатом является мысль, воплощенная в новом образе. Этим мышлением обладают люди с художественным складом ума."},
{ "title":"Ваш результат - знаковое мышление",
"description":"Преобразование информации осуществляется с помощью умозаключений. Знаки объединяются в более крупные единицы по правилам единой грамматики. Результатом является мысль в форме понятия или высказывания, фиксирующего существенные отношения между обозначаемыми предметами. Этим мышлением обладают люди с гуманитарным складом ума."
},
{"title":"Ваш результат - символическое мышление",
"description":"Преобразование информации осуществляется с помощью правил вывода (в частности, алгебраических правил или арифметических знаков и операций). Результатом является мысль, выраженная в виде структур и формул, фиксирующих существенные отношения между символами. Этим мышлением обладают люди с математическим складом ума."
}
]
},
{
"questions":
["Мой сон хуже, чем в обычное время",
"Сейчас мое настроение хуже обычного",
"Я не спокоен за свое будущее",
"Мой аппетит в последнее время изменился",
"Обычно я чувствую к себе ненависть",
"У меня порой бывает желание умереть",
с трудом могу принимаю решения",
"События радуют меня меньше, чем раньше"
],
"results": [
{ "title":"Ваш результат - выраженная депрессия ",
"description":"Вы стали малообщительным человеком, стараетесь избегать контактов даже с близкими людьми. Вероятно, подолгу не выходите из своей комнаты или из дома. Происходящее вокруг теперь не вызывает такого интереса как ранее, а жизнь кажется серой. Скорее всего, вы не следите за собой, за питанием и внешним видом. В вашем случае крайне необходима помощь со стороны специалиста, не стоит тянуть время."
},{"title":"Ваш результат - умеренная депрессия",
"description":"Легкая депрессия — это расстройство, возникающее в результате перегрузки организма, конфликта с окружающими или просто сильного стресса. Она характеризуется продолжительным плохим настроением (несколько дней и более), периодической раздражительностью или даже агрессией. В последнее время все чаще вы проявляете равнодушие и апатию к окружающему, к тому, что раньше часто приносило положительные эмоции. Чувство усталости даже от нетрудной и не длительной работы. Она проходит, когда человек решает свои проблемы, но если вам не удается самостоятельно справиться с ними, то стоит обратиться за помощью к психотерапевту."
},{
"title":"Ваш результат - депрессия отсутствует",
"description":"Депрессия отсутствует, либо незначительна. Смена настроения, самочувствия часто наблюдается при сезонной депрессии или кратковременных стрессах. В первом случае это следствие недостатка солнечного света, витамина D и дефицита аминов (серотонина, дофамина, норадреналина). А во втором случае — это ощущение эмоциональных и физических перегрузок. Не стоит переживать, это вполне нормальная защитная реакция организма."}
]
},
{
"questions":
["Я испытываю ужас при мысли об избыточном весе",
"Я избегаю приема пищи, когда чувствую голод",
"Я разрезаю свою еду на маленькие кусочки",
"Я знаю о количестве калорий в моей еде",
"Я избегаю пищу с большим содержанием углеводов",
"Другие хотели бы, чтобы я ел больше",
"У меня бывает рвота после того, как поем",
"Я испытываю чрезмерную вину после еды"
],
"results": [{
"title":"Ваш результат - похоже у вас РПП",
"description":"Вы набрали высокие баллы по показателям анорексии и булимии. Это момент для серьезного разговора и поддержки. Анорексия и булимия это не просто «диеты» или «плохие привычки». Это глубокие психологические трудности, которые могут иметь опасные и даже смертельные последствия. При анорексии люди могут потерять контакт с реальностью, столкнуться с критическим истощением, нарушением работы внутренних органов. И, да, это может привести к летальному исходу… Булимия тоже чревата серьезными последствиями: электролитный дисбаланс, проблемы с пищеварением, повреждение зубов и даже сердечные нарушения."},
{"title":"Ваш результат - ограничительное пищевое поведение",
"description":"Ограничительное пищевое поведение является следствием самолечения от ожирения или дистрофии.Ограничительное пищевое поведение может возникнуть на фоне диетотерапии. Крайняя степень выражения ограничительного поведения так называемая «диетическая депрессия».Профилактикой ограничительного пищевого поведения может послужить постепенное, а не одномоментное исключение из рациона любимых блюд."
},
{ "title":"Ваш результат - у вас нет РПП ",
"description":"Поздравляем! У вас отличные отношения с едой. Кажется, ваше детство прошло без лишнего давления или критики по поводу фигуры и пищевых привычек. Вас, вероятно, не заставляли есть против вашей воли, и вы выросли в атмосфере поддержки и позитивного отношения к своему телу. Будьте здоровы!"
}
]
},
{
"questions":
["Другие люди недостаточно ценят мои хорошие качества",
"Люди часто видятся мне либо величественными, либо ужасными",
"Я особенно чувствительно реагирую на свои успех и неудачи",
"Я очень сильно завидую тем, у кого есть то, чего нет у меня",
"Я завидую всем людям, которых считаю красивее себя",
"В отношениях я то обожаю, то презираю другого человека",
"Я сильно боюсь быть отвергнутым другим человеком",
"Когда меня критикуют, я чувствую сильное унижение и апатию"
],
"results": [{
"title":"Ваш результат - тайный поклонник себя",
"description":"Ваш результат указывает на высокий уровень скрытого нарциссизма. Это означает, что ваша самооценка и самоуважение во многом зависят от внешнего одобрения и восхищения со стороны окружающих. Вы особенно чувствительны к критике и склонны скрывать свое негодование, вызванное критическими замечаниями, из страха перед еще большим осуждением. Вы частенько «уходите в себя», пытаясь защитить свою уязвимую сторону от враждебного мира, и оставляете участников коммуникации и партнеров в недоумении.Вероятно, вам приходится постоянно ранжировать свои мысли, эмоции, чувства и действия, чтобы продемонстрировать те, которые «подходят» ситуации. Этот процесс может отнимать колоссальное количество ресурса — и вы постоянно чувствуете усталость и истощение. Истинные чувства и мотивы приходится скрывать. Из-за этого ваше поведение может выглядеть загадочным и непоследовательным для окружающих. "},
{"title":"Ваш результат - легкая тень нарциссизма",
"description":"Вы набрали средний балл по шкале нарциссической уязвимости. Вероятно, вы периодически ищете подтверждения своей значимости со стороны других. Вы чувствительны к критике и беспокоитесь о том, что о вас подумают другие. Иногда вы переживаете моменты неуверенности в себе, которые компенсируете внешним одобрением и вниманием окружающих. Несмотря на то, что ваш результат находится в рамках нормы, эти нарциссические черты все-таки могут вызывать некоторую неудовлетворенность. Кроме того, ваш результат может отражать определенную степень интроверсии, которая не обязательно связана с нарциссическими чертами. Это может означать, что вы предпочитаете делиться своими мыслями и мотивами поступков только с ограниченным кругом близких, и в целом проявляете избирательность в коммуникациях."
},
{ "title":"Ваша результат - ваше Эго в порядке ",
"description":"У вас нет или очень мало деструктивных нарциссических черт. Вы вряд ли находитесь в постоянном поиске внешней валидации, внимания или восхищения. Вы склонны подходить к критике с открытым умом, и не слишком огорчаетесь, если вам отказывают в просьбах. Ваши дружеские и романтические связи, скорее всего, строятся на взаимном уважении и эмпатии, а ваша самооценка стабильна и не зависит от постоянного одобрения окружающих. Это замечательно!"
}
]
},
{
"questions":
["Я чувствую эмоциональную опустошенность",
"После работы я чувствую себя, как выжатый лимон",
"Утром мне тяжело выйти на работу",
"Я редко чувствую энергию и эмоциональный подъем",
"Я часто чувствую угнетенность и апатию",
"Я замечаю, что моя работа ожесточает меня",
"Моя работа все больше меня разочаровывает",
"Мне глубоко безразлично, как живут мои знакомые"
],
"results": [{
"title":"Ваш результат - выгорание",
"description":"Эмоциональное выгорание случается, когда мы работаем до истощения ресурсов, игнорируем усталость и не умеем ее отслеживать. Нервное напряжение становится обычным фоном — и скоро желание что-то делать и вообще вставать с кровати приближается к нулю. Человек в таком состоянии недоволен не только работой, но и собой в целом, падает иммунитет, коллеги и задачи раздражают или даже вызывают ненависть. Частый спутник выгорания — зависимость. Сначала бокал вина кажется неплохим способом справиться со стрессом, затем бокал перерастает в бутылку, а последствия употребления алкоголя лишают сил окончательно. На последних стадиях выгорания мы уже не помним, что значит чувствовать вдохновение от работы, становимся апатичными, выполняем задачи по минимально допустимой планке качества — лишь бы не уволили. "},
{"title":"Ваш результат - на пороге выгорания",
"description":"Еще недавно вы были влюблены в свое дело и энергичны — теперь же редко можете выполнить больше необходимого минимума задач. Вы мотивируете себя — «надо поднажать, выпить еще кофе», — но результата почти нет. Утром вы никак не можете проснуться, а вечером тянетесь к алкоголю, вредной еде, сериалам. Так бывает, когда фокус внимания «застревает» на работе: вы считаете, что дела надо делать лучше, а жизнь за пределами офиса или рабочего ноутбука может пока подождать. Сказываются и сами условия работы: например, когда задач и требований слишком много, а внутри команды зреют конфликты и токсичная конкуренция"
},
{ "title":"Ваша результат - нет выгорания ",
"description":"Похоже, работа вам в радость. В понедельник утром вы бодры и настроены на продуктивную неделю: новые задачи вызывают любопытство, брейнштормы с командой — вдохновение, вычеркнутые из списка дела — гордость. Команда вас ценит: вы проявляете инициативу, не подводите с дедлайнами и готовы в перерывах поболтать за чашкой кофе. Большинство людей именно так представляют себе идеальные отношения с работой. В чем же ваш секрет? Чаще всего устойчивость к выгоранию наращивается за пределами рабочего места: в отношениях с близкими, интересных хобби, умении слышать себя. Вы отдыхаете качественно и регулярно (а не когда сил уже нет совсем), поддерживаете себя, если что-то не получается, не принимаете рабочие конфликты близко к сердцу."
}
]
},
{
"questions":
["Я чувствую беспокойство, если не знаю, чего от меня ждут",
"Я склонен очень критично относиться как к себе, так и к другим",
"Я боюсь выглядеть глупо и беспокоюсь о своей внешности",
"Я преувеличиваю свои ошибки и преуменьшаю успехи",
"Я часто чувствую опустошенность или подавленность",
"Большую часть времени я тревожусь относительно неважных вещей",
"Я чувствую, что не знаю, что нужно сделать или сказать",
"Я боюсь сделать ошибку, которую заметят другие люди"
],
"results": [{
"title":"Ваш результат - не уверены в себе",
"description":"Вы привыкли быть безжалостным критиком самому себе. Похоже, в детстве эту роль выполняли ваши родители — их похвала, если и была, то звучала абстрактно; зато упреки попадали прямо в цель. «Что за негодный ребенок мне достался!», «От тебя — одни беды», «За что мне такое наказание?» — такие послания говорят не о наших поступках, а о нас целиком. Они фиксируют в психике уверенность ребенка в том, что сам по себе он ничтожен, не достоин внимания и любви. Когда мы вырастаем, желание заслужить эту любовь становится ведущим, а критикующий голос «поселяется» внутри, превращается в преследователя и экзекутора, который следит за каждым нашим шагом. Следуя ему, мы начинаем себя оценивать еще до того, как нас оценили другие."},
{"title":"Ваш результат - средняя уверенность",
"description":"Ваши результаты теста на уверенность в себе указывают на то, что у вас сбалансированный уровень самоуверенности. Возможно, у вас бывают моменты колебаний и сомнений в своих способностях, но в целом вы обладаете здоровой долей уверенности. Вы можете иногда испытывать неуверенность в своих действиях или решениях, но это не мешает вам двигаться вперед и принимать вызовы. Вы готовы учиться на своих ошибках и стремитесь к личному развитию."
},
{ "title":"Ваш результат - уверены в себе ",
"description":"Ваши результаты теста на уверенность в себе свидетельствуют о том, что вы обладаете здоровой самоуверенностью и позитивным отношением к себе. Вероятно, у вас была поддерживающая и позитивная среда в детстве, где вас поощряли и высоко ценили. Вы умеете видеть свои сильные стороны и цените себя как личность. Ваши достижения и качества не остаются незамеченными, и вы умеете радоваться своим успехам. Ваше отношение к себе положительное, и вы не склонны к самокритике или излишнему самообвинению. "
}
]
},
{
"questions":
["Я порой чувствую, что мне не по себе",
"Я испытываю внутреннее напряжение или дрожь",
"Я часто испытываю сильный страх и ужас",
"Я неусидчивый, мне постоянно нужно двигаться",
"Беспокойные мысли крутятся у меня в голове",
"У меня бывает внезапное чувство паники",
"Мне бывает трудно сесть и расслабиться",
"Я боюсь сделать ошибку, которую заметят другие"
],
"results": [{
"title":"Ваш результат - выраженная тревога",
"description":"Возможно, вы часто ощущаете беспокойство, нервозность и неспокойство по поводу различных ситуаций в вашей жизни. Тревога может влиять на ваше поведение, эмоциональное состояние и даже физическое здоровье. Важно обратить внимание на свои ощущения и найти способы справляться с тревожностью. Помните, что тревога — это естественная реакция организма на стрессовые ситуации, но если она начинает мешать вашей повседневной жизни, важно обратиться за помощью к специалисту. "},
{"title":"Ваш результат - умеренный уровень",
"description":"У вас наблюдается определенная степень тревожности. Время от времени вы ощущаете беспокойство или нервозность, но это не преобладает в вашей повседневной жизни. Средний уровень тревоги может быть обусловлен стрессом, изменениями в жизни или другими факторами. Важно обращать внимание на свои эмоции и уметь справляться с ними. Регулярные методы релаксации могут помочь снизить уровень тревоги."
},
{ "title":"Ваша результат - нет тревоги ",
"description":"Поздравляем! Результаты вашего теста на тревогу показывают, что у вас низкий уровень тревожности. Это означает, что вы обычно спокойны и уверены в себе, не испытываете значительной тревоги или беспокойства. Низкий уровень тревоги свидетельствует о том, что вы хорошо справляетесь с повседневными стрессовыми ситуациями и не даете негативным эмоциям влиять на ваше благополучие. "
}
]
},
{
"questions":
["Мне трудно помнить обо всех назначенных встречах и обязательствах",
"Когда мне нужно долго сидеть на месте, я ерзаю, делаю лишние движения",
"Я часто совершаю в работе ошибки по невнимательности",
"Бывает такое, что я теряю и потом с трудом нахожу вещи",
"Мне сложно держать внимание при скучной однообразной работе",
"Я отвлекаюсь на события или шум вокруг во время работы или важного дела",
"Мне трудно расслабиться и отдохнуть, даже когда у меня есть свободное время",
"Я порой заканчиваю предложения за других, не давая им договорить"
],
"results": [{
"title":"Ваш результат - похоже у вас СДВГ",
"description":"Результаты теста говорят о том, что вы — и скорее всего, уже давно — замечаете за собой невнимательность к деталям, ошибки из-за небрежности, проблемы с планированием и организацией дел, склонность терять вещи и опаздывать. Это признаки так называемого «невнимательного» типа СДВГ, которые часто дополняются признаками «гиперактивного» типа: суетливостью, беспокойством, склонностью делать что-то импульсивно и не оценивая последствия. Жить с СДВГ правда тяжело — во многом еще и потому, что общество, ориентированное на «отличников», которые всего достигают и не делают глупостей, часто призывает людей с таким диагнозом «взять себя в руки», «перестать лениться», жить и работать по распорядку, держать дела «по полочкам»."},
{"title":"Ваш результат - симптомы СДВГ",
"description":"Синдром дефицита внимания и гиперактивности — это особенность нейроразвития, которая серьезно влияет на поведение человека. О его проявлениях сегодня говорят много — это неусидчивость, невнимательность, неспособность замедлиться и расслабиться, будто внутри работает заведенный мотор. Обычно симптомы проявляются с детства, и если у ребенка их можно объяснить особенностями темперамента или возрастным кризисом (кто из нас не отвлекался на уроках и не забывал сменку?), то взрослым СДВГ сильно мешает жить."
},
{ "title":"Ваша результат - нет СДВГ ",
"description":"Поздравляем! Ваши ответы на вопросы теста говорят о том, что с внимательностью и усидчивостью у вас все в порядке. У вас также нет проблем с концентрацией и памятью, вы можете работать последовательно — без вспышек активности и апатии. Похоже, вы не склонны действовать импульсивно, не оценивая последствий, и можете контролировать «неприятные» импульсы, вроде желания перебить собеседника, отвлечься на суету за окном, бросить дело на полпути. "
}
]
},
{
"questions":
[" Навязчивые мысли сильно влияют на вашу повседневную жизнь",
"У Вас есть привычка считать непредсказуемые вещи",
"Вы пристально наблюдаюте за дыханием, морганием",
"Вам постоянно кажется, что вокруг недостаточно чисто",
"У Вас есть ритуальные действия для снижения тревоги",
"Перед выходом из дома вы перепроверяете, выключен ли утюг, свет",
"Вы не выносите, когда вещи лежат не на своем месте",
"Вы испытываете навязчивый страх какого-либо тяжелого заболевания"
],
"results": [{
"title":"Ваш результат - сильное ОКР",
"description":"Похоже, ваша жизнь наполнена всепоглощающей тревогой. Иногда вы можете на время заглушать ее, выполняя весьма затейливые ритуалы. Может казаться, что вы временами теряете контакт с реальным миром, и магическое мышление начинает доминировать над логическим и рациональным. Например, вам кажется, что если вы выполните определенное действие несколько раз, то это каким-то образом улучшит ваше состояние, даже если это противоречит здравому смыслу. Вам чрезвычайно сложно контролировать и останавливать повторяющееся поведение. Если другие люди пытаются изменить «заведенный порядок», это может вызывать раздражение и гнев. "},
{"title":"Ваш результат - средне-выраженное ОКР",
"description":"Вы отмечаете некоторые странности в своем поведении и мыслях. Возможно, вас давно беспокоит какая-то идея, но в целом жить это не мешает. Подумаешь, странности есть у всех! Иногда хочется часто мыть руки после встречи с неприятным человеком или проверять, все ли в порядке в доме, в документах, в новостях. Но это ситуативные случаи, и в целом вы можете противостоять этим состояниям так, чтобы они не нарушали ваш привычный ритм. Если вы понимаете, что в последнее время навязчивое поведение повторяется слишком часто, и вы хотите от него избавиться — проконсультируйтесь со специалистом"
},
{ "title":"Ваша результат - нет ОКР ",
"description":"Поздравляем! Это означает, что у вас нет характерных симптомов этого психического расстройства, таких как навязчивые мысли и компульсивные действия. Отсутствие ОКР является позитивным результатом, поскольку обсессивно-компульсивное расстройство может серьезно повлиять на качество жизни человека, вызывая тревожность, стресс и нарушения в поведении."
}
]
}
],
"options": [
{"text": "Совершенно верно", "count": 4},
{"text": "Верно", "count": 3},
{"text": "Затрудняюсь ответить", "count": 2},
{"text": "Скорее неверно", "count": 1},
{"text": "Совершенно неверно", "count": 0}
],
"titles":
[
{ "id": 0, "name": "Тест на самооценку", "executionTime": 3, "filter": "На тип личности"},
{ "id": 1, "name": "Какой у Вас тип мышления?", "executionTime": 2, "filter": "Интеллектуальные" },
{ "id": 2, "name": "Определение уровня депрессии", "executionTime": 4, "filter": "Диагностика расстройств"},
{ "id": 3, "name": "Есть ли у Вас РПП?", "executionTime": 1, "filter": "Быстрые" },
{ "id": 4, "name": "Тест на скрытый нарциссизм", "executionTime": 4, "filter": "На тип личности" },
{ "id": 5, "name": "Диагностика выгорания", "executionTime": 3, "filter": "Диагностика расстройств" },
{ "id": 6, "name": "Тест на уверенность в себе", "executionTime": 2, "filter": "Быстрые" },
{ "id": 7, "name": "Насколько Вы тревожны?", "executionTime": 5, "filter": "Диагностика расстройств" },
{ "id": 8, "name": "Тест на СДВГ", "executionTime": 1, "filter": "Быстрые" },
{ "id": 9, "name": "Диагностика ОКР", "executionTime": 2, "filter": "Диагностика расстройств" }
]}

View File

@@ -0,0 +1,14 @@
[
{
"eMail": "dashakhan3009@mail.ru",
"first_name": "Дарья",
"second_name": "Ханаева",
"password": "qwerty123"
},
{
"eMail": "alexandraaa.ha@gmail.com",
"first_name": "Александра",
"second_name": "Харитонова",
"password": "12345"
}
]

View File

@@ -0,0 +1,35 @@
const router = require('express').Router();
router.get("/users", (request, response) => {
response.send(require("./json/users/users.json"))
})
router.post("/auth", (request, response) => {
const {phoneNumber, password} = request.body;
console.log(phoneNumber, password);
if (phoneNumber === '89999999999') {
response.send(require("./json/auth/dogsitter.success.json"))
}
else if (phoneNumber === '89555555555') {
response.status(400).send(require("./json/auth/error.json"))
}
else {
response.send(require("./json/auth/owner.success.json"))
}
})
router.post("/register", (request, response) => {
const {firstName, secondName, phoneNumber, password, role} = request.body;
console.log(phoneNumber, password, role);
if (phoneNumber === '89283244141' || phoneNumber === '89872855893') {
response.status(400).send(require("./json/register/error.json"))
}
else if (role === 'dogsitter') {
response.send(require("./json/register/dogsitter.success.json"))
}
else {
response.send(require("./json/register/owner.success.json"))
}
})
module.exports = router;

View File

@@ -0,0 +1,12 @@
{
"data": {
"id": 1,
"phoneNumber": 89283244141,
"firstName": "Вася",
"secondName": "Пупкин",
"role": "dogsitter",
"location": "Россия, республика Татарстан, Казань, улица Пушкина, 12",
"price": 1500,
"aboutMe": "Я люблю собак"
}
}

View File

@@ -0,0 +1,3 @@
{
"error": "Пользователь не найден"
}

View File

@@ -0,0 +1,9 @@
{
"data": {
"id": 3,
"phoneNumber": 89872855893,
"firstName": "Гадий",
"secondName": "Петрович",
"role": "owner"
}
}

View File

@@ -0,0 +1,12 @@
{
"data": {
"id": 5,
"phoneNumber": 89555555555,
"firstName": "Масяня",
"secondName": "Карлова",
"role": "dogsitter",
"location": "Россия, республика Татарстан, Казань, улица Пушкина, 12",
"price": 100,
"aboutMe": "Все на свете - собаки"
}
}

View File

@@ -0,0 +1,3 @@
{
"error": "Пользователь с таким номером телефона уже существует"
}

View File

@@ -0,0 +1,9 @@
{
"data": {
"id": 6,
"phoneNumber": 89888888888,
"firstName": "Генадий",
"secondName": "Паровозов",
"role": "owner"
}
}

View File

@@ -0,0 +1,39 @@
[
{
"id": 1,
"phone_number": 89283244141,
"first_name": "Вася",
"second_name": "Пупкин",
"role": "dogsitter",
"location": "Россия, республика Татарстан, Казань, улица Пушкина, 12",
"price": 1500,
"about_me": "Я люблю собак"
},
{
"id": 2,
"phone_number": 89272844541,
"first_name": "Ваня",
"second_name": "Пуськин",
"role": "dogsitter",
"location": "Россия, республика Татарстан, Казань, улица Абсалямова, 19",
"price": 1000000,
"about_me": "Я не люблю собак. И вообще я котоман."
},
{
"id": 3,
"phone_number": 89872855893,
"first_name": "Гадий",
"second_name": "Петрович",
"role": "owner"
},
{
"id": 4,
"phone_number": 89872844591,
"first_name": "Галкин",
"second_name": "Максим",
"role": "dogsitter",
"location": "Россия, республика Татарстан, Казань, проспект Ямашева, 83",
"price": 1000000,
"about_me": "Миллион алых роз"
}
]

View File

@@ -0,0 +1,15 @@
const router = require('express').Router()
router.get('/arm/masters', (req, res) => {
res
.status(200)
.send(require("./json/arm-masters/success.json"))
})
router.get('/arm/orders', (req, res) => {
res
.status(200)
.send(require(`./json/arm-orders/success.json`))
})
module.exports = router

View File

@@ -0,0 +1,35 @@
{
"success": true,
"body": [
{
"id": "masters1",
"name": "Иван Иванов",
"schedule": [ {
"id": "order1",
"startWashTime": "2024-11-24T10:30:00.000Z",
"endWashTime": "2024-11-24T16:30:00.000Z"
},
{
"id": "order2",
"startWashTime": "2024-11-24T11:30:00.000Z",
"endWashTime": "2024-11-24T17:30:00.000Z"
}],
"phone": "+7 900 123 45 67"
},
{
"id": "masters12",
"name": "Иван Иванов",
"schedule": [ {
"id": "order1",
"startWashTime": "2024-11-24T10:30:00.000Z",
"endWashTime": "2024-11-24T16:30:00.000Z"
},
{
"id": "order2",
"startWashTime": "2024-11-24T11:30:00.000Z",
"endWashTime": "2024-11-24T17:30:00.000Z"
}],
"phone": "+7 900 123 45 67"
}
]
}

View File

@@ -0,0 +1,25 @@
{
"success": true,
"body": [
{
"id": "order1",
"carNumber": "A123BC",
"startWashTime": "2024-11-24T10:30:00.000Z",
"endWashTime": "2024-11-24T16:30:00.000Z",
"orderDate": "2024-11-24T08:41:46.366Z",
"status": "progress",
"phone": "79001234563",
"location": "Казань, ул. Баумана, 1"
},
{
"id": "order2",
"carNumber": "A245BC",
"startWashTime": "2024-11-24T11:30:00.000Z",
"endWashTime": "2024-11-24T17:30:00.000Z",
"orderDate": "2024-11-24T07:40:46.366Z",
"status": "progress",
"phone": "79001234567",
"location": "Казань, ул. Баумана, 43"
}
]
}

View File

@@ -0,0 +1,15 @@
const router = require('express').Router();
router.get('/recipe-data', (request, response) => {
response.send(require('./json/recipe-data/success.json'))
})
router.get('/userpage-data', (req, res)=>{
res.send(require('./json/userpage-data/success.json'))
})
router.get('/homepage-data', (req, res)=>{
res.send(require('./json/homepage-data/success.json'))
})
module.exports = router;

View File

@@ -0,0 +1,112 @@
{
"data": [
{
"src": "pancakes_meat",
"alt": "Фотография блинчиков с мясом, сыром и луком",
"href": "?=dish01",
"name": "Блинчики с мясом, сыром и лучком",
"category": [
"Ужины"
]
},
{
"src": "cheesecakes",
"alt": "Фотография сырников из творога",
"href": "?=dish02",
"name": "Сырники из творога",
"category": [
"Завтраки"
]
},
{
"src": "borsch",
"alt": "Фотография борща",
"href": "?=dish03",
"name": "Борщ",
"category": [
"Супы"
]
},
{
"src": "vareniki",
"alt": "Фотография вареников",
"href": "?=dish04",
"name": "Ленивые вареники",
"category": [
"Ужины"
]
},
{
"src": "rice_porridge",
"alt": "Фотография рисовой каши",
"href": "?=dish05",
"name": "Рисовая каша",
"category": [
"Завтраки"
]
},
{
"src": "cutlets",
"alt": "Фотография котлет по-киевски",
"href": "?=dish06",
"name": "Котлеты по-киевски",
"category": [
"Обеды"
]
},
{
"src": "draniki",
"alt": "Фотография драников",
"href": "?=dish07",
"name": "Драники",
"category": [
"Обеды"
]
},
{
"src": "meringue",
"alt": "Фотография безе",
"href": "?=dish08",
"name": "Безе",
"category": [
"Выпечка и десерты"
]
},
{
"src": "goulash",
"alt": "Фотография гуляша",
"href": "?=dish09",
"name": "Гуляш",
"category": [
"Мясо"
]
},
{
"src": "pancakes_cherries",
"alt": "Фотография блинчиков с вишней и творожным сыром",
"href": "?=dish10",
"name": "Блинчики с вишней и творожным сыром",
"category": [
"Завтраки"
]
},
{
"src": "canned_soup",
"alt": "Фотография супа из рыбных консервов",
"href": "?=dish11",
"name": "Суп из рыбных консервов",
"category": [
"Супы"
]
},
{
"src": "salad",
"alt": "Фотография салата",
"href": "?=dish12",
"name": "Салат \"Весенний\"",
"category": [
"Салаты"
]
}
]
}

View File

@@ -0,0 +1,58 @@
{
"name":"Блинчики с вишней и творожным сыром",
"stages":
[
"Смешать муку, молоко, яйца, сахар и соль в миске",
"Добавить вишню в тесто и перемешать",
"Вылить тесто на разогретую сковороду и обжарить с двух сторон до золотистого цвета",
"Подавать блинчики, украсив творожным сыром сверху"
],
"table":
[
{ "ingredient": "1",
"weight": "500 гр",
"price1": "500р.",
"price2": "439р.",
"price3": "600р." },
{ "ingredient": "Ингредиент 2",
"weight": "2 шт",
"price1": "120р.",
"price2": "150р.",
"price3": "130р." },
{ "ingredient": "Ингредиент 3",
"weight": "500 гр",
"price1": "12р.",
"price2": "12.99р.",
"price3": "10р." },
{ "ingredient": "Ингредиент 4",
"weight": "500 гр",
"price1": "500р.",
"price2": "439р.",
"price3": "600р." },
{ "ingredient": "Ингредиент 5",
"weight": "500 гр",
"price1": "500р.",
"price2": "439р.",
"price3": "600р." },
{ "ingredient": "Ингредиент 6",
"weight": "500 гр",
"price1": "500р.",
"price2": "439р.",
"price3": "600р." }
],
"tags":
[
{ "name": "#блины", "href": "#01" },
{ "name": "#вишня", "href": "#02" },
{ "name": "#молоко"," href": "#03" }
]
}

View File

@@ -0,0 +1,30 @@
{
"data":{
"id":1,
"loginname":"Логин пользователя",
"datesignin":"2024/05/18",
"favoritedishes":
[
{"id":1,
"dishlink":"?=dish1",
"dishname":"Блюдо1"
},
{"id":2,
"dishlink":"?=dish2",
"dishname":"Блюдо2"
},
{"id":3,
"dishlink":"?=dish3",
"dishname":"Блюдо3"
},
{"id":4,
"dishlink":"?=dish4",
"dishname":"Блюдо4"
},
{"id":5,
"dishlink":"?=dish5",
"dishname":"Блюдо5"
}
]
}
}

View File

@@ -0,0 +1,147 @@
const adminRouter = require('express').Router()
const fs = require('fs')
const path = require('path')
const { TOKEN } = require('../const')
require('dotenv').config()
const dataFilePath = path.join(__dirname, '../data.json')
let data = require('../data.json')
const verifyToken = (req, res, next) => {
const token = req.headers['authorization']
if (token === TOKEN) {
next()
} else {
res.status(403).send({ 'status': 'Failed', 'data': 'Invalid token' })
}
}
const saveData = (data) => {
fs.writeFileSync(dataFilePath, JSON.stringify(data, null, 2), 'utf-8')
}
adminRouter.post('/edit/nickname', verifyToken, (req, res) => {
const { name, colored } = req.body
if (!name || !colored) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Nickname is required' })
}
data.nickname = { name, colored }
saveData(data)
res.status(200).send({ 'status': 'OK', 'data': 'Nickname updated successfully' })
})
adminRouter.post('/edit/tech-stack', verifyToken, (req, res) => {
const { techStack } = req.body
if (!techStack || !Array.isArray(techStack)) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Valid tech stack is required' })
}
data.techStack = techStack
saveData(data)
res.status(200).send({ 'status': 'OK', 'data': 'Tech stack updated successfully' })
})
adminRouter.post('/edit/city', verifyToken, (req, res) => {
const { city } = req.body
if (!city) {
return res.status(400).send({ 'status': 'Failed', 'data': 'City is required' })
}
const isValid = typeof city === 'object' && 'name' in city && 'href' in city
if (!isValid) {
return res.status(400).send({ 'status': 'Failed', 'data': 'City must contain href and name' })
}
data.city = city
saveData(data)
res.status(200).send({ 'status': 'OK', 'data': 'City updated successfully' })
})
adminRouter.post('/edit/github-repo', verifyToken, (req, res) => {
const { github } = req.body
if (!github) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Github is required' })
}
const isValid = typeof github === 'object' && 'author' in github && 'repo' in github
if (!isValid) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Github must contain author and repo' })
}
data.githubRepo = github
saveData(data)
res.status(200).send({ 'status': 'OK', 'data': 'Github updated successfully' })
})
adminRouter.post('/edit/nav-links', verifyToken, (req, res) => {
const { navLinks } = req.body
if (!navLinks || !Array.isArray(navLinks)) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Valid navLinks are required' })
}
const isValid = navLinks.every(link =>
link && typeof link === 'object' && 'href' in link && 'title' in link
)
if (!isValid) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Each navLink must contain href and title' })
}
data.navLinks = navLinks
saveData(data)
res.status(200).send({ 'status': 'OK', 'data': 'Navigation links updated successfully' })
})
adminRouter.post('/edit/links', verifyToken, (req, res) => {
const { links } = req.body
if (!links || !Array.isArray(links)) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Valid links are required' })
}
const isValid = links.every(link =>
link && typeof link === 'object' && 'href' in link && 'title' in link
)
if (!isValid) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Each link must contain href and title' })
}
data.links = links
saveData(data)
res.status(200).send({ 'status': 'OK', 'data': 'Links updated successfully' })
})
adminRouter.post('/edit/projects', verifyToken, (req, res) => {
const { projects } = req.body
if (!projects) {
return res.status(400).send({ 'status': 'Failed', 'data': 'Projects are required' })
}
const projectFields = ['id', 'title', 'description', 'link', 'techStack', 'image']
const isValidProject = (project) => {
return projectFields.every(field => field && field in project)
}
const allProjectsValid = projects.every(project => isValidProject(project))
if (!allProjectsValid) {
return res.status(400).send({ 'status': 'Failed', 'data': 'All projects must contain ' + projectFields.join(", ") })
}
data.projects = projects
saveData(data)
res.status(200).send({ 'status': 'OK', 'data': 'Projects updated successfully' })
})
module.exports = adminRouter

View File

@@ -0,0 +1,16 @@
const authRouter = require('express').Router()
const { TOKEN } = require('../const')
module.exports = authRouter
authRouter.post('/login', (req, res) => {
const { email, password } = req.body
console.log(`Login with email=${email} and password=${password}`)
if (email === 'admin@admin.admin' && password === 'admin') {
res.status(200).send({ 'status': 'OK', 'data': `${TOKEN}` })
} else {
res.status(401).send({ 'status': 'Failed!', 'data': 'Invalid email or password' })
}
})

View File

@@ -0,0 +1,3 @@
const TOKEN = "ASDFGHJKLLKJHGFDSDFGHJKJHGF"
module.exports = { TOKEN }

View File

@@ -0,0 +1,118 @@
{
"nickname": {
"name": "supercool",
"colored": "nickname"
},
"techStack": [
"React",
"Next.js",
"Svelte",
"SvelteKit",
"HTML",
"CSS",
"JavaScript",
"TypeScript",
"TailwindCSS",
"Styled-Components",
"Framer-Motion",
"shadcn-ui",
"Ant-Design",
"ESLint",
"Prettier",
"husky",
"lint-staged",
"Redux",
"RTK Query",
"Tanstack Query",
"Python",
"FastApi",
"Flask",
"SQLite",
"PostgreSQL",
"MongoDB",
"SQLAlchemy",
"Alembic",
"PyPy",
"poetry",
"pylint",
"GitHub Actions",
"GitLab CI/CD",
"Docker",
"Git"
],
"githubRepo": {
"author": "MishaBlin",
"repo": "EPJA_portfolio_app"
},
"city": {
"name": "Innopolis",
"href": "https://ru.wikipedia.org/wiki/Иннополис"
},
"navLinks": [
{
"href": "#about",
"title": "About"
},
{
"href": "#projects",
"title": "Projects"
}
],
"links": [
{
"href": "mailto:svyatoslavsvyatkin@yandex.ru",
"title": "Mail"
},
{
"href": "https://t.me/dmhd6219",
"title": "Telegram"
},
{
"href": "https://github.com/dmhd6219",
"title": "GitHub"
},
{
"href": "https://last.fm/user/dmhd",
"title": "LastFm"
},
{
"href": "https://pay.cloudtips.ru/p/02da9349",
"title": "Buy me a coffee"
}
],
"projects": [
{
"title": "Elasticsearch",
"description": "Elasticsearch is a distributed search and analytics engine, scalable data store and vector database optimized for speed and relevance on production-scale workloads.",
"link": "https://github.com/elastic/elasticsearch",
"techStack": [
"Java",
"Groovy"
],
"image": "https://datascientest.com/en/files/2023/04/Elasticsearch.jpg",
"id": "elasticsearch"
},
{
"title": "React-native",
"description": "React Native brings React's declarative UI framework to iOS and Android. With React Native, you use native UI controls and have full access to the native platform.",
"link": "https://github.com/facebook/react-native",
"techStack": [
"C++",
"Javascript",
"Kotlin"
],
"image": "https://www.simplilearn.com/ice9/free_resources_article_thumb/React_Native_Tutorial.jpg",
"id": "react-native"
},
{
"title": "Zarr",
"description": "Zarr is a Python package providing an implementation of compressed, chunked, N-dimensional arrays, designed for use in parallel computing. See the documentation for more information.",
"link": "https://github.com/zarr-developers/zarr-python",
"techStack": [
"Python"
],
"image": "https://raw.githubusercontent.com/zarr-developers/community/main/logos/logo2.png",
"id": "zarr"
}
]
}

View File

@@ -0,0 +1,11 @@
const authRouter = require('./auth')
const adminRouter = require('./admin')
const rootRouter = require('./root')
const router = require('express').Router()
module.exports = router
router.use(`/auth`, authRouter)
router.use(`/admin`, adminRouter)
router.use(`/`, rootRouter)

View File

@@ -0,0 +1,44 @@
const rootRouter = require('express').Router()
const data = require('../data.json')
rootRouter.get('/get/nickname', (req, res) => {
res.status(200).send({ 'status': 'OK', 'data': data.nickname })
})
rootRouter.get('/get/tech-stack', (req, res) => {
res.status(200).send({ 'status': 'OK', 'data': data.techStack })
})
rootRouter.get('/get/github-repo', (req, res) => {
res.status(200).send({ 'status': 'OK', 'data': data.githubRepo })
})
rootRouter.get('/get/city', (req, res) => {
res.status(200).send({ 'status': 'OK', 'data': data.city })
})
rootRouter.get('/get/nav-links', (req, res) => {
res.status(200).send({ 'status': 'OK', 'data': data.navLinks })
})
rootRouter.get('/get/links', (req, res) => {
res.status(200).send({ 'status': 'OK', 'data': data.links })
})
rootRouter.get('/get/projects', (req, res) => {
res.status(200).send({ 'status': 'OK', 'data': data.projects })
})
rootRouter.get('/get/projects/:id', (req, res) => {
const { id } = req.params
const project = data.projects.find(p => p.id === id)
if (project) {
res.status(200).send({ status: 'OK', data: project })
} else {
res.status(404).send({ status: 'NOT_FOUND', message: 'Project not found' })
}
})
module.exports = rootRouter

View File

@@ -0,0 +1,9 @@
const plantsRouter = require('./plants/getPlants')
const calendarRouter = require('./plants_calendar/index')
const router = require('express').Router()
module.exports = router
router.use('/plants',plantsRouter)
router.use('/plants_calendar',calendarRouter)

View File

@@ -0,0 +1,6 @@
const CONFIG = {
CLIENT_ID: 'kD2JXj1faSCYAWdT4B069wQAx89CZAkXmzTinRvH',
CLIENT_SECRET: 'bJq7Uiwua52tHiLP80N60hALNtQX2wcE4Mj6yNA9OzG2iZbgHuqyeAs6WSWX6MNJdfv0Nqzb7OHta8qPZr4zxWBLTauleaMfraln3xFEvbXLDpi1Lcrwe7DxfgsQQ1E4',
}
module.exports = CONFIG

View File

@@ -0,0 +1,143 @@
const express = require ('express')
const axios = require ('axios')
const plantsRouter = express.Router ()
const CONFIG = require ('./config')
async function getAccessToken () {
const formData = new FormData ()
formData.append ('grant_type', 'client_credentials')
formData.append ('client_id', CONFIG.CLIENT_ID)
formData.append ('client_secret', CONFIG.CLIENT_SECRET)
try {
const response = await axios.post (
'https://open.plantbook.io/api/v1/token/',
formData,
{
headers: {'Content-Type': 'multipart/form-data'},
}
)
if (response.data && response.data.access_token) {
console.log ('Access token retrieved:', response.data.access_token)
return response.data.access_token
} else {
console.error ('Error: access_token not found in response')
return null
}
} catch (error) {
console.error (
'Error fetching access token:',
error.response ? error.response.data : error.message
)
return null
}
}
async function fetchPlantData (plantId) {
const accessToken = await getAccessToken ()
if (!accessToken) {
return null
}
try {
const response = await axios.get (
`https://open.plantbook.io/api/v1/plant/detail/${encodeURIComponent (plantId)}/`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)
return response.data
} catch (error) {
console.error (
'Error fetching plant data:',
error.response ? error.response.data : error.message
)
return null
}
}
plantsRouter.get ('/list', async (req, res) => {
const accessToken = await getAccessToken ()
if (!accessToken) {
res.status (500).send ({message: 'Error obtaining access token'})
return
}
try {
const alias = req.query.alias || 'monstera'
const response = await axios.get (
'https://open.plantbook.io/api/v1/plant/search',
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
params: {
alias: alias,
},
}
)
const plantsList = response.data.results
const plants = await Promise.all (
plantsList.map (async plant => {
const plantDetails = await fetchPlantData (plant.pid)
return {
id: plant.pid,
alias: plant.alias,
display_name: plant.display_name,
image_url: plantDetails ? plantDetails.image_url : null,
max_light: plantDetails ? plantDetails.max_light : null,
min_light: plantDetails ? plantDetails.min_light : null,
max_temp: plantDetails ? plantDetails.max_temp : null,
min_temp: plantDetails ? plantDetails.min_temp : null,
max_env_humid: plantDetails ? plantDetails.max_env_humid : null,
min_env_humid: plantDetails ? plantDetails.min_env_humid : null,
max_soil_moist: plantDetails ? plantDetails.max_soil_moist : null,
min_soil_moist: plantDetails ? plantDetails.min_soil_moist : null,
max_soil_ec: plantDetails ? plantDetails.max_soil_ec : null,
min_soil_ec: plantDetails ? plantDetails.min_soil_ec : null,
}
})
)
res.send ({results: plants})
} catch (error) {
console.error (
'Error fetching plant list:',
error.response ? error.response.data : error.message
)
res.status (500).send ({message: 'Error fetching plant list'})
}
})
plantsRouter.get ('/:id', async (req, res) => {
const plantId = req.params.id
const plantData = await fetchPlantData (plantId)
if (plantData) {
const detailedPlantData = {
id: plantData.pid,
display_name: plantData.display_name,
alias: plantData.alias,
max_light: plantData.max_light,
min_light: plantData.min_light,
max_temperature: plantData.max_temp,
min_temperature: plantData.min_temp,
max_humidity: plantData.max_env_humid,
min_humidity: plantData.min_env_humid,
max_soil_moisture: plantData.max_soil_moist,
min_soil_moisture: plantData.min_soil_moist,
max_soil_ec: plantData.max_soil_ec,
min_soil_ec: plantData.min_soil_ec,
image_url: plantData.image_url,
}
res.send (detailedPlantData)
} else {
res.status (404).send ({message: 'Plant not found'})
}
})
module.exports = plantsRouter

View File

@@ -0,0 +1,42 @@
const express = require('express')
const plantsRouter = express.Router()
const plants = [
{
name: "Rose",
image: "https://ervanarium.com.br/wp-content/uploads/2019/03/cactus-3142589_1920.jpg",
frequency: 3,
startDate: "2024-10-09",
},
{
name: "Sunflower",
image: "https://avatars.mds.yandex.net/i?id=31da587c9aabc83ad3615023f91d7284781be06c-10701700-images-thumbs&n=13",
frequency: 3,
startDate: "2024-10-05",
},
]
const calculateWateringDates = (startDate, frequency) => {
const dates = []
const start = new Date(startDate)
for (let i = 0; i < 30; i += frequency) {
const nextWateringDate = new Date(start)
nextWateringDate.setDate(start.getDate() + i)
dates.push(nextWateringDate.toISOString().split('T')[0])
}
return dates
}
const plantsWithDates = plants.map(plant => ({
...plant,
wateringDates: calculateWateringDates(plant.startDate, plant.frequency),
}))
plantsRouter.get('/api/plants', (req, res) => {
res.json(plantsWithDates)
})
module.exports = plantsRouter

View File

@@ -0,0 +1,73 @@
const authRouter = require('express').Router()
// For creating tokens
const jwt = require('jsonwebtoken')
const { TOKEN_KEY } = require('../key')
module.exports = authRouter
const { addUserToDB, getUserFromDB } = require('../db')
// Get a user by its id
authRouter.get('/:id', (req, res) => {
const user = getUserFromDB(req.params.id)
if (user) {
res.status(200).send({user})
} else {
res.status(404).send({message: 'User was not found'})
}
})
// For login (authorization)
authRouter.post('/login', (req, res) => {
const { name, password } = req.body
const user = getUserFromDB(name)
// Invalid identification
if (!user) {
res.status(401).send({message: 'Invalid credentials (id)'})
return
}
// Invalid authentication
if (!password || password !== user.password) {
res.status(401).send({message: 'Invalid credentials (password)'})
return
}
// Now, authorization
const token = jwt.sign({id: name}, TOKEN_KEY, {
expiresIn: '1h'
})
res.status(200).send({token})
})
authRouter.post('/reg', (req, res) => {
const { name, password, nickname } = req.body
const user = getUserFromDB(name)
// Invalid identification
if (user) {
res.status(409).send({message: 'Such id already exists'})
return
}
if (!name || !password || !nickname) {
res.status(401).send({message: 'Empty or invalid fields'})
return
}
// Add to 'DB'
const newUser = {id: name, password: password, nickname: nickname}
addUserToDB(newUser)
res.status(200).send({user: newUser})
})

View File

@@ -0,0 +1,52 @@
[
{
"nickname": "Alice Johnson",
"password": "1234",
"id": "alice"
},
{
"nickname": "Bob Smith",
"password": "1234",
"id": "bobsm"
},
{
"nickname": "Charlie Brown",
"password": "1234",
"id": "charl"
},
{
"nickname": "David Clark",
"password": "1234",
"id": "david"
},
{
"nickname": "Eve Adams",
"password": "1234",
"id": "evead"
},
{
"nickname": "Frank Wright",
"password": "1234",
"id": "frank"
},
{
"nickname": "Grace Lee",
"password": "1234",
"id": "grace"
},
{
"nickname": "Hannah Scott",
"password": "1234",
"id": "hanna"
},
{
"nickname": "Ian Davis",
"password": "1234",
"id": "ianda"
},
{
"nickname": "Jill Thompson",
"password": "1234",
"id": "jillt"
}
]

View File

@@ -0,0 +1,64 @@
const changeRouter = require('express').Router()
module.exports = changeRouter
const { getUserFromDB, deleteUserFromDB, addUserToDB } = require('../db')
changeRouter.post('/nickname', (req, res) => {
const { id, newNickname } = req.body
const user = getUserFromDB(id)
// Invalid identification
if (!user) {
res.status(401).send({message: 'Invalid credentials (id)'})
return
}
const updatedUser = {
"nickname": newNickname,
"password": user.password,
"id": user.id
}
// Delete the old one
deleteUserFromDB(id)
// Insert updated
addUserToDB(updatedUser)
res.status(200).send({})
})
changeRouter.post('/password', (req, res) => {
const { id, newPassword } = req.body
const user = getUserFromDB(id)
// Invalid identification
if (!user) {
res.status(401).send({message: 'Invalid credentials (id)'})
return
}
// Delete the old one
deleteUserFromDB(id)
// Insert updated
const updatedUser = {
"nickname": user.nickname,
"password": newPassword,
"id": user.id
}
addUserToDB(updatedUser)
res.status(200).send({})
})
changeRouter.delete('/:id', (req, res) => {
const { id } = req.params
deleteUserFromDB(id)
})

View File

@@ -0,0 +1,662 @@
[
{
"id1": "alice",
"id2": "bobsm",
"messages": [
{
"data": "Hello Bob!",
"senderId": "alice",
"recipientId": "bobsm",
"timestamp": "09.10.2024 07:00:00"
},
{
"data": "Hey Alice, how are you?",
"senderId": "bobsm",
"recipientId": "alice",
"timestamp": "09.10.2024 07:05:00"
},
{
"data": "I'm good, thanks for asking.",
"senderId": "alice",
"recipientId": "bobsm",
"timestamp": "09.10.2024 07:10:00"
},
{
"data": "Glad to hear!",
"senderId": "bobsm",
"recipientId": "alice",
"timestamp": "09.10.2024 07:15:00"
}
]
},
{
"id1": "alice",
"id2": "charl",
"messages": [
{
"data": "How's the project going?",
"senderId": "alice",
"recipientId": "charl",
"timestamp": "09.10.2024 07:20:00"
},
{
"data": "It's coming along, almost done!",
"senderId": "charl",
"recipientId": "alice",
"timestamp": "09.10.2024 07:25:00"
},
{
"data": "That's great to hear!",
"senderId": "alice",
"recipientId": "charl",
"timestamp": "09.10.2024 07:30:00"
},
{
"data": "Thanks for checking in.",
"senderId": "charl",
"recipientId": "alice",
"timestamp": "09.10.2024 07:35:00"
}
]
},
{
"id1": "alice",
"id2": "david",
"messages": [
{
"data": "Did you get the files?",
"senderId": "david",
"recipientId": "alice",
"timestamp": "09.10.2024 07:40:00"
},
{
"data": "Yes, I did. Thank you!",
"senderId": "alice",
"recipientId": "david",
"timestamp": "09.10.2024 07:45:00"
},
{
"data": "You're welcome.",
"senderId": "david",
"recipientId": "alice",
"timestamp": "09.10.2024 07:50:00"
},
{
"data": "Let me know if you need anything else.",
"senderId": "alice",
"recipientId": "david",
"timestamp": "09.10.2024 07:55:00"
}
]
},
{
"id1": "alice",
"id2": "frank",
"messages": [
{
"data": "Can you review this document for me?",
"senderId": "alice",
"recipientId": "frank",
"timestamp": "09.10.2024 08:20:00"
},
{
"data": "Sure, I'll take a look.",
"senderId": "frank",
"recipientId": "alice",
"timestamp": "09.10.2024 08:25:00"
},
{
"data": "Thanks, much appreciated!",
"senderId": "alice",
"recipientId": "frank",
"timestamp": "09.10.2024 08:30:00"
},
{
"data": "No problem.",
"senderId": "frank",
"recipientId": "alice",
"timestamp": "09.10.2024 08:35:00"
}
]
},
{
"id1": "alice",
"id2": "grace",
"messages": [
{
"data": "Hey Grace, let's meet up for coffee!",
"senderId": "alice",
"recipientId": "grace",
"timestamp": "09.10.2024 08:40:00"
},
{
"data": "Sounds good, when are you free?",
"senderId": "grace",
"recipientId": "alice",
"timestamp": "09.10.2024 08:45:00"
},
{
"data": "How about tomorrow afternoon?",
"senderId": "alice",
"recipientId": "grace",
"timestamp": "09.10.2024 08:50:00"
},
{
"data": "Works for me!",
"senderId": "grace",
"recipientId": "alice",
"timestamp": "09.10.2024 08:55:00"
}
]
},
{
"id1": "alice",
"id2": "hanna",
"messages": [
{
"data": "Hannah, do you have a moment?",
"senderId": "alice",
"recipientId": "hanna",
"timestamp": "09.10.2024 09:00:00"
},
{
"data": "Sure, what's up?",
"senderId": "hanna",
"recipientId": "alice",
"timestamp": "09.10.2024 09:05:00"
},
{
"data": "Just wanted to check on the report.",
"senderId": "alice",
"recipientId": "hanna",
"timestamp": "09.10.2024 09:10:00"
},
{
"data": "I'll send it soon.",
"senderId": "hanna",
"recipientId": "alice",
"timestamp": "09.10.2024 09:15:00"
}
]
},
{
"id1": "alice",
"id2": "ianda",
"messages": [
{
"data": "Ian, have you completed the review?",
"senderId": "alice",
"recipientId": "ianda",
"timestamp": "09.10.2024 09:20:00"
},
{
"data": "Yes, I sent my feedback.",
"senderId": "ianda",
"recipientId": "alice",
"timestamp": "09.10.2024 09:25:00"
},
{
"data": "Thanks for that.",
"senderId": "alice",
"recipientId": "ianda",
"timestamp": "09.10.2024 09:30:00"
},
{
"data": "Anytime!",
"senderId": "ianda",
"recipientId": "alice",
"timestamp": "09.10.2024 09:35:00"
}
]
},
{
"id1": "alice",
"id2": "jillt",
"messages": [
{
"data": "Jill, let's schedule a catch-up meeting.",
"senderId": "alice",
"recipientId": "jillt",
"timestamp": "09.10.2024 09:40:00"
},
{
"data": "Sounds good, when works for you?",
"senderId": "jillt",
"recipientId": "alice",
"timestamp": "09.10.2024 09:45:00"
},
{
"data": "Tomorrow afternoon?",
"senderId": "alice",
"recipientId": "jillt",
"timestamp": "09.10.2024 09:50:00"
},
{
"data": "That works for me!",
"senderId": "jillt",
"recipientId": "alice",
"timestamp": "09.10.2024 09:55:00"
}
]
},
{
"id1": "alice",
"id2": "evead",
"messages": [
{
"data": "Eve, did you send the schedule?",
"senderId": "alice",
"recipientId": "evead",
"timestamp": "09.10.2024 10:00:00"
},
{
"data": "Yes, just sent it.",
"senderId": "evead",
"recipientId": "alice",
"timestamp": "09.10.2024 10:05:00"
},
{
"data": "Thanks, much appreciated!",
"senderId": "alice",
"recipientId": "evead",
"timestamp": "09.10.2024 10:10:00"
},
{
"data": "No problem!",
"senderId": "evead",
"recipientId": "alice",
"timestamp": "09.10.2024 10:15:00"
}
]
},
{
"id1": "bobsm",
"id2": "charl",
"messages": [
{
"data": "How's everything going?",
"senderId": "bobsm",
"recipientId": "charl",
"timestamp": "09.10.2024 10:20:00"
},
{
"data": "Pretty good, how about you?",
"senderId": "charl",
"recipientId": "bobsm",
"timestamp": "09.10.2024 10:25:00"
},
{
"data": "Can't complain!",
"senderId": "bobsm",
"recipientId": "charl",
"timestamp": "09.10.2024 10:30:00"
},
{
"data": "Glad to hear that.",
"senderId": "charl",
"recipientId": "bobsm",
"timestamp": "09.10.2024 10:35:00"
}
]
},
{
"id1": "bobsm",
"id2": "david",
"messages": [
{
"data": "Can you send the report?",
"senderId": "bobsm",
"recipientId": "david",
"timestamp": "09.10.2024 10:40:00"
},
{
"data": "I'll send it in an hour.",
"senderId": "david",
"recipientId": "bobsm",
"timestamp": "09.10.2024 10:45:00"
},
{
"data": "Perfect, thanks.",
"senderId": "bobsm",
"recipientId": "david",
"timestamp": "09.10.2024 10:50:00"
},
{
"data": "No problem.",
"senderId": "david",
"recipientId": "bobsm",
"timestamp": "09.10.2024 10:55:00"
}
]
},
{
"id1": "charl",
"id2": "evead",
"messages": [
{
"data": "Hey Eve, how's it going?",
"senderId": "charl",
"recipientId": "evead",
"timestamp": "09.10.2024 11:00:00"
},
{
"data": "Good, how about you?",
"senderId": "evead",
"recipientId": "charl",
"timestamp": "09.10.2024 11:05:00"
},
{
"data": "Can't complain!",
"senderId": "charl",
"recipientId": "evead",
"timestamp": "09.10.2024 11:10:00"
},
{
"data": "Glad to hear.",
"senderId": "evead",
"recipientId": "charl",
"timestamp": "09.10.2024 11:15:00"
}
]
},
{
"id1": "charl",
"id2": "frank",
"messages": [
{
"data": "Do you have time to talk today?",
"senderId": "charl",
"recipientId": "frank",
"timestamp": "09.10.2024 11:20:00"
},
{
"data": "I have a meeting, but I can chat afterward.",
"senderId": "frank",
"recipientId": "charl",
"timestamp": "09.10.2024 11:25:00"
},
{
"data": "Sounds good.",
"senderId": "charl",
"recipientId": "frank",
"timestamp": "09.10.2024 11:30:00"
},
{
"data": "I'll message you after.",
"senderId": "frank",
"recipientId": "charl",
"timestamp": "09.10.2024 11:35:00"
}
]
},
{
"id1": "david",
"id2": "frank",
"messages": [
{
"data": "Did you review the document?",
"senderId": "david",
"recipientId": "frank",
"timestamp": "09.10.2024 11:40:00"
},
{
"data": "Yes, it's all good.",
"senderId": "frank",
"recipientId": "david",
"timestamp": "09.10.2024 11:45:00"
},
{
"data": "Great, thanks for the quick turnaround!",
"senderId": "david",
"recipientId": "frank",
"timestamp": "09.10.2024 11:50:00"
},
{
"data": "No worries!",
"senderId": "frank",
"recipientId": "david",
"timestamp": "09.10.2024 11:55:00"
}
]
},
{
"id1": "david",
"id2": "grace",
"messages": [
{
"data": "Grace, can you send the updated schedule?",
"senderId": "david",
"recipientId": "grace",
"timestamp": "09.10.2024 12:00:00"
},
{
"data": "Yes, I'll send it in a few minutes.",
"senderId": "grace",
"recipientId": "david",
"timestamp": "09.10.2024 12:05:00"
},
{
"data": "Thanks, much appreciated!",
"senderId": "david",
"recipientId": "grace",
"timestamp": "09.10.2024 12:10:00"
},
{
"data": "You're welcome!",
"senderId": "grace",
"recipientId": "david",
"timestamp": "09.10.2024 12:15:00"
}
]
},
{
"id1": "frank",
"id2": "grace",
"messages": [
{
"data": "How are you today?",
"senderId": "frank",
"recipientId": "grace",
"timestamp": "09.10.2024 12:20:00"
},
{
"data": "I'm doing well, thanks for asking.",
"senderId": "grace",
"recipientId": "frank",
"timestamp": "09.10.2024 12:25:00"
},
{
"data": "Glad to hear that.",
"senderId": "frank",
"recipientId": "grace",
"timestamp": "09.10.2024 12:30:00"
},
{
"data": "How about you?",
"senderId": "grace",
"recipientId": "frank",
"timestamp": "09.10.2024 12:35:00"
}
]
},
{
"id1": "frank",
"id2": "hanna",
"messages": [
{
"data": "Did you attend the meeting?",
"senderId": "frank",
"recipientId": "hanna",
"timestamp": "09.10.2024 12:40:00"
},
{
"data": "Yes, it was productive.",
"senderId": "hanna",
"recipientId": "frank",
"timestamp": "09.10.2024 12:45:00"
},
{
"data": "Good to hear!",
"senderId": "frank",
"recipientId": "hanna",
"timestamp": "09.10.2024 12:50:00"
},
{
"data": "Indeed, lots to follow up on.",
"senderId": "hanna",
"recipientId": "frank",
"timestamp": "09.10.2024 12:55:00"
}
]
},
{
"id1": "grace",
"id2": "hanna",
"messages": [
{
"data": "Can we meet later today?",
"senderId": "grace",
"recipientId": "hanna",
"timestamp": "09.10.2024 01:00:00"
},
{
"data": "Sure, what's a good time?",
"senderId": "hanna",
"recipientId": "grace",
"timestamp": "09.10.2024 01:05:00"
},
{
"data": "How about 3?",
"senderId": "grace",
"recipientId": "hanna",
"timestamp": "09.10.2024 01:10:00"
},
{
"data": "Works for me.",
"senderId": "hanna",
"recipientId": "grace",
"timestamp": "09.10.2024 01:15:00"
}
]
},
{
"id1": "grace",
"id2": "ianda",
"messages": [
{
"data": "Ian, did you get the message I sent?",
"senderId": "grace",
"recipientId": "ianda",
"timestamp": "09.10.2024 01:20:00"
},
{
"data": "Yes, I'll respond soon.",
"senderId": "ianda",
"recipientId": "grace",
"timestamp": "09.10.2024 01:25:00"
},
{
"data": "Thanks, appreciate it!",
"senderId": "grace",
"recipientId": "ianda",
"timestamp": "09.10.2024 01:30:00"
},
{
"data": "You're welcome!",
"senderId": "ianda",
"recipientId": "grace",
"timestamp": "09.10.2024 01:35:00"
}
]
},
{
"id1": "hanna",
"id2": "ianda",
"messages": [
{
"data": "Ian, do you have a minute?",
"senderId": "hanna",
"recipientId": "ianda",
"timestamp": "09.10.2024 01:40:00"
},
{
"data": "Yes, what do you need?",
"senderId": "ianda",
"recipientId": "hanna",
"timestamp": "09.10.2024 01:45:00"
},
{
"data": "Just a quick update on the project.",
"senderId": "hanna",
"recipientId": "ianda",
"timestamp": "09.10.2024 01:50:00"
},
{
"data": "I'll email you the details.",
"senderId": "ianda",
"recipientId": "hanna",
"timestamp": "09.10.2024 01:55:00"
}
]
},
{
"id1": "hanna",
"id2": "jillt",
"messages": [
{
"data": "Jill, can we talk tomorrow?",
"senderId": "hanna",
"recipientId": "jillt",
"timestamp": "09.10.2024 02:00:00"
},
{
"data": "Yes, I'm free after 2.",
"senderId": "jillt",
"recipientId": "hanna",
"timestamp": "09.10.2024 02:05:00"
},
{
"data": "Perfect, see you then.",
"senderId": "hanna",
"recipientId": "jillt",
"timestamp": "09.10.2024 02:10:00"
},
{
"data": "Looking forward to it.",
"senderId": "jillt",
"recipientId": "hanna",
"timestamp": "09.10.2024 02:15:00"
}
]
},
{
"id1": "ianda",
"id2": "jillt",
"messages": [
{
"data": "Jill, I have the files you requested.",
"senderId": "ianda",
"recipientId": "jillt",
"timestamp": "09.10.2024 02:20:00"
},
{
"data": "Thanks, please send them over.",
"senderId": "jillt",
"recipientId": "ianda",
"timestamp": "09.10.2024 02:25:00"
},
{
"data": "I'll send them right now.",
"senderId": "ianda",
"recipientId": "jillt",
"timestamp": "09.10.2024 02:30:00"
},
{
"data": "Great, thanks again!",
"senderId": "jillt",
"recipientId": "ianda",
"timestamp": "09.10.2024 02:35:00"
}
]
}
]

View File

@@ -0,0 +1,86 @@
const chatRouter = require('express').Router()
module.exports = chatRouter
const { getChatFromDB, getUsersChats, addChatToDB, getUserFromDB,
addMessageToChat} = require('../db')
chatRouter.get('/item/:id1/:id2', (req, res) => {
const { id1, id2 } = req.params
if (id1 === id2) {
res.status(400).send({message: 'Ids should be different'})
return
}
const chat = getChatFromDB(id1, id2)
if (chat) {
res.status(200).send({chat})
} else {
res.status(404).send({message: 'Chat was not found'})
}
})
chatRouter.post('/item/:id1/:id2', (req, res) => {
const { id1, id2 } = req.params
if (id1 === id2) {
res.status(400).send({message: 'Ids should be different'})
return
}
const chat = getChatFromDB(id1, id2)
if (chat) {
// Chat already exists
res.status(200).send({chat})
} else {
if (!getUserFromDB(id1) || !getUserFromDB(id2)) {
res.status(404).send({message: 'Such interlocutor does not exist'})
} else {
// Creating new chat
const newChat = {
id1: id1,
id2: id2,
messages: []
}
addChatToDB(newChat)
res.status(200).send({newChat})
}
}
})
chatRouter.get('/list/:id', (req, res) => {
const { id } = req.params
const userChats = getUsersChats(id)
if (!userChats) {
res.status(404).send({message: 'Error with retrieving chats'})
} else {
res.status(200).send({chats: userChats})
}
})
chatRouter.post('/message/:sender/:receiver', (req, res) => {
const { sender, receiver } = req.params
const { message } = req.body
const chat = getChatFromDB(sender, receiver)
if (!chat) {
// Chat already exists
res.status(400).send({message: "Such chat does not exist"})
} else {
if (!getUserFromDB(sender) || !getUserFromDB(receiver)) {
res.status(404).send({message: 'Such people do not exist'})
} else {
// Add new message
addMessageToChat(chat, message)
res.status(200).send({})
}
}
})

View File

@@ -0,0 +1,74 @@
// Read already defined users (pseudo-DB)
const users = require('./auth/users.json')
const chats = require('./chat/chats.json')
const getUserFromDB = (userID) => {
if (!userID) {return false}
// Accessing 'DB'
const user = users.find((user) => user.id === userID)
if (user) {
return user
} else {
return false
}
}
const deleteUserFromDB = (userID) => {
const index = users.findIndex(item => item.id === userID)
if (index !== -1) {
users.splice(index, 1)
}
}
const addUserToDB = (user) => {
users.push(user)
}
const getChatFromDB = (firstID, secondID) => {
if (!firstID || !secondID) {return false}
// Accessing 'DB'
const chat = chats.find((item) =>
(item.id1 === firstID && item.id2 === secondID) || (item.id1 === secondID && item.id2 === firstID))
if (chat) {
return chat
} else {
return false
}
}
const getUsersChats = (userID) => {
if (!userID) {return false}
const userChats = chats.filter((chat) => (chat.id1 === userID || chat.id2 === userID))
if (userChats) {
return userChats
} else {
return false
}
}
const addMessageToChat = (chat, msg) => {
chat.messages.push(msg)
}
const deleteChatFromDB = (firstID, secondID) => {
const index = chats.findIndex(item =>
(item.id1 === firstID && item.id2 === secondID) || (item.id1 === secondID && item.id2 === firstID))
if (index !== -1) {
chats.splice(index, 1)
}
}
const addChatToDB = (chat) => {
chats.push(chat)
}
module.exports = {users, chats, getUserFromDB, getChatFromDB, addUserToDB,
deleteUserFromDB, addChatToDB, deleteChatFromDB, getUsersChats, addMessageToChat}

View File

@@ -0,0 +1,17 @@
const changeRouter = require("./change")
const authRouter = require("./auth")
const chatRouter = require("./chat")
const router = require('express').Router()
const delay = require('./middlewares/delay')
const verify = require('./middlewares/verify')
module.exports = router
// router.use(delay(300));
// router.use('/books', delay, booksRouter);
router.use('/auth', authRouter)
router.use('/change', verify, changeRouter)
router.use('/chat', verify, chatRouter)

View File

@@ -0,0 +1,3 @@
const TOKEN_KEY = '5frv12e4few3r'
module.exports = { TOKEN_KEY }

View File

@@ -0,0 +1,5 @@
const delay = (ms = 1000) => (req, res, next) => {
setTimeout(next, ms)
}
module.exports = delay

View File

@@ -0,0 +1,22 @@
const jwt = require('jsonwebtoken')
const { TOKEN_KEY } = require('../key')
function verifyToken(req, res, next) {
const token = req.headers['authorization']?.split(' ')[1]
if (!token) {
return res.status(401).send({ message: 'No token provided' })
}
// Verify token
jwt.verify(token, TOKEN_KEY, (err, decoded) => {
if (err) {
return res.status(401).send({ message: 'Unauthorized' })
}
next() // Proceed to the next middleware or route
})
}
module.exports = verifyToken

View File

@@ -0,0 +1,10 @@
const { Router } = require('express')
const router = Router()
router.use('/enterfront', require('./enterfront/index'))
router.use('/cats', require('./cats/index'))
router.use('/ecliptica', require('./ecliptica/index'))
module.exports = router

View File

@@ -1,19 +0,0 @@
const router = require('express').Router()
const first = router.get('/first', (req, res) => {
res.send({
success: true,
warnings: [{
title: 'Внимание',
text: 'Данный api создан для примера!',
}],
})
/**
* Этот эндпоинт будет доступен по адресу http://89.223.91.151:8080/multystub/example/first
*/
})
router.use('/example-api', first)
module.exports = router

View File

@@ -0,0 +1,23 @@
const Router = require('express').Router;
const router = Router()
const timer = (_req, _res, next) => {
setTimeout(() => next(), 500)
}
router.use(timer)
router.get(
'/active',
(req, res) =>
res.send(require(`./json/active-order-success.json`))
)
router.get(
'/history',
(req, res) =>
res.send(require(`./json/history-success.json`))
)
module.exports = router

View File

@@ -0,0 +1,6 @@
{
"success": false,
"errors": [
"Не получилось получить заказ с id = 123123"
]
}

View File

@@ -0,0 +1,46 @@
{
"success": true,
"body": {
"id": "1212",
"createdAt": "2024-11-29 13:24:08",
"updatedAt": "2024-11-29 13:24:10",
"status": "in_progress",
"timeline": [
{
"color": "gray",
"children": "Москва"
},
{
"children": "Владимир, 25.10.2024 18:02"
},
{
"children": "Нижний новгород, 25.10.2024 12:21"
},
{
"children": "Казань, 25.10.2024 03:00"
}
],
"statistics": [
{
"key": "address-from",
"value": "г. Казань, ул Ильи Давыдова, стр. 87а"
},
{
"key": "address-to",
"value": "г. Москва, ул. Тверская, д. 12"
},
{
"key": "delivery",
"value": "26.10.2024 23:08"
},
{
"key": "cost",
"value": "100500₽"
},
{
"key": "customer",
"value": "ООО \"Сидоров\""
}
]
}
}

View File

@@ -0,0 +1,9 @@
{
"success": false,
"body": {
"history": []
},
"errors": [
"Что-то пошло не так"
]
}

View File

@@ -0,0 +1,187 @@
{
"success": true,
"body": {
"history": [
{
"key": 1,
"number": "12324",
"cost": 15000,
"dateEnd": 1685998800000,
"customer": "ООО \"Иванов\"",
"cityFrom": "Псков",
"cityTo": "Мурманск"
},
{
"key": 2,
"number": "12323",
"cost": 10000,
"dateEnd": 1686085200000,
"customer": "ООО \"Попов\"",
"cityFrom": "Астрахань",
"cityTo": "Ставрополь"
},
{
"key": 3,
"number": "12325",
"cost": 12000,
"dateEnd": 1686171600000,
"customer": "ООО \"Сидоров\"",
"cityFrom": "Москва",
"cityTo": "Казань"
},
{
"key": 4,
"number": "12326",
"cost": 9000,
"dateEnd": 1686258000000,
"customer": "ООО \"Петров\"",
"cityFrom": "Новосибирск",
"cityTo": "Томск"
},
{
"key": 5,
"number": "12327",
"cost": 13000,
"dateEnd": 1686344400000,
"customer": "ООО \"Смирнов\"",
"cityFrom": "Омск",
"cityTo": "Тюмень"
},
{
"key": 6,
"number": "12328",
"cost": 14000,
"dateEnd": 1686430800000,
"customer": "ООО \"Кузнецов\"",
"cityFrom": "Саратов",
"cityTo": "Самара"
},
{
"key": 7,
"number": "12329",
"cost": 11000,
"dateEnd": 1686517200000,
"customer": "ООО \"Васильев\"",
"cityFrom": "Краснодар",
"cityTo": "Сочи"
},
{
"key": 8,
"number": "12330",
"cost": 8000,
"dateEnd": 1686603600000,
"customer": "ООО \"Зайцев\"",
"cityFrom": "Пермь",
"cityTo": "Екатеринбург"
},
{
"key": 9,
"number": "12331",
"cost": 7000,
"dateEnd": 1686690000000,
"customer": "ООО \"Морозов\"",
"cityFrom": "Челябинск",
"cityTo": "Уфа"
},
{
"key": 10,
"number": "12332",
"cost": 16000,
"dateEnd": 1686776400000,
"customer": "ООО \"Павлов\"",
"cityFrom": "Волгоград",
"cityTo": "Ростов-на-Дону"
},
{
"key": 11,
"number": "12333",
"cost": 9000,
"dateEnd": 1686862800000,
"customer": "ООО \"Фролов\"",
"cityFrom": "Калининград",
"cityTo": "Смоленск"
},
{
"key": 12,
"number": "12334",
"cost": 15500,
"dateEnd": 1686949200000,
"customer": "ООО \"Богданов\"",
"cityFrom": "Нижний Новгород",
"cityTo": "Киров"
},
{
"key": 13,
"number": "12335",
"cost": 13500,
"dateEnd": 1687035600000,
"customer": "ООО \"Григорьев\"",
"cityFrom": "Тверь",
"cityTo": "Ярославль"
},
{
"key": 14,
"number": "12336",
"cost": 12500,
"dateEnd": 1687122000000,
"customer": "ООО \"Дмитриев\"",
"cityFrom": "Сургут",
"cityTo": "Ханты-Мансийск"
},
{
"key": 15,
"number": "12337",
"cost": 14500,
"dateEnd": 1687208400000,
"customer": "ООО \"Михайлов\"",
"cityFrom": "Иркутск",
"cityTo": "Братск"
},
{
"key": 16,
"number": "12338",
"cost": 10500,
"dateEnd": 1687294800000,
"customer": "ООО \"Романов\"",
"cityFrom": "Владивосток",
"cityTo": "Хабаровск"
},
{
"key": 17,
"number": "12339",
"cost": 9500,
"dateEnd": 1687381200000,
"customer": "ООО \"Федоров\"",
"cityFrom": "Якутск",
"cityTo": "Магадан"
},
{
"key": 18,
"number": "12340",
"cost": 8500,
"dateEnd": 1687467600000,
"customer": "ООО \"Жуков\"",
"cityFrom": "Симферополь",
"cityTo": "Севастополь"
},
{
"key": 19,
"number": "12341",
"cost": 11500,
"dateEnd": 1687554000000,
"customer": "ООО \"Николаев\"",
"cityFrom": "Барнаул",
"cityTo": "Бийск"
},
{
"key": 20,
"number": "12342",
"cost": 10000,
"dateEnd": 1687640400000,
"customer": "ООО \"Орлов\"",
"cityFrom": "Кемерово",
"cityTo": "Новокузнецк"
}
]
}
}

View File

@@ -0,0 +1,5 @@
const router = require('express').Router();
router.use('/performer', require('./dashboard-performer'))
module.exports = router;

View File

@@ -0,0 +1,103 @@
const router = require('express').Router();
//const loginMiddleware = require('../middleware/login-middleware');
// First page
router.get('/getInfoAboutKazan', (request, response) => {
response.send(require('./json/first/info-about-kazan/success.json'))
})
router.get('/getNews', (request, response) => {
response.send(require('./json/first/news/success.json'))
})
// Sport page
router.get('/getSportData', (request, response) => {
response.send(require('./json/sport/sport-data.json'))
})
// Places page
router.get('/getPlacesData', (request, response) => {
response.send(require('./json/places/places-data.json'))
})
// Transport page
router.get('/getInfoAboutTransportPage', (request, response) => {
response.send(require('./json/transport/info-about-page.json'))
})
router.get('/getBus', (request, response) => {
response.send(require('./json/transport/bus-numbers.json'))
})
router.get('/getTral', (request, response) => {
response.send(require('./json/transport/tral-numbers.json'))
})
router.get('/getEvents', (request, response) => {
response.send(require('./json/transport/events-calendar.json'))
})
router.get('/getTripSchedule', (request, response) => {
response.send(require('./json/transport/trip-schedule/success.json'))
})
router.get('/getInfoAboutInstitutions', (request, response) => {
response.send(require('./json/transport/info-about-institutions.json'))
})
// Education page
router.get('/getInfoAboutKFU', (request, response) => {
response.send(require('./json/education/info-about-kfu.json'))
})
// Login
router.post('/entrance', (request, response) => {
const { email, password } = request.body.entranceData;
try {
const users = require('../json/users-information/success.json');
const user = users.data.find(user => user.email === email && user.password === password);
if (!user) {
return response.status(401).send('Неверные учетные данные');
}
const responseObject = {
email: user.email,
}
if (user.cardId){
responseObject.cardId = user.cardId || "";
}
return response.json(responseObject);
} catch (error) {
console.error('Ошибка чтения файла:', error);
response.status(500).send('Внутренняя ошибка сервера');
}
})
router.post('/registration', async (request, response) => {
const { email, password, confirmPassword } = request.body.registerData;
try {
if (password !== confirmPassword) {
return response.status(400).send('Пароли не совпадают!');
}
const users = require('../json/users-information/success.json');
const existingUser = users.data.find(user => user.email === email);
if (existingUser) {
return response.status(400).send('Пользователь с такой почтой уже существует!');
}
return response.json({ email: email});
} catch (error) {
console.error('Ошибка регистрации пользователя:', error);
response.status(500).send('Внутренняя ошибка сервера');
}
});
module.exports = router;

View File

@@ -0,0 +1,4 @@
[
"Казанский (Приволжский) федеральный университет (полное наименование — федеральное государственное автономное образовательное учреждение высшего образования «Казанский (Приволжский) федеральный университет», тат. Казан (Идел буе) федераль университеты) — высшее учебное заведение в Казани, один из старейших российских университетов (основан в 1804 году) и один из десяти федеральных университетов (с 2010 года).",
"В состав университетского учебно-научного комплекса входят научная библиотека, научно-исследовательские институты химии, математики и механики, 7 музеев, ботанический сад, астрономические обсерватории, центр информационных технологий, издательство, центр и лаборатория оперативной полиграфии, культурно-спортивный комплекс, спортивно-оздоровительный лагерь и другие подразделения."
]

View File

@@ -0,0 +1,3 @@
[
"Казань — древний город с богатой историей, где слились воедино культуры Востока и Запада. Подобно драгоценному камню, сияющему в ожерелье городов России, Казань покоряет своей красотой и многообразием. Её красивая архитектура и гостеприимные жители создают уютную атмосферу, привлекающую туристов со всего мира."
]

View File

@@ -0,0 +1,32 @@
[
{
"id": "1",
"image": "new1",
"title": "На предприятиях в Казани объявили эвакуацию",
"text": "В Казани на некоторых предприятиях объявлена необходимость эвакуации. Об этом сообщили в пресс-службе главы Татарстана. «В отдельных районах Казани на предприятиях объявлена необходимость эвакуации», — сообщили в пресс-службе главы Татарстана. Информацию передает ТАСС. Telegram-канал Shot пишет об эвакуации сотрудников химической компании «Казаньоргсинтез»."
},
{
"id": "2",
"image": "new2",
"title": "В Казани обсудили взаимодействие детей с гаджетами",
"text": "В Казани состоялась конференция, посвящённая проблемам воспитания в эпоху технического прогресса. Участники встречи, среди которых психологи, педагоги и родители, обсудили методы противодействия гаджетозависимости и возможности использования технологий для развития молодёжи. «Ничего плохого нет в том, что ребёнок сидит в телефоне. Главное — правильно его направить», - поделилась своим опытом Альфия Валеева, педагог с 16-летним стажем."
},
{
"id": "3",
"image": "new3",
"title": "Казанский УНИКС проиграл ЦСКА, счёт в серии 0-3",
"text": "В третьем матче финала Единой лиги ВТБ ЦСКА на своей площадке оказался сильнее УНИКСа — 80:72. Счет в серии стал 30 в пользу ЦСКА. Если армейцы выиграют еще раз, то станут чемпионами. В отличие от предыдущей игры казанцы уверенно начали. Первую четверть они выиграли 17:13, а на старте второй вели 21:13. Однако ЦСКА быстро сравнял счет, а затем вышел вперед. "
},
{
"id": "4",
"image": "new4",
"title": "Синоптики предупредили о грозе и сильном ветре в Казани",
"text": "Сегодня вечером в Татарстане, включая Казань, ожидаются гроза и сильный юго-западный ветер порывами 1520 м/с, местами до 23 м/с. Об этом предупреждает Гидрометцентр РТ."
},
{
"id": "5",
"image": "new5",
"title": "Между столицей РТ и аэропортом запустят дополнительные рейсы",
"text": "На маршруте Казань Аэропорт Казань два дня будут курсировать дополнительные пригородные поезда. Это связано с проведением концертов в МВЦ «Казань Экспо». Дополнительные поезда проследуют без промежуточных остановок, сообщили в пресс-службе АО «Содружество»."
}
]

View File

@@ -0,0 +1,78 @@
[
{
"id": "1",
"type": "Достопримечательности",
"image": "kremlin",
"head": "Кремль",
"text": "Строительство кремля продолжалось с X по XVI век. После завоевания Казани Иваном Грозным в 1552 году татарский кремль был разрушен. На его месте псковские зодчие построили мощные белокаменные стены, оставив лишь некоторые фрагменты старого сооружения. В XVIII веке кремль потерял военное значение, но долго оставался административным и культурным центром Поволжья."
},
{
"id": "2",
"image": "kulsharif",
"head": "Мечеть Кул-Шариф",
"text": "Это одна из визитных карточек Казани. Кроме того, Кул-Шариф ещё и главная джума-мечеть Татарстана. Её возведение началось в 1996 году для восстановления важной архитектурной реликвии Казанского ханства, разрушенной войсками Ивана Грозного в 1552 году. Мечеть получила название в честь последнего имама Казани Кул-Шарифа."
},
{
"id": "3",
"image": "suumbike",
"head": "Башня Сююмбике",
"text": "Сооружение впервые упоминается в документах 1703 года, однако точных сведений ни о дате постройки, ни о происхождении названия нет. По одной из версий, это была сторожевая башня, потому что с её вершины хорошо просматриваются окрестности, а также реки Казанка и Волга."
},
{
"id": "4",
"type": "Активный отдых",
"image": "cyrc",
"head": "Казанский цирк",
"text": "Один из ярких памятников советского модернизма. Издалека здание цирка напоминает летающую тарелку. Такую «космическую» форму он получил после масштабной реконструкции 1967 года. Тогда для строительства применили авангардные архитектурные и инженерные решения."
},
{
"id": "5",
"image": "park",
"head": "Экстрим-парк УРАМ",
"text": "УРАМ — самый большой экстрим-парк в России, который состоит из двух частей — открытой и крытой. Уличная часть, объединяющая профессиональные экстрим-зоны и места для прогулок, открылась летом 2020 года и стала одним из самых популярных общественных пространств Казани, а также местом, где спортсмены готовились к соревнованиями мирового масштаба, например, к Олимпиаде в Токио."
},
{
"id": "6",
"image": "zoo",
"head": "Зоопарк Река-Замбези",
"text": "Зоопарк «Река Замбези» Казанский зооботсад - один из старейших зооботсадов в Европе. Увлекательное путешествие в мир животных и растений. Это уникальное место, где посетители могут насладиться богатством флоры и фауны. Он предлагает разнообразные экспозиции, включая животных различных континентов, от экзотических видов до местных жителей."
},
{
"id": "7",
"type": "Театры и музеи",
"head": "Театр кукол Экият",
"text": "Театр кукол Экият в Казани представляет уникальное сочетание традиционного и современного искусства. Он известен своими яркими постановками, привлекающими внимание как детей, так и взрослых. Расположенный в центре города, он стал неотъемлемой частью культурной жизни региона.",
"image": "akiyat"
},
{
"id": "8",
"head": "Театр оперы и балета",
"text": "Театр оперы и балета в Казани является вершиной музыкального и театрального искусства в регионе. С его помощью зрители могут наслаждаться высококлассными оперными постановками и великолепными балетными представлениями, которые оставляют незабываемые впечатления.",
"image": "opera"
},
{
"id": "9",
"head": "Театр им. К.Тинчурина",
"text": "Театр имени Тинчурина воплощает традиции классического искусства, предлагая зрителям широкий выбор спектаклей, начиная от драм и комедий до мюзиклов и балетов. История театра имени К. Тинчурина насчитывает десятилетия искусства и культурного наследия.",
"image": "tinchurina"
},
{
"id": "10",
"type": "Еда и напитки",
"head": "Тюбетей",
"text": "«Тюбетей» - это уютное заведение в Казани, предлагающее посетителям широкий выбор блюд татарской кухни в атмосфере гостеприимства и комфорта. Здесь можно насладиться татарскими блюдами, такими как чак-чак, шашлык, манты и другие.",
"image": "tubetey"
},
{
"id": "11",
"head": "MORE & MORE",
"text": "Этот ресторан специализируется на морепродуктах и рыбе. Ресторан More & More концептуальный проект от ALBA GROUP с акцентом на seafood and wine. По казанским меркам место дорогое, но блюда и ингредиенты оправдывают стоимость",
"image": "more"
},
{
"id": "12",
"head": "Палома Кантина",
"text": "«Палома Кантина» — это мексиканское кафе. Его открыли основатели петербургского бара El Copitas, который попал в мировой рейтинг The Worlds 50 Best Bars. Если в Казани вы почувствуете себя одиноко, захотите ярких красок, вам сюда.",
"image": "paloma"
}
]

View File

@@ -0,0 +1,87 @@
[
{
"id": "1",
"type": "Баскетбол",
"title": "УНИКС ",
"text": "Баскетбольный клуб УНИКС — российский мужской баскетбольный клуб. Основан в 1991 году. Представляет город Казань, столицу Республики Татарстан. Выступает в Профессиональной баскетбольной лиге. «УНИКС» расшифровывается как «Университет — Культура — Спорт».",
"logo": "unics_logo",
"logo_alt": "Логотип УНИКСа",
"image": "unics_img",
"img_alt": "Фотография игроков УНИКСа с первым чемпионским кубком единой Лиги ВТБ",
"link": "https://www.unics.ru/"
},
{
"id": "2",
"title": "Казаночка ",
"text": "Казаночка участвует в женской баскетбольной суперлиге и представляет город Казань на национальном уровне. «Казаночка» играет важную роль в развитии женского баскетбола в регионе и активно соревнуется на международной арене.",
"logo": "kazanochka_logo",
"logo_alt": "Логотип спортивного клуба Казаночка",
"image": "kazanochka_img",
"img_alt": "Фотография игроков Казаночки",
"link": "https://bckazanochka.ru/"
},
{
"id": "3",
"type": "Хоккей",
"title": "Ак Барс ",
"text": "Хоккейный клуб «Ак Барс» из Казани — это один из наиболее известных и успешных профессиональных хоккейных клубов в России. Он был основан в 1956 году и является членом Континентальной Хоккейной Лиги (КХЛ), самой престижной лиги в России и одной из сильнейших в мире.",
"logo": "akbars_logo",
"logo_alt": "Логотип Ак Барса",
"image": "akbars_img",
"img_alt": "Фотография игроков Ак Барса",
"link": "https://www.ak-bars.ru/"
},
{
"id": "4",
"title": "Динамо-Ак Барс ",
"text": "«Динамо-Казань» — команда по хоккею с мячом из Казани. Играет в суперлиге чемпионата России. Действующий чемпион России.",
"logo": "hockey_dinamo_logo",
"logo_alt": "Логотип Динамо-Казань",
"image": "hockey_dinamo_img",
"img_alt": "Фотография игроков Динамо-Казань",
"link": "https://hcdinamo-kazan.ru/"
},
{
"id": "5",
"type": "Футбол",
"title": "Рубин ",
"text": "«Рубин» (тат. Рубин Казан футбол төркеме) — российский футбольный клуб из Казани. Один из ведущих российских футбольных клубов второй половины 2000-х годов. Ведёт свою историю с 1936 года, но официальной датой основания считается 1958 год.",
"logo": "rubin_logo",
"logo_alt": "Логотип Рубина",
"image": "rubin_img",
"img_alt": "Фотография игроков Рубина",
"link": "https://www.rubin-kazan.ru/"
},
{
"id": "6",
"type": "Волейбол",
"title": "Зенит-Казань ",
"text": "«Зенит» (Казань) — российский мужской волейбольный клуб. Основан в 2000 году, до 2004 года назывался «Динамо», с 2005 по июнь 2008 года — «Динамо-Таттрансгаз». 4-кратный чемпион России, 3-кратный обладатель Кубка России, победитель Лиги чемпионов сезонов 2007/08 и 2011/12 годов. Основные цвета: бело-синие.",
"logo": "zenit_logo",
"logo_alt": "Логотип Зенита",
"image": "zenit_img",
"img_alt": "Фотография игроков Зенита",
"link": "https://zenit-kazan.com/"
},
{
"id": "7",
"title": "Динамо-Ак Барс ",
"text": "«Динамо-Казань» Казань (до 2008 — «Казаночка») — российский женский волейбольный клуб.",
"logo": "vol_dinamo_logo",
"logo_alt": "Логотип Динамо-Казань",
"image": "vol_dinamo_img",
"img_alt": "Фотография игроков Динамо-Казань",
"link": "https://dinamo-kazan.com/"
},
{
"id": "8",
"type": "Водное поло",
"title": "Синтез ",
"text": "Толчком развития водного поло в Казани стало строительство первого в Республике 50-ти метрового плавательного бассейна «Оргсинтез», закончившееся в 1973 году. Именно на базе бассейна «Оргсинтез» и была создана взрослая команда «Синтез», добившаяся права играть в первой группе чемпионата РСФСР.",
"logo": "waterpolo_logo",
"logo_alt": "Логотип Синтеза",
"image": "waterpolo_img",
"img_alt": "Фотография игроков Синтеза",
"link": "https://www.sintez-kazan.ru/index.php/ru/"
}
]

View File

@@ -0,0 +1,59 @@
[
1,
2,
4,
5,
6,
9,
10,
"10a",
11,
15,
18,
22,
23,
25,
28,
"28a",
29,
30,
31,
33,
34,
35,
"35a",
36,
"36a",
37,
40,
42,
43,
45,
46,
47,
49,
53,
54,
55,
56,
60,
62,
63,
68,
70,
71,
72,
74,
75,
77,
78,
84,
"84a",
88,
89,
"89a",
90,
91,
93,
94
]

View File

@@ -0,0 +1,178 @@
[
{
"month": "ЯНВАРЬ",
"name": "Республиканский фестиваль народного творчества «Кукморские валенки» #ItekFest",
"body": "Программа фестиваля традиционно включает творческие номера от команд-участников и представление ростовых фигур в форме пары валенок. На фестивале работают торговые ряды, где можно приобрести знаменитые кукморские валенки и другие сувениры, изготовленные местными умельцами.",
"place": "Кукморский район, г.Кукмор"
},
{
"name": "Международный оперный фестиваль им.Федора Шаляпина",
"month": "ФЕВРАЛЬ",
"body": "Один из культурных брендов Республики Татарстан. В традиционной фестивальной программе спектакли, в которых выступал сам великий бас Федор Шаляпин.",
"place": "г.Казань, Татарский академический государственный театр оперы и балета им.М.Джалиля"
},
{
"name": "Фестиваль креативных санок SUNNYФЕСТ",
"body": "Со всех городов республики и даже других регионов России сюда съезжаются санки разных форм и размеров. Презентовав созданные своими руками невообразимые конструкции, участники пробуют их в деле скатываются с горы, на ходу разыгрывая сценки или исполняя песни. Также зрителей ждут ярмарка, тематические фотосессии и прочие зимние забавы.",
"place": "Мамадышский район, г.Мамадыш"
},
{
"name": "III спортивно-исторический фестиваль «Кыш Батыр. Не просто Зимние игры»",
"body": "На площадке фестиваля пройдут соревнования по лыжным гонкам и по историческому биатлону среди разных возрастных категорий, победителей лыжных гонок определят по 16 номинациям. Также гостей фестиваля ждет спортивная зарядка под зажигательную музыку, танцы, стрельба из лука и арбалета, метание топориков, поднятие штанги, приседание с коромыслами, бои на импровизированных мечах.",
"place": "г.Казань, Горкинско-Ометьевский лес"
},
{
"month": "МАРТ",
"name": "Масленица",
"body": "Яркая и веселая Масленица с песнями, танцами, играми, угощениями и, конечно, сжиганием чучела проходит во многих городах Татарстана в Казани (на озере Лебяжье), на острове-граде Свияжск, в Алексеевском, в Чистополе.",
"place": "Города Татарстана"
},
{
"month": "АПРЕЛЬ",
"name": "Международный фестиваль «Рахлинские сезоны»",
"body": "Фестиваль «Рахлинские сезоны» посвящен памяти первого художественного руководителя и главного дирижера Государственного симфонического оркестра Татарстана Н.Рахлина.",
"place": "г.Казань, Большой концертный зал имени Сайдашева"
},
{
"month": "МАЙ",
"name": "Международный фестиваль классического балета им. Рудольфа Нуриева",
"body": "Крупнейший фестиваль балетного искусства, один из старейших в России. С 1993 года носит имя величайшего танцовщика XX века Рудольфа Нуриева, принявшего участие в фестивале в 1992 году.",
"place": "г.Казань, Татарский академический государственный театр оперы и балета им. М. Джалиля"
},
{
"name": "Фестиваль русского фольклора «Каравон»",
"body": "Программа фольклорного праздника включает красочное театрализованное представление, игры и забавы, выставку-продажу изделий народных ремесел. Кульминацией праздника становится общий дружный хоровод.",
"place": "Лаишевский район, с. Никольское"
},
{
"name": "Религиозный праздник «Изге Болгар жиены»",
"body": "Торжественные мероприятия, посвященные годовщине принятия ислама Волжскими Булгарами в 922 году, на которые съезжаются тысячи верующих из разных регионов России и стран мира.",
"place": "Спасский район, г.Болгар"
},
{
"name": "Ак Барс Банк Казанский марафон",
"body": "Участники марафона, который проходит с 2015 года, увидят главные достопримечательности Казани, расположенные на всем протяжении соревновательной трассы. На выбор предлагаются четыре дистанции: 3 км, 10 км, 21,1 км, 42,2 км, отдельные старты запланированы для самых юных спортсменов.",
"place": "г.Казань"
},
{
"name": "Международный фестиваль медиаискусства «НУР»",
"body": "Участники фестиваля создают медиаарт-работы с помощью света, звука, компьютерных технологий и дополненной реальности в десятках казанских локаций. Кроме инсталляций, выставок цифрового искусства и аудиовизуальных перформансов, на фестивале организуются образовательная программа с лекциями, воркшопами и медиалабораториями, ночная музыкальная программа.",
"place": "г.Казань"
},
{
"name": "Татарский национальный праздник «Сабантуй»",
"month": "ИЮНЬ",
"body": "Праздник проходит в три этапа. В первую субботу по окончании весеннего сева в селах и деревнях республики, через неделю в крупных городах Татарстана, а еще через неделю в столице проходит главный Сабантуй. В районах Казани организуются майданы для проведения состязаний, площадки для выступления мастеров культуры и искусств Татарстана, народные гулянья. На центральном ипподроме города проводятся скачки.",
"place": "Города Татарстана"
},
{
"name": "Международный музыкальный фестиваль Бориса Березовского «Летние вечера в Елабуге»",
"body": "Этот фестиваль проводится в формате open-air (на открытом воздухе). Художественным руководителем проекта является заслуженный артист России Борис Березовский. Помимо него участие в фестивале принимают известные музыканты, оркестры и коллективы.",
"place": "Елабужский район, г.Елабуга, Шишкинские пруды"
},
{
"name": "Фестиваль колокольного звона и русской песни «Алексеевские перезвоны»",
"body": "Фестиваль визитная карточка Алексеевского района. Музыкальная часть фестиваля включает звон-концерт лучших звонарей России и других стран, выступления авторов и исполнителей духовной и народной музыки, фольклорных и танцевальных коллективов различных жанров. Также гостей фестивальной площадки ждут ярмарка «Город мастеров», где можно приобрести сувениры, созданные мастерами-ремесленниками, мастер-классы по изготовлению изделий декоративно-прикладного творчества, детские активности.",
"place": "Алексеевский район, пгт. Алексеевское, Соборная площадь"
},
{
"name": "Республиканский фестиваль марийской культуры «Семык»",
"body": "«Семык» один из любимых традиционных праздников марийцев, знаменующий начало летнего праздничного цикла. На фестивале неизменно присутствуют элементы марийской культуры: национальные костюмы, инструментальная музыка, народные песни, танцы, игры, традиционная кухня.",
"place": "Мамадышский район, с.Большая Шия"
},
{
"name": "Фестиваль чувашей Закамья «Учук»",
"body": "Фестиваль проводится ежегодно с 2006 года в последнюю субботу июня. Во время праздника недалеко от фестивальной площадки старейшинами села варится традиционная каша на родниковой воде. Затем проходят специальные моления с просьбой о дожде для посевов. После молебна приготовленную ритуальную кашу дождя раздают всем присутствующим.",
"place": "Альметьеввский район, с.Старое Суркино"
},
{
"name": "Республиканский удмуртский праздник «Гырон Быдтон»",
"body": "Праздник традиционно проводится после завершения весенней пахоты и сева яровых, перед сенокосом. Гостей праздника угощают ритуальной кашей, которая варится на кострах. Национальный напиток кумышку гостям полагается пить из чаши, прикрепленной к концу посоха, который держит в руках хозяйка. Гость руками к чаше и посоху не прикасается, так что приходится выпивать «до дна».",
"place": "Менделеевский район, с.Енабердино"
},
{
"name": "Республиканский праздник мордовской культуры «Валда шинясь»",
"body": "Праздник приурочен ко дню летнего солнцестояния, отражающему мифологические представления мордовского народа о мире. Праздник объединяет в себе два основных субэтноса мордовского народа эрзя и мокшу, а также уникальную этнографическую группу мокшан-каратаев, проживающих в Камско-Устьинском районе Татарстана. Праздник традиционно проходит на большой поляне, где презентуется мордовская национальная культура быт, обряды, национальная кухня.",
"place": "Тетюшский район, с. Кильдюшево"
},
{
"name": "День рыбака",
"month": "ИЮЛЬ",
"body": "Праздник проходит в Тетюшах, где День города и День рыбака отмечают одновременно, весело и задорно. В этот день гостей ждут театрализованные представления, конкурс на самый крупный улов, танцы и песни, богатый рыбный стол.",
"place": "Тетюшский район, г. Тетюши"
},
{
"name": "Республиканский праздник чувашской культуры «Уяв»",
"body": "Уяв старинный чувашский обрядовый праздник, бережно хранимый и передаваемый из поколения в поколение, с особыми ритуалами, хороводами народными забавами и игрищами. На площадках майдана также можно увидеть выставку изделий декоративно-прикладного искусства, поучаствовать в мастер-классах, оценить творческие состязания частушечников и гармонистов.",
"place": "Алькеевский район, с. Сиктерме"
},
{
"name": "Республиканский праздник культуры кряшен «Питрау»",
"body": "«Питрау» один из важных обрядовых праздников кряшен. Он приходится на самую макушку лета и олицетворяет переход на новый календарный цикл. После Петрова дня массово выходят на сенокос.",
"place": "Мамадышский район, с. Зюри"
},
{
"name": "Республиканский праздник славянской культуры «Иван Купала»",
"body": "«Иван Купала» народный праздник восточных славян, посвященный летнему солнцестоянию и наивысшему расцвету природы. Праздник воссоздает традиционные купальские обряды плетение венков, гадание на венках, украшение купальского дерева березы, зажигание купальского костра и прыжки через него. Для участников праздника работают интерактивные площадки, ярмарка товаров народно-художественных промыслов, мастер-классы по плетению венков, изготовлению оберегов, кукол, талисманов.",
"place": "Зеленодольский район"
},
{
"name": "Всероссийский фестиваль «Скорлупино»",
"body": "Фестиваль - визитная карточка Пестречинского района. Ежегодно на празднике устанавливается необычный гастрономический рекорд. Результат предоставляется возможность продегустировать всем гостям. Традиционно программа фестиваля включает ярмарку народных художественных промыслов с мастер-классами от ремесленников, яркие тематические фотозоны, забавные игры с призами, музыкальные площадки.",
"place": "Пестречинский район"
},
{
"name": "Фестиваль современной татарской культуры «Печән базары»",
"body": "В день проведения колоритного фестиваля, погружающего в татарскую культуру, работает ярмарка мастеров, где можно приобрести аутентичные и необычные подарки и сувениры на память о Татарстане: одежду, аксессуары и украшения с татарским орнаментом, посуду ручной работы, игрушки, натуральную косметику и многое другое. Также гостей фестиваля ждут лекции, концертная программа, мастер-классы для детей и другие активности, которые помогут узнать много интересного о Татарстане и его культуре.",
"place": "г.Казань, Старо-татарская слобода, набережная озера Кабан"
},
{
"name": "Фестиваль «Ага-Базар»",
"body": "Идея фестиваля - в возрождении традиций «Восточного базара», который находился в пригороде средневекового Болгара и считался торгово-ремесленным и культурным центром Волжской Булгарии. На фестивале можно услышать этноколлективы, посетить национальные подворья, чтобы познакомиться с обычаями и традициями народов Поволжья. Одна из центральных площадок - стилизованный средневековый рынок Волжской Булгарии, на котором можно было приобрести товары ручной работы.",
"place": "Спасский район, г.Болгар, Болгарский музей-заповедник"
},
{
"name": "Международный этнический фестиваль «Крутушка»",
"month": "АВГУСТ",
"body": "Фестиваль проводится для истинных ценителей качественной этнической музыки и живого фольклорного наследия. По традиции здесь можно поучаствовать в разнообразных мастер-классах: научиться танцам разных народов, основам игры на традиционных инструментах, изготовить собственными руками изделия из глины, кожи, войлока, лозы, дерева, бисера и бересты",
"place": "г.Казань, пос.Крутушка"
},
{
"name": "Всероссийская Спасская ярмарка",
"body": "В ярмарке принимают участие более 1000 мастеров декоративно-прикладного искусства, художественного творчества и народных промыслов из 150 городов и поселений России и других стран. Проходят выступления фольклорных и цирковых коллективов, работают национальные подворья, «Город мастеров».",
"place": "Елабужский район, г.Елабуга"
},
{
"name": "Музейно-фольклорный праздник «Яблочный Спас в Красновидово»",
"body": "Издревле село Красновидово славилось своими плодоносными яблоневыми садами. Основа праздника это концертная программа с выступлением вокального ансамбля «Оберег» и творческих коллективов Республики Татарстан. Также в программе мероприятия и проведение мастер-классов по изготовлению предметов народных промыслов.",
"place": "Камско-Устьинский район, село Красновидово"
},
{
"name": "День Казани и Республики Татарстан",
"body": "Главный праздник для жителей Татарстана: он широко отмечается во всех городах республики, а казанцы в этот день, 30 августа, справляют еще и день города. На многочисленных праздничных площадках проводятся театрализованные представления, концерты, мотошоу, конкурсы. Завершается день праздничным салютом.",
"place": "г.Казань и города Татарстана"
},
{
"name": "Казанский международный фестиваль мусульманского кино",
"month": "СЕНТЯБРЬ",
"body": "Фестиваль проходит в столице Татарстана с 2005 года. В программу фестиваля отбираются фильмы, отражающие общечеловеческие ценности и культурные традиции, несущие идеи веротерпимости и гуманизма вне зависимости от вероисповедания автора. Помимо основной, зрителей ожидает обширная внеконкурсная программа, которая представит зрителям лучшие образцы российского игрового, документального и анимационного кино, ретроспективные и тематические программы.",
"place": "г.Казань"
},
{
"name": "Казанский национальный полумарафон",
"body": "На полумарафоне традиционно проходят забеги на дистанциях в 3, 10, 21,1 км, а также детский старт TIMERKIDS для юных спортсменов в разных возрастных категориях. Старт и финиш организуются у стадиона «Ак Барс Арена».",
"place": "г.Казань"
},
{
"name": "Международный фестиваль современной музыки им. Софии Губайдулиной Concordia",
"month": "НОЯБРЬ",
"body": "Фестиваль проходит с 2011 года. Он носит имя известного российского композитора, автора более сотни симфонических произведений Софии Губайдуллиной. Главное направление фестиваля — современная музыка. Традиционно на фестивале звучат и творения самой Софии Губайдуллиной.",
"place": "г.Казань, Большой концертный зал имени Сайдашева"
},
{
"name": "«КышДаКар-фест»",
"month": "ДЕКАБРЬ",
"body": "Новогодний фестиваль открывает свои двери в конце декабря и продолжает работу все новогодние праздники. Нарядные домики традиционно устанавливаются возле главной городской елки у Центра семьи «Казан». Все желающие могут попробовать необычные лакомства, оценить национальную кухню, приобрести сувениры и принять участие в кулинарных мастер-классах. На фестивале свою продукцию представляют индивидуальные предприниматели, самозанятые и фермеры из районов Татарстана.",
"place": "г.Казань"
}
]

View File

@@ -0,0 +1,6 @@
[
"Наиболее развитая сеть в городе автобусная. Она обеспечивает беспересадочные перевозки пассажиров между всеми районами города.",
"Трамвайная и троллейбусная маршрутная сеть образует радиально-кольцевую систему. Трамвайным и троллейбусным транспортом обслуживаются все районы города.",
"Метрополитен г. Казани современный, высококомфортабельный и скоростной вид транспорта. Поезда, оснащенные новейшими системами автоматики, позволяют на высоком уровне обслуживать пассажиров.",
"Казань также обладает различными туристическими объектами, такими как пешеходные улицы, парки и набережные, которые часто становятся популярными местами для прогулок и отдыха."
]

View File

@@ -0,0 +1,12 @@
[
1,
2,
3,
5,
6,
7,
8,
9,
12,
13
]

View File

@@ -0,0 +1,450 @@
[
{
"id": "1",
"from": "Речной порт",
"to": "жилой массив Дербышки",
"route_length": "18,03 км",
"operating_mode_weekdays": "Будни: начало движения — 5:24. Отправление в последний рейс А — 22:32. Отправление в последний рейс Б — 21:27. Интервал движения: утро — 6,9 мин, вечер — 7,3 мин.",
"operating_mode_weekend": " В выходные: начало движения — 5:30. Отправление в последний рейс А — 22:44. Отправление в последний рейс Б — 21:55. Интервал движения 7,5 мин."
},
{
"id": "2",
"from": "Станция метро «Аметьево»",
"to": "ул.Привокзальная",
"route_length": "20,9 км",
"operating_mode_weekdays": "Будни: начало движения — 5:40. Отправление в последний рейс А — 21:54. Отправление в последний рейс Б — 21:01. Интервал движения 8,5 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:40. Отправление в последний рейс А — 21:34. Отправление в последний рейс Б — 20:32. Интервал движения 9 мин."
},
{
"id": "4",
"from": "Жилой массив Ферма-2",
"to": "жилой массив Новая Сосновка",
"route_length": "24,59 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 21:02. Отправление в последний рейс Б — 20:50. Интервал движения 14,8 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:30. Отправление в последний рейс А — 21:07. Отправление в последний рейс Б — 21:20. Интервал движения 22 мин."
},
{
"id": "5",
"from": "ЦУМ",
"to": "ул.Халитова",
"route_length": "27,42 км",
"operating_mode_weekdays": "Будни: начало движения — 5:43. Отправление в последний рейс А — 22:05. Отправление в последний рейс Б — 20:45. Интервал движения: утро 6,7 мин, вечер 7 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:31. Отправление в последний рейс А — 22:15. Отправление в последний рейс Б — 21:03. Интервал движения 7,6 мин."
},
{
"id": "6",
"from": "Речной порт",
"to": "жилой массив Северный",
"route_length": "20,9 км",
"operating_mode_weekdays": "Будни: начало движения — 5:00. Отправление в последний рейс А — 22:24. Отправление в последний рейс Б — 21:32. Интервал движения 7,8 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:45. Отправление в последний рейс А — 22:07. Отправление в последний рейс Б — 21:20. Интервал движения 8,4 мин."
},
{
"id": "9",
"from": "Жилой массив Дербышки",
"to": "жилой массив Аки",
"route_length": "4,52 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 19:10. Отправление в последний рейс Б — 19:40.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 19:10. Отправление в последний рейс Б — 19:40."
},
{
"id": "10",
"from": "Ул.Серова",
"to": "ул.Академика Губкина (кольцевой)",
"route_length": "15,3 км",
"operating_mode_weekdays": "Будни: начало движения — 5:20. Отправление в последний рейс А — 22:12. Отправление в последний рейс Б — 23:04. Интервал движения 5,7 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 21:30. Отправление в последний рейс Б — 22:30. Интервал движения 7,1 мин."
},
{
"id": "10a",
"from": "Ул.Серова",
"to": "ул.Академика Губкина (кольцевой)",
"route_length": "14,82 км",
"operating_mode_weekdays": "Будни: начало движения — 5:19. Отправление в последний рейс А — 21:52. Отправление в последний рейс Б — 22:23. Интервал движения 5,9 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 21:55. Отправление в последний рейс Б — 22:25. Интервал движения 7,2 мин."
},
{
"id": "11",
"from": "Жилой массив Дербышки",
"to": "жилой массив Малые Дербышки",
"route_length": "10,56 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 18:45. Отправление в последний рейс Б — 19:10.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 18:45. Отправление в последний рейс Б — 19:10."
},
{
"id": "15",
"from": "Комбинат «Здоровье»",
"to": "ул.Адоратского",
"route_length": "10,38 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 22:51. Отправление в последний рейс Б — 22:22. Интервал движения 6 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 22:50. Отправление в последний рейс Б — 22:30. Интервал движения 7 мин.99"
},
{
"id": "18",
"from": "Ул.Северополюсная",
"to": "переулок Дуслык",
"route_length": "31,41 км",
"operating_mode_weekdays": "Будни: начало движения — 4:50. Отправление в последний рейс А — 22:01. Отправление в последний рейс Б — 20:20. Интервал движения 8,5 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:40. Отправление в последний рейс А — 21:58. Отправление в последний рейс Б — 20:14. Интервал движения 10,2 мин."
},
{
"id": "22",
"from": "Ул.Можайского",
"to": "жилой массив Ферма-2",
"route_length": "24,45 км",
"operating_mode_weekdays": "5:30. Отправление в последний рейс А — 21:38. Отправление в последний рейс Б — 20:34. Интервал движения: утро 7,1 мин, вечер 7,4 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:40. Отправление в последний рейс А — 21:19. Отправление в последний рейс Б — 20:01. Интервал движения 10,1 мин."
},
{
"id": "23",
"from": "Ул.Р.Яхина",
"to": "жилой массив Мирный",
"route_length": "13,58 км",
"operating_mode_weekdays": "Будни: начало движения — 5:20. Отправление в последний рейс А — 22:11. Отправление в последний рейс Б — 21:40. Интервал движения: утро 12,9 мин, вечер 15,1 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:20. Отправление в последний рейс А — 21:05. Отправление в последний рейс Б — 21:13. Интервал движения 15 мин."
},
{
"id": "25",
"from": "Ул.Техническая",
"to": "жилой массив Дербышки",
"route_length": "20,66 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 19:30. Отправление в последний рейс Б — 18:30. Интервал движения 13,2 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:10. Отправление в последний рейс А — 18:10. Отправление в последний рейс Б — 17:50. Интервал движения 20 мин."
},
{
"id": "28",
"from": "ЦПКиО",
"to": "ул.Короленко (кольцевой)",
"route_length": "8,81 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 21:45. Отправление в последний рейс Б — 22:02. Интервал движения 7,6 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 21:38. Отправление в последний рейс Б — 22:01. Интервал движения 15 мин."
},
{
"id": "28a",
"from": "Чеховский рынок",
"to": "ул.Короленко (кольцевой)",
"route_length": "10,74 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 21:30. Отправление в последний рейс Б — 22:01. Интервал движения 8 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 21:30. Отправление в последний рейс Б — 22:01. Интервал движения 15 мин."
},
{
"id": "29",
"from": "Строительный институт",
"to": "ул.Гудованцева",
"route_length": "17,23 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 22:30. Отправление в последний рейс Б — 21:40. Интервал движения 7,2 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 22:30. Отправление в последний рейс Б — 21:40. Интервал движения 9,2 мин."
},
{
"id": "30",
"from": "Переулок Дуслык",
"to": "станция Лагерная",
"route_length": "27,05 км",
"operating_mode_weekdays": "Будни: начало движения — 4:38. Отправление в последний рейс А — 21:24. Отправление в последний рейс Б — 22:40. Интервал движения: утро 6,6 мин, вечер 6,8 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:01. Отправление в последний рейс А — 20:56. Отправление в последний рейс Б — 22:18. Интервал движения 8,1 мин."
},
{
"id": "31",
"from": "Магазин «IKEA»",
"to": "жилой массив Старое Победилово",
"route_length": "29,48 км",
"operating_mode_weekdays": "Будни: начало движения — 5:15. Отправление в последний рейс А — 22:10. Отправление в последний рейс Б — 21:46. Интервал движения: утро 6,6 мин, вечер 6,8 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:30. Отправление в последний рейс А — 22:10. Отправление в последний рейс Б — 21:51. Интервал движения 8 мин."
},
{
"id": "33",
"from": "Ул.Ленинградская",
"to": "жилой массив Ферма-2",
"route_length": "99999",
"operating_mode_weekdays": "88888",
"operating_mode_weekend": "99999"
},
{
"id": "34",
"from": "Жилой массив Ферма-2",
"to": "ДК им.Саид-Галеева",
"route_length": "25,39 км",
"operating_mode_weekdays": "Будни: начало движения — 5:25. Отправление в последний рейс А — 18:51. Отправление в последний рейс Б — 19:59. Интервал движения 14,8 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 17:44. Отправление в последний рейс Б — 18:48. Интервал движения 17,5 мин."
},
{
"id": "35",
"from": "Станция метро «Площадь Г.Тукая»",
"to": "ул.Гаврилова (кольцевой)",
"route_length": "14,33 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 22:26. Отправление в последний рейс Б — 21:35. Интервал движения 7 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 22:15. Отправление в последний рейс Б — 21:21. Интервал движения 9,4 мин."
},
{
"id": "35a",
"from": "Станция метро «Площадь Г.Тукая»",
"to": "Авторынок (кольцевой)",
"route_length": "14,06 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 22:37. Отправление в последний рейс Б — 21:45. Интервал движения утро 6,4 мин, вечер 6,9 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 22:20. Отправление в последний рейс Б — 21:30. Интервал движения 9 мин."
},
{
"id": "36",
"from": "Вещевой рынок",
"to": "Осиново",
"route_length": "29,9 км",
"operating_mode_weekdays": "Будни: начало движения — 5:14. Отправление в последний рейс А — 21:42. Отправление в последний рейс Б — 20:28. Интервал движения: утро 6,8 мин, вечер 7,1 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:30. Отправление в последний рейс А — 21:41. Отправление в последний рейс Б — 20:21. Интервал движения 11 мин."
},
{
"id": "36a",
"from": "Жилой массив Залесный",
"to": "Новониколаевский",
"route_length": "14,98 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 19:00. Отправление в последний рейс Б — 19:15.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 19:00. Отправление в последний рейс Б — 19:15."
},
{
"id": "37",
"from": "Жилой массив Ферма-2",
"to": "жилой массив Сухая Река",
"route_length": "30,26 км",
"operating_mode_weekdays": "Будни: начало движения — 4:58. Отправление в последний рейс А — 21:47. Отправление в последний рейс Б — 21:32. Интервал движения 10 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:30. Отправление в последний рейс А — 21:48. Отправление в последний рейс Б — 20:54. Интервал движения 13,7 мин."
},
{
"id": "40",
"from": "Ул.Гаврилова",
"to": "кафе «Ак Барс»",
"route_length": "19,5 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 20:00. Отправление в последний рейс Б — 20:55.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 20:00. Отправление в последний рейс Б — 20:00."
},
{
"id": "42",
"from": "КДК им.Ленина",
"to": "жилой массив Борисоглебское",
"route_length": "8,56 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 19:10. Отправление в последний рейс Б -19:40.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 19:10. Отправление в последний рейс Б 19:40."
},
{
"id": "43",
"from": "Ул. Химическая",
"to": "ул.Техническая",
"route_length": "27,37 км",
"operating_mode_weekdays": "Будни: начало движения — 5:00. Отправление в последний рейс А — 21:45. Отправление в последний рейс Б — 21:45. Интервал движения 7,9 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:12. Отправление в последний рейс А — 20:32. Отправление в последний рейс Б — 22:02. Интервал движения 11,3 мин."
},
{
"id": "45",
"from": "Жилой массив Ферма-2",
"to": "Су Анасы",
"route_length": "39,28 км",
"operating_mode_weekdays": "Будни: начало движения — 4:57. Отправление в последний рейс А — 22:01. Отправление в последний рейс Б — 22:17. Интервал движения утро 7,1 мин, вечер 7,9 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:00. Отправление в последний рейс А — 21:46. Отправление в последний рейс Б — 22:00. Интервал движения 7,6 мин."
},
{
"id": "46",
"from": "Жилой комплекс «Экопарк „Дубрава“»",
"to": "Профилакторий",
"route_length": "41,42 км",
"operating_mode_weekdays": "Будни: начало движения — 5:20. Отправление в последний рейс А — 22:19. Отправление в последний рейс Б — 21:46. Интервал движения 7,1 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:45. Отправление в последний рейс А — 22:01. Отправление в последний рейс Б — 22:01. Интервал движения 8,1 мин."
},
{
"id": "47",
"from": "Ул.Батыршина",
"to": "Деревня Универсиады",
"route_length": "20,67 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 21:48. Отправление в последний рейс Б — 22:51. Интервал движения 6,6 мин",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 21:18. Отправление в последний рейс Б — 22:20. Интервал движения 8,2 мин."
},
{
"id": "49",
"from": "Вещевой рынок",
"to": "станция Лагерная",
"route_length": "21,52 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 20:48. Отправление в последний рейс Б — 19:48. Интервал движения утро 8,3 мин, вечер 8,9 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 20:43. Отправление в последний рейс Б — 19:50. Интервал движения 11,4 мин."
},
{
"id": "53",
"from": "Речной порт",
"to": "ул.Ленинградская",
"route_length": "16,73 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 22:10. Отправление в последний рейс Б — 21:14. Интервал движения 9,1 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:20. Отправление в последний рейс А — 21:41. Отправление в последний рейс Б — 20:47. Интервал движения 12,4 мин."
},
{
"id": "54",
"from": "Речной порт",
"to": "ул.Гаврилова",
"route_length": "13,14 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 22:26. Отправление в последний рейс Б — 21:41. Интервал движения 5,6 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 22:20. Отправление в последний рейс Б — 21:35. Интервал движения 9,1 мин."
},
{
"id": "55",
"from": "39-й квартал",
"to": "жилой комплекс «Лесной городок»",
"route_length": "22,22 км",
"operating_mode_weekdays": "Будни: начало движения — 5:35. Отправление в последний рейс А — 22:02. Отправление в последний рейс Б — 22:22. Интервал движения 8,7 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 22:02. Отправление в последний рейс Б — 22:02. Интервал движения 15 мин."
},
{
"id": "56",
"from": "Ул.Р.Яхина",
"to": "жилой массив Петровский",
"route_length": "17,10 км",
"operating_mode_weekdays": "Будни: начало движения — 5:40. Отправление в последний рейс А — 21:30. Отправление в последний рейс Б — 20:46.",
"operating_mode_weekend": "В выходные: начало движения — 5:50. Отправление в последний рейс А — 18:11. Отправление в последний рейс Б — 19:05."
},
{
"id": "60",
"from": "Ул. Химическая",
"to": "жилой массив Дербышки",
"route_length": "26,62 км",
"operating_mode_weekdays": "Будни: начало движения — 5:15. Отправление в последний рейс А — 22:15. Отправление в последний рейс Б — 21:08. Интервал движения утро 7,7 мин, вечер 8,5 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:15. Отправление в последний рейс А — 21:55. Отправление в последний рейс Б — 20:43. Интервал движения 8,2 мин."
},
{
"id": "62",
"from": "ДВВС",
"to": "жилой комплекс «Салават Купере»",
"route_length": "29,33 км",
"operating_mode_weekdays": "Будни: начало движения — 5:00. Отправление в последний рейс А — 21:00. Отправление в последний рейс Б — 21:19. Интервал движения 12,5 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:30. Отправление в последний рейс А — 21:06. Отправление в последний рейс Б — 20:06. Интервал движения 12 мин."
},
{
"id": "63",
"from": "Ул.Комиссара Габишева",
"to": "жилой массив Левченко",
"route_length": "30,90 км",
"operating_mode_weekdays": "Будни: начало движения — 5:45. Отправление в последний рейс А — 21:20. Отправление в последний рейс Б — 22:41. Интервал движения 8,6 мин.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 20:56. Отправление в последний рейс Б — 22:26. Интервал движения 11,5 мин."
},
{
"id": "68",
"from": "Ж/д вокзал",
"to": "ул.Иман",
"route_length": "20,87 км",
"operating_mode_weekdays": "Будни: начало движения — 5:00. Отправление в последний рейс А — 21:47. Отправление в последний рейс Б — 20:46. Интервал движения 10 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:00. Отправление в последний рейс А — 21:14. Отправление в последний рейс Б — 20:15. Интервал движения 12,5 мин."
},
{
"id": "70",
"from": "Чеховский рынок",
"to": "жилой комплекс «Весна»",
"route_length": "11,09 км",
"operating_mode_weekdays": "Будни: начало движения — 5:50. Отправление в последний рейс А — 21:30. Отправление в последний рейс Б — 21:00.",
"operating_mode_weekend": "В выходные: начало движения — 5:50. Отправление в последний рейс А — 21:21. Отправление в последний рейс Б — 20:39."
},
{
"id": "71",
"from": "Городская клиническая больница №5",
"to": "жилой массив Константиновка",
"route_length": "17,29 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 21:35. Отправление в последний рейс Б — 20:53.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 21:30. Отправление в последний рейс Б — 20:45."
},
{
"id": "72",
"from": "Площадь Вахитова",
"to": "Профилакторий",
"route_length": "27,33 км",
"operating_mode_weekdays": "Будни: начало движения — 5:40. Отправление в последний рейс А — 22:25. Отправление в последний рейс Б — 21:59.",
"operating_mode_weekend": "В выходные: начало движения — 6:10. Отправление в последний рейс А — 20:45. Отправление в последний рейс Б — 20:14."
},
{
"id": "74",
"from": "ДВВС",
"to": "10-й микрорайон",
"route_length": "22,39 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 21:47. Отправление в последний рейс Б — 20:45.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 21:40. Отправление в последний рейс Б — 20:38."
},
{
"id": "75",
"from": "Комбинат «Здоровье»",
"to": "Универсам-2",
"route_length": "11,60 км",
"operating_mode_weekdays": "Будни: начало движения — 5:40. Отправление в последний рейс А — 22:25. Отправление в последний рейс Б — 21:59.",
"operating_mode_weekend": "В выходные: начало движения — 6:10. Отправление в последний рейс А — 20:45. Отправление в последний рейс Б — 20:14."
},
{
"id": "77",
"from": "Переулок Дуслык",
"to": "Нефтебаза",
"route_length": "28,10 км",
"operating_mode_weekdays": "Будни: начало движения — 4:45. Отправление в последний рейс А — 19:23. Отправление в последний рейс Б — 20:20.",
"operating_mode_weekend": "В выходные: начало движения — 5:00. Отправление в последний рейс А — 19:03. Отправление в последний рейс Б — 20:22."
},
{
"id": "78",
"from": "Ул.Волгоградская",
"to": "жилой массив Крутушка",
"route_length": " 18,74 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 19:35. Отправление в последний рейс Б — 20:20.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 19:35. Отправление в последний рейс Б — 20:20."
},
{
"id": "84",
"from": "Ул. Халитова",
"to": "жилой массив Чебакса",
"route_length": "15,32 км",
"operating_mode_weekdays": "Будни: начало движения — 6:15. Отправление в последний рейс А — 17:10. Отправление в последний рейс Б — 18:00.",
"operating_mode_weekend": "В выходные: начало движения — 6:15. Отправление в последний рейс А — 17:10. Отправление в последний рейс Б — 18:00."
},
{
"id": "84a",
"from": "Ул. Халитова",
"to": "жилой массив Чебакса",
"route_length": "17,48 км",
"operating_mode_weekdays": "Будни: начало движения — 6:15. Отправление в последний рейс А — 17:10. Отправление в последний рейс Б — 18:00.",
"operating_mode_weekend": "В выходные: начало движения — 6:15. Отправление в последний рейс А — 17:10. Отправление в последний рейс Б — 18:00."
},
{
"id": "88",
"from": "Жилой массив Дербышки",
"to": "жилой массив Кульсеитово",
"route_length": "9,69 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 22:05. Отправление в последний рейс Б — 20:57. Интервал движения утро 7,4 мин, вечер 7,7 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:30. Отправление в последний рейс А — 21:30. Отправление в последний рейс Б — 20:00. Интервал движения 9,4 мин."
},
{
"id": "89",
"from": "Ул.Академика Сахарова",
"to": "ул.Гудованцева",
"route_length": "27,98 км",
"operating_mode_weekdays": "Будни: начало движения — 5:18. Отправление в последний рейс А — 22:13. Отправление в последний рейс Б — 21:04. Интервал движения 7,3 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:30. Отправление в последний рейс А — 22:11. Отправление в последний рейс Б — 20:40. Интервал движения 9,1 мин."
},
{
"id": "90",
"from": "Станция метро «Площадь Г.Тукая»",
"to": "Куюки",
"route_length": "22,02 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 21:10. Отправление в последний рейс Б — 20:13. Интервал движения 13,8 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:45. Отправление в последний рейс А — 21:10. Отправление в последний рейс Б — 20:04. Интервал движения 19 мин."
},
{
"id": "91",
"from": "ЦУМ",
"to": "Высокая Гора (АРЗ)",
"route_length": "26,71 км",
"operating_mode_weekdays": "Будни: начало движения — 5:30. Отправление в последний рейс А — 22:05. Отправление в последний рейс Б — 20:57. Интервал движения утро 7,4 мин, вечер 7,7 мин.",
"operating_mode_weekend": "В выходные: начало движения — 5:30. Отправление в последний рейс А — 21:30. Отправление в последний рейс Б — 20:00. Интервал движения 9,4 мин."
},
{
"id": "93",
"from": "КДК им.Ленина",
"to": "н.п.Берновые Ковали",
"route_length": "21,20 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 18:10. Отправление в последний рейс Б — 18:55.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 16:30. Отправление в последний рейс Б — 17:15."
},
{
"id": "94",
"from": "остановка Дубравная",
"to": "жилой массив Привольный",
"route_length": "6,65 км",
"operating_mode_weekdays": "Будни: начало движения — 6:00. Отправление в последний рейс А — 19:30. Отправление в последний рейс Б — 20:00.",
"operating_mode_weekend": "В выходные: начало движения — 6:00. Отправление в последний рейс А — 19:30. Отправление в последний рейс Б — 20:00."
}
]

View File

@@ -0,0 +1,29 @@
{
"data": [
{
"name": "Kamila",
"email": "kamila@gmail.com",
"password": "qwerty"
},
{
"name": "Liliya",
"email": "liliya@mail.ru",
"password": "12121"
},
{
"name": "Guzel",
"email": "guzel@gmail.com",
"password": "12345"
},
{
"name": "Labeyrie",
"email": "superlu@unics.ru",
"password": "qwertyqwe"
},
{
"name": "Ismael Bako",
"email": "bako@unics.ru",
"password": "21"
}
]
}

View File

@@ -1,7 +1,7 @@
const ObjectId = require('mongodb').ObjectID
const getHash = require('pbkdf2-password')()
const { getDB } = require('../../utils/mongo')
const { getDB } = require('../../../utils/mongo')
const USERS_COLLECTION = 'users'
const LISTS_COLLECTION = 'lists'

Some files were not shown because too many files have changed in this diff Show More