From fb687094eeaec74b0d2594ab30b65e86076a1c71 Mon Sep 17 00:00:00 2001 From: wancat Date: Sun, 8 Oct 2023 17:25:29 +0800 Subject: [PATCH 01/15] feat: new analytics package, setup template --- package.json | 1 + packages/analytics/nodemon.json | 3 + packages/analytics/package.json | 19 ++ packages/analytics/src/index.js | 17 ++ packages/analytics/views/home.handlebars | 2 + .../analytics/views/layouts/main.handlebars | 8 + yarn.lock | 185 ++++++++++++++++-- 7 files changed, 224 insertions(+), 11 deletions(-) create mode 100644 packages/analytics/nodemon.json create mode 100644 packages/analytics/package.json create mode 100644 packages/analytics/src/index.js create mode 100644 packages/analytics/views/home.handlebars create mode 100644 packages/analytics/views/layouts/main.handlebars diff --git a/package.json b/package.json index 6673de9..cb6fbb1 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "format": "prettier --ignore-path .prettierignore --write app server", "test": "yarn node --experimental-vm-modules $(yarn bin jest)", "test:e2e": "yarn workspace tests test", + "analytics": "yarn workspace analytics dev", "clean": "yarn workspace server clean" }, "devDependencies": { diff --git a/packages/analytics/nodemon.json b/packages/analytics/nodemon.json new file mode 100644 index 0000000..d98dcc2 --- /dev/null +++ b/packages/analytics/nodemon.json @@ -0,0 +1,3 @@ +{ + "ext": "js,handlebars" +} diff --git a/packages/analytics/package.json b/packages/analytics/package.json new file mode 100644 index 0000000..70ef945 --- /dev/null +++ b/packages/analytics/package.json @@ -0,0 +1,19 @@ +{ + "name": "analytics", + "version": "1.0.0", + "main": "index.js", + "private": true, + "type": "module", + "license": "GPL", + "scripts": { + "start": "node src/index.js", + "dev": "nodemon src/index.js" + }, + "dependencies": { + "express": "^4.18.2", + "express-handlebars": "^7.1.2" + }, + "devDependencies": { + "nodemon": "^3.0.1" + } +} diff --git a/packages/analytics/src/index.js b/packages/analytics/src/index.js new file mode 100644 index 0000000..73dd1fc --- /dev/null +++ b/packages/analytics/src/index.js @@ -0,0 +1,17 @@ +import express from 'express' +import { engine } from 'express-handlebars' + +const app = express() + +// Setting up Handlebars as templating engine +app.engine('handlebars', engine()) +app.set('view engine', 'handlebars') +app.set('views', './views') + +app.get('/', (req, res) => { + res.render('home', { title: 'Linux Odyssey Admin' }) +}) + +app.listen(3001, () => { + console.log('Server started on http://localhost:3001') +}) diff --git a/packages/analytics/views/home.handlebars b/packages/analytics/views/home.handlebars new file mode 100644 index 0000000..35a5107 --- /dev/null +++ b/packages/analytics/views/home.handlebars @@ -0,0 +1,2 @@ +

Welcome to {{title}}

+

This is the content of the homepage.

\ No newline at end of file diff --git a/packages/analytics/views/layouts/main.handlebars b/packages/analytics/views/layouts/main.handlebars new file mode 100644 index 0000000..ce48582 --- /dev/null +++ b/packages/analytics/views/layouts/main.handlebars @@ -0,0 +1,8 @@ + + + {{title}} + + + {{{body}}} + + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 33272f0..0046d79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -547,6 +547,18 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -835,6 +847,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@pkgr/utils@^2.3.1": version "2.4.2" resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" @@ -1182,6 +1199,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1201,6 +1223,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + any-promise@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -1547,6 +1574,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2148,6 +2182,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -2183,6 +2222,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -2633,6 +2677,15 @@ expect@^29.6.1: jest-message-util "^29.6.1" jest-util "^29.6.1" +express-handlebars@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/express-handlebars/-/express-handlebars-7.1.2.tgz#2471673d11af46f496cba4098a705f0217232fda" + integrity sha512-ss9d3mBChOLTEtyfzXCsxlItUxpgS3i4cb/F70G6Q5ohQzmD12XB4x/Y9U6YboeeYBJZt7WQ5yUNu7ZSQ/EGyQ== + dependencies: + glob "^10.3.3" + graceful-fs "^4.2.11" + handlebars "^4.7.8" + express-session@^1.17.3: version "1.17.3" resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.3.tgz#14b997a15ed43e5949cb1d073725675dd2777f36" @@ -2837,6 +2890,14 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -3027,6 +3088,17 @@ glob@7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^10.3.3: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -3079,7 +3151,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -3089,6 +3161,18 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +handlebars@^4.7.8: + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.2" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -3530,6 +3614,15 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jest-changed-files@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" @@ -4178,6 +4271,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== + luxon@^3.2.1: version "3.4.1" resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.1.tgz#9147374b2c539e7893f906c420e9b080b59c5457" @@ -4281,7 +4379,14 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.8: +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -4298,6 +4403,11 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -4428,6 +4538,11 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + node-addon-api@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" @@ -4792,6 +4907,14 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -5272,6 +5395,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + simple-update-notifier@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" @@ -5444,7 +5572,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5453,6 +5581,15 @@ string-length@^4.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string.prototype.trim@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" @@ -5487,13 +5624,20 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -5827,6 +5971,11 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" +uglify-js@^3.1.4: + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + uid-safe@~2.1.5: version "2.1.5" resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" @@ -6047,6 +6196,20 @@ wide-align@^1.1.2: dependencies: string-width "^1.0.2 || 2 || 3 || 4" +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -6056,14 +6219,14 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" wrappy@1: version "1.0.2" From add6bfd1003b0f2ce4d25f2c4700d61530ed1d32 Mon Sep 17 00:00:00 2001 From: wancat Date: Mon, 9 Oct 2023 10:14:05 +0800 Subject: [PATCH 02/15] feat: connect analytics to mongo --- packages/analytics/package.json | 1 + packages/analytics/src/config.js | 3 +++ packages/analytics/src/index.js | 29 ++++++++++++++++++----------- 3 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 packages/analytics/src/config.js diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 70ef945..56b62de 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -10,6 +10,7 @@ "dev": "nodemon src/index.js" }, "dependencies": { + "@linux-odyssey/models": "*", "express": "^4.18.2", "express-handlebars": "^7.1.2" }, diff --git a/packages/analytics/src/config.js b/packages/analytics/src/config.js new file mode 100644 index 0000000..fa291ff --- /dev/null +++ b/packages/analytics/src/config.js @@ -0,0 +1,3 @@ +export default { + db: process.env.MONGO_URL || 'mongodb://localhost:27017/odyssey-test', +} diff --git a/packages/analytics/src/index.js b/packages/analytics/src/index.js index 73dd1fc..e2b9360 100644 --- a/packages/analytics/src/index.js +++ b/packages/analytics/src/index.js @@ -1,17 +1,24 @@ +import connectDB from '@linux-odyssey/models' import express from 'express' import { engine } from 'express-handlebars' +import config from './config.js' -const app = express() +async function main() { + await connectDB(config.db) + const app = express() -// Setting up Handlebars as templating engine -app.engine('handlebars', engine()) -app.set('view engine', 'handlebars') -app.set('views', './views') + // Setting up Handlebars as templating engine + app.engine('handlebars', engine()) + app.set('view engine', 'handlebars') + app.set('views', './views') -app.get('/', (req, res) => { - res.render('home', { title: 'Linux Odyssey Admin' }) -}) + app.get('/', (req, res) => { + res.render('home', { title: 'Linux Odyssey Admin' }) + }) -app.listen(3001, () => { - console.log('Server started on http://localhost:3001') -}) + app.listen(3001, () => { + console.log('Server started on http://localhost:3001') + }) +} + +main().catch(console.error) From cc95bb195b427e6ece0a6ffddde273d9acd4b262 Mon Sep 17 00:00:00 2001 From: wancat Date: Mon, 9 Oct 2023 10:47:44 +0800 Subject: [PATCH 03/15] feat: add usercount, session count and complete rate --- packages/analytics/README.md | 59 +++++++++++++++++++++ packages/analytics/src/controllers/index.js | 15 ++++++ packages/analytics/src/index.js | 5 +- packages/analytics/src/models/quests.js | 24 +++++++++ packages/analytics/src/models/users.js | 6 +++ packages/analytics/views/home.handlebars | 23 +++++++- server/src/containers/expiryChecker.js | 4 +- 7 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 packages/analytics/README.md create mode 100644 packages/analytics/src/controllers/index.js create mode 100644 packages/analytics/src/models/quests.js create mode 100644 packages/analytics/src/models/users.js diff --git a/packages/analytics/README.md b/packages/analytics/README.md new file mode 100644 index 0000000..01371e4 --- /dev/null +++ b/packages/analytics/README.md @@ -0,0 +1,59 @@ +# Analytics + +## Information provided + +### 1. **Dashboard Overview**: + +- **Total Users**: Display the total number of registered users. +- **Active Users**: Count of users who've been active in the past day, week, or month. +- **Completed Quests**: Total quests or challenges completed by all users. +- **Average Time Usage**: Average time a user spends on the platform or on challenges. + +### 2. **User Analytics**: + +- **User Growth**: A graph showing user registrations over time (daily, weekly, monthly). +- **Retention Rate**: Percentage of users who return after their first visit. +- **User Segmentation**: Group users based on criteria like their progress level, frequency of usage, or other custom metrics. + +### 3. **Quest/Challenge Analytics**: + +- **Quest Popularity**: Rank quests by the number of completions or engagements. +- **Average Completion Time**: The average time taken by users to complete each quest. +- **Drop-Off Points**: Identify quests where users abandon or fail frequently. + +### 4. **Error Analysis**: + +- **Common Errors**: List frequently mistyped or erroneous commands. +- **Quest-specific Errors**: Identify challenges where users make the most mistakes. + +### 5. **Feedback & Survey Results**: + +- **Feedback Overview**: Display recent feedback or suggestions. +- **Survey Analysis**: If you've integrated a survey, show aggregated results or key insights. + +### 6. **System Health & Usage**: + +- **Server Load**: Monitor server performance metrics like CPU usage, memory usage, etc. +- **Error Logs**: View any system errors, glitches, or issues. + +### 7. **User Details**: + +- **Search & View**: Ability to search for specific users and view their profile, progress, and activity logs. +- **User Behavior**: For selected users, see a detailed path of their activity, including the quests they've engaged with, time spent, errors made, etc. + +### 8. **Notifications & Alerts**: + +- **System Alerts**: Notifications about server downtimes, high error rates, or other critical issues. +- **User Activity Alerts**: Set alerts for specific user activities, e.g., when a user completes all challenges. + +### 9. **Engagement Metrics**: + +- **Daily Active Users**: Users who engage with the platform daily. +- **Top Users**: Identify power users or those with high engagement rates. + +### 10. **Export & Reports**: + +- **Data Export**: Option to export user data, analytics, or other metrics. +- **Generate Reports**: Create detailed reports based on selected metrics, useful for team meetings or strategy planning. + +When designing this admin dashboard, focus on clarity and ease of use. Utilize visual aids like graphs, charts, and heatmaps to make data interpretation straightforward. Since your backend is built with NodeJS and ExpressJS and you use MongoDB for data storage, you can utilize various NPM packages to aid in data visualization and dashboard creation. Ensure the dashboard is secure and accessible only to authorized personnel. diff --git a/packages/analytics/src/controllers/index.js b/packages/analytics/src/controllers/index.js new file mode 100644 index 0000000..283a03b --- /dev/null +++ b/packages/analytics/src/controllers/index.js @@ -0,0 +1,15 @@ +import { userCount } from '../models/users.js' +import { sessionCount, sessionCompleted } from '../models/quests.js' + +// eslint-disable-next-line import/prefer-default-export +export async function homeController(req, res) { + const payload = { + title: 'Linux Odyssey Admin', + userCount: await userCount(), + sessionCount: await sessionCount(), + sessionCompleted: await sessionCompleted(), + } + payload.completedRate = + Math.round((payload.sessionCompleted / payload.sessionCount) * 10000) / 100 + res.render('home', payload) +} diff --git a/packages/analytics/src/index.js b/packages/analytics/src/index.js index e2b9360..3e4a4cb 100644 --- a/packages/analytics/src/index.js +++ b/packages/analytics/src/index.js @@ -2,6 +2,7 @@ import connectDB from '@linux-odyssey/models' import express from 'express' import { engine } from 'express-handlebars' import config from './config.js' +import { homeController } from './controllers/index.js' async function main() { await connectDB(config.db) @@ -12,9 +13,7 @@ async function main() { app.set('view engine', 'handlebars') app.set('views', './views') - app.get('/', (req, res) => { - res.render('home', { title: 'Linux Odyssey Admin' }) - }) + app.get('/', homeController) app.listen(3001, () => { console.log('Server started on http://localhost:3001') diff --git a/packages/analytics/src/models/quests.js b/packages/analytics/src/models/quests.js new file mode 100644 index 0000000..7a0a3b3 --- /dev/null +++ b/packages/analytics/src/models/quests.js @@ -0,0 +1,24 @@ +import { Session } from '@linux-odyssey/models' + +export function sessionCount() { + return Session.find().count() +} + +export function sessionCompleted() { + return Session.find({ status: 'finished' }).count() +} + +export function averageTimeUsage() { + return Session.aggregate([ + { + $group: { + _id: '$quest', + average: { + $avg: { + $subtract: ['$finishedAt', '$createdAt'], + }, + }, + }, + }, + ]) +} diff --git a/packages/analytics/src/models/users.js b/packages/analytics/src/models/users.js new file mode 100644 index 0000000..4862af2 --- /dev/null +++ b/packages/analytics/src/models/users.js @@ -0,0 +1,6 @@ +import { User } from '@linux-odyssey/models' + +// eslint-disable-next-line import/prefer-default-export +export function userCount() { + return User.find().count() +} diff --git a/packages/analytics/views/home.handlebars b/packages/analytics/views/home.handlebars index 35a5107..5d8ce3e 100644 --- a/packages/analytics/views/home.handlebars +++ b/packages/analytics/views/home.handlebars @@ -1,2 +1,23 @@

Welcome to {{title}}

-

This is the content of the homepage.

\ No newline at end of file +

This is the content of the homepage.

+
+

Users

+ + + + + + + + + + + + + + + + + +
Registered Users{{userCount}}
Session Count{{sessionCount}}
Completed Session{{sessionCompleted}}
Completed Rate{{completedRate}}%
+
\ No newline at end of file diff --git a/server/src/containers/expiryChecker.js b/server/src/containers/expiryChecker.js index 41699cc..3ecc30c 100644 --- a/server/src/containers/expiryChecker.js +++ b/server/src/containers/expiryChecker.js @@ -16,7 +16,9 @@ export async function removeExpired() { sessions.map(async (session) => { console.log('Expiring session: ', session._id, session.containerId) await deleteContainer(session.containerId) - session.status = 'inactive' + if (session.status === 'active') { + session.status = 'inactive' + } session.containerId = null await session.save() }) From abf1ecddb401800c4cbf1b0bb848eab6ae048680 Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 16:17:47 +0800 Subject: [PATCH 04/15] feat: add router and css --- packages/analytics/public/css/style.css | 9 +++++++++ packages/analytics/src/index.js | 5 +++-- packages/analytics/src/router.js | 9 +++++++++ packages/analytics/views/layouts/main.handlebars | 1 + 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 packages/analytics/public/css/style.css create mode 100644 packages/analytics/src/router.js diff --git a/packages/analytics/public/css/style.css b/packages/analytics/public/css/style.css new file mode 100644 index 0000000..3f78b7a --- /dev/null +++ b/packages/analytics/public/css/style.css @@ -0,0 +1,9 @@ +table, +tr, +td, +th { + border-collapse: collapse; + border-spacing: 0; + width: 50%; + border: 2px solid black; +} diff --git a/packages/analytics/src/index.js b/packages/analytics/src/index.js index 3e4a4cb..463efca 100644 --- a/packages/analytics/src/index.js +++ b/packages/analytics/src/index.js @@ -2,7 +2,7 @@ import connectDB from '@linux-odyssey/models' import express from 'express' import { engine } from 'express-handlebars' import config from './config.js' -import { homeController } from './controllers/index.js' +import router from './router.js' async function main() { await connectDB(config.db) @@ -13,7 +13,8 @@ async function main() { app.set('view engine', 'handlebars') app.set('views', './views') - app.get('/', homeController) + app.use(router) + app.use(express.static('./public')) app.listen(3001, () => { console.log('Server started on http://localhost:3001') diff --git a/packages/analytics/src/router.js b/packages/analytics/src/router.js new file mode 100644 index 0000000..20b35bd --- /dev/null +++ b/packages/analytics/src/router.js @@ -0,0 +1,9 @@ +import { Router } from 'express' + +import { homeController } from './controllers/index.js' + +const router = Router() + +router.get('/', homeController) + +export default router diff --git a/packages/analytics/views/layouts/main.handlebars b/packages/analytics/views/layouts/main.handlebars index ce48582..c044eb7 100644 --- a/packages/analytics/views/layouts/main.handlebars +++ b/packages/analytics/views/layouts/main.handlebars @@ -1,6 +1,7 @@ {{title}} + {{{body}}} From c8c9a584d091330efe45bd0a664253114ef9e38e Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 17:09:50 +0800 Subject: [PATCH 05/15] fix: add social login to exist user --- server/src/auth/oauthVerify.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/src/auth/oauthVerify.js b/server/src/auth/oauthVerify.js index ce20d19..409fde3 100644 --- a/server/src/auth/oauthVerify.js +++ b/server/src/auth/oauthVerify.js @@ -15,7 +15,10 @@ export default async function oauthVerify(provider, profile, query, cb) { newUser[provider] = profile return cb(null, { newUser }) } - user[provider] = profile + user[provider] = { + id: profile.id, + displayName: profile.displayName, + } await user.save() } From 9e990a2fa45452672bf0e3cbaf8afd4bd180bc5e Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 17:10:17 +0800 Subject: [PATCH 06/15] feat: users list page --- packages/analytics/public/css/style.css | 8 +++- packages/analytics/src/controllers/users.js | 6 +++ packages/analytics/src/models/users.js | 45 ++++++++++++++++++++- packages/analytics/src/router.js | 2 + packages/analytics/views/users.handlebars | 23 +++++++++++ 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 packages/analytics/src/controllers/users.js create mode 100644 packages/analytics/views/users.handlebars diff --git a/packages/analytics/public/css/style.css b/packages/analytics/public/css/style.css index 3f78b7a..f77ad99 100644 --- a/packages/analytics/public/css/style.css +++ b/packages/analytics/public/css/style.css @@ -4,6 +4,12 @@ td, th { border-collapse: collapse; border-spacing: 0; - width: 50%; + width: 100%; border: 2px solid black; } + +th, +td { + width: 1px; + white-space: nowrap; +} diff --git a/packages/analytics/src/controllers/users.js b/packages/analytics/src/controllers/users.js new file mode 100644 index 0000000..5eb16b9 --- /dev/null +++ b/packages/analytics/src/controllers/users.js @@ -0,0 +1,6 @@ +import { userList } from '../models/users.js' + +// eslint-disable-next-line import/prefer-default-export +export async function userListController(req, res) { + res.render('users', { users: await userList() }) +} diff --git a/packages/analytics/src/models/users.js b/packages/analytics/src/models/users.js index 4862af2..9d1a545 100644 --- a/packages/analytics/src/models/users.js +++ b/packages/analytics/src/models/users.js @@ -1,6 +1,47 @@ -import { User } from '@linux-odyssey/models' +import { Session, User } from '@linux-odyssey/models' + +function loginMethods(user) { + const methods = [] + if (user.hashedPassword) methods.push('password') + if (user.google?.id) methods.push('google') + if (user.github?.id) methods.push('github') + return methods +} -// eslint-disable-next-line import/prefer-default-export export function userCount() { return User.find().count() } + +export async function userList() { + const users = await Session.aggregate([ + { + $group: { + _id: '$user', + count: { $sum: 1 }, + lastActivityAt: { $max: '$lastActivityAt' }, + }, + }, + { + $lookup: { + from: 'users', + localField: '_id', + foreignField: '_id', + as: 'userData', + }, + }, + { $unwind: '$userData' }, + { $sort: { 'userData.createdAt': 1 } }, + ]) + console.log(users) + return users.map(({ userData, count, lastActivityAt }) => { + const { username, email, createdAt } = userData + return { + username, + email, + createdAt: createdAt.toLocaleString(), + method: loginMethods(userData), + sessionCount: count, + lastActivityAt: lastActivityAt.toLocaleString(), + } + }) +} diff --git a/packages/analytics/src/router.js b/packages/analytics/src/router.js index 20b35bd..6e3b0ae 100644 --- a/packages/analytics/src/router.js +++ b/packages/analytics/src/router.js @@ -1,9 +1,11 @@ import { Router } from 'express' import { homeController } from './controllers/index.js' +import { userListController } from './controllers/users.js' const router = Router() router.get('/', homeController) +router.get('/users', userListController) export default router diff --git a/packages/analytics/views/users.handlebars b/packages/analytics/views/users.handlebars new file mode 100644 index 0000000..acc6233 --- /dev/null +++ b/packages/analytics/views/users.handlebars @@ -0,0 +1,23 @@ +

Users List

+
+ + + + + + + + + + {{#each users}} + + + + + + + + + {{/each}} +
UsernameEmailRegistration MethodRegistration TimeSessions CountLast Activity
{{username}}{{email}}{{method}}{{createdAt}}{{sessionCount}}{{lastActivityAt}}
+
\ No newline at end of file From d249207283fabbfbfccd3b1a5a5496c46f804cd0 Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 17:12:42 +0800 Subject: [PATCH 07/15] feat: add nav bar --- packages/analytics/views/layouts/main.handlebars | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/analytics/views/layouts/main.handlebars b/packages/analytics/views/layouts/main.handlebars index c044eb7..09e1d4a 100644 --- a/packages/analytics/views/layouts/main.handlebars +++ b/packages/analytics/views/layouts/main.handlebars @@ -4,6 +4,12 @@ + {{{body}}} \ No newline at end of file From 50e53b566752316641f28b8c349dd11cf9b4fd21 Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 17:43:12 +0800 Subject: [PATCH 08/15] feat: add error commands page --- .../analytics/src/controllers/commands.js | 9 +++++++ packages/analytics/src/models/commands.js | 26 +++++++++++++++++++ packages/analytics/src/router.js | 2 ++ packages/analytics/views/commands.handlebars | 22 ++++++++++++++++ packages/analytics/views/home.handlebars | 1 - .../analytics/views/layouts/main.handlebars | 1 + 6 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 packages/analytics/src/controllers/commands.js create mode 100644 packages/analytics/src/models/commands.js create mode 100644 packages/analytics/views/commands.handlebars diff --git a/packages/analytics/src/controllers/commands.js b/packages/analytics/src/controllers/commands.js new file mode 100644 index 0000000..4692652 --- /dev/null +++ b/packages/analytics/src/controllers/commands.js @@ -0,0 +1,9 @@ +import { errorCommands } from '../models/commands.js' + +// eslint-disable-next-line import/prefer-default-export +export async function commandListController(req, res) { + const payload = { + errorCommands: await errorCommands(), + } + res.render('commands', payload) +} diff --git a/packages/analytics/src/models/commands.js b/packages/analytics/src/models/commands.js new file mode 100644 index 0000000..2ea16de --- /dev/null +++ b/packages/analytics/src/models/commands.js @@ -0,0 +1,26 @@ +import { Command } from '@linux-odyssey/models' + +// eslint-disable-next-line import/prefer-default-export +export async function errorCommands() { + const commands = await Command.find({ error: { $ne: '' } }) + .populate({ + path: 'session', + populate: [ + { + path: 'user', + }, + { path: 'quest' }, + ], + }) + .exec() + return commands.map(({ command, error, createdAt, session }) => { + const { user, quest } = session + return { + command, + error, + createdAt: createdAt.toLocaleString(), + user: user.username, + quest: quest.id, + } + }) +} diff --git a/packages/analytics/src/router.js b/packages/analytics/src/router.js index 6e3b0ae..b6c9b98 100644 --- a/packages/analytics/src/router.js +++ b/packages/analytics/src/router.js @@ -2,10 +2,12 @@ import { Router } from 'express' import { homeController } from './controllers/index.js' import { userListController } from './controllers/users.js' +import { commandListController } from './controllers/commands.js' const router = Router() router.get('/', homeController) router.get('/users', userListController) +router.get('/commands', commandListController) export default router diff --git a/packages/analytics/views/commands.handlebars b/packages/analytics/views/commands.handlebars new file mode 100644 index 0000000..ed7078f --- /dev/null +++ b/packages/analytics/views/commands.handlebars @@ -0,0 +1,22 @@ +

Commands

+
+

Error commands

+ + + + + + + + + {{#each errorCommands}} + + + + + + + + {{/each}} +
CommandUserQuestErrorCreated At
{{command}}{{user}}{{quest}}{{error}}{{createdAt}}
+
\ No newline at end of file diff --git a/packages/analytics/views/home.handlebars b/packages/analytics/views/home.handlebars index 5d8ce3e..cd8148a 100644 --- a/packages/analytics/views/home.handlebars +++ b/packages/analytics/views/home.handlebars @@ -1,5 +1,4 @@

Welcome to {{title}}

-

This is the content of the homepage.

Users

diff --git a/packages/analytics/views/layouts/main.handlebars b/packages/analytics/views/layouts/main.handlebars index 09e1d4a..feb46cd 100644 --- a/packages/analytics/views/layouts/main.handlebars +++ b/packages/analytics/views/layouts/main.handlebars @@ -8,6 +8,7 @@ {{{body}}} From fe1f595f0f1fc88f89cab833428147679b5e04f7 Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 18:28:01 +0800 Subject: [PATCH 09/15] feat: add sessions page --- packages/analytics/public/css/style.css | 4 ++ packages/analytics/src/controllers/index.js | 2 +- .../analytics/src/controllers/sessions.js | 7 ++ packages/analytics/src/models/quests.js | 24 ------- packages/analytics/src/models/sessions.js | 67 +++++++++++++++++++ packages/analytics/src/router.js | 2 + .../analytics/views/layouts/main.handlebars | 1 + packages/analytics/views/sessions.handlebars | 25 +++++++ 8 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 packages/analytics/src/controllers/sessions.js delete mode 100644 packages/analytics/src/models/quests.js create mode 100644 packages/analytics/src/models/sessions.js create mode 100644 packages/analytics/views/sessions.handlebars diff --git a/packages/analytics/public/css/style.css b/packages/analytics/public/css/style.css index f77ad99..d973b00 100644 --- a/packages/analytics/public/css/style.css +++ b/packages/analytics/public/css/style.css @@ -1,3 +1,7 @@ +body { + font-family: 'sans'; +} + table, tr, td, diff --git a/packages/analytics/src/controllers/index.js b/packages/analytics/src/controllers/index.js index 283a03b..d5a6967 100644 --- a/packages/analytics/src/controllers/index.js +++ b/packages/analytics/src/controllers/index.js @@ -1,5 +1,5 @@ import { userCount } from '../models/users.js' -import { sessionCount, sessionCompleted } from '../models/quests.js' +import { sessionCount, sessionCompleted } from '../models/sessions.js' // eslint-disable-next-line import/prefer-default-export export async function homeController(req, res) { diff --git a/packages/analytics/src/controllers/sessions.js b/packages/analytics/src/controllers/sessions.js new file mode 100644 index 0000000..3da3ef4 --- /dev/null +++ b/packages/analytics/src/controllers/sessions.js @@ -0,0 +1,7 @@ +import { sessionList } from '../models/sessions.js' + +// eslint-disable-next-line import/prefer-default-export +export async function sessionListController(req, res) { + const sessions = await sessionList() + res.render('sessions', { sessions }) +} diff --git a/packages/analytics/src/models/quests.js b/packages/analytics/src/models/quests.js deleted file mode 100644 index 7a0a3b3..0000000 --- a/packages/analytics/src/models/quests.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Session } from '@linux-odyssey/models' - -export function sessionCount() { - return Session.find().count() -} - -export function sessionCompleted() { - return Session.find({ status: 'finished' }).count() -} - -export function averageTimeUsage() { - return Session.aggregate([ - { - $group: { - _id: '$quest', - average: { - $avg: { - $subtract: ['$finishedAt', '$createdAt'], - }, - }, - }, - }, - ]) -} diff --git a/packages/analytics/src/models/sessions.js b/packages/analytics/src/models/sessions.js new file mode 100644 index 0000000..9b429a8 --- /dev/null +++ b/packages/analytics/src/models/sessions.js @@ -0,0 +1,67 @@ +import { Session } from '@linux-odyssey/models' + +export function sessionCount() { + return Session.find().count() +} + +export function sessionCompleted() { + return Session.find({ status: 'finished' }).count() +} + +export function averageTimeUsage() { + return Session.aggregate([ + { + $group: { + _id: '$quest', + average: { + $avg: { + $subtract: ['$finishedAt', '$createdAt'], + }, + }, + }, + }, + ]) +} + +function formatTime(time) { + const seconds = Math.floor(time / 1000) + const minutes = Math.floor(seconds / 60) + const hours = Math.floor(minutes / 60) + return `${hours}h ${minutes % 60}m ${seconds % 60}s` +} + +export async function sessionList() { + const sessions = await Session.aggregate([ + { + $lookup: { + from: 'users', + localField: 'user', + foreignField: '_id', + as: 'user', + }, + }, + { $unwind: '$user' }, + { + $lookup: { + from: 'commands', + localField: '_id', + foreignField: 'session', + as: 'commands', + }, + }, + ]) + console.log(sessions) + return sessions.map( + ({ user, quest, status, createdAt, finishedAt, commands }) => { + return { + user: user.username, + quest, + status, + createdAt: createdAt.toLocaleString(), + finishedAt: finishedAt?.toLocaleString(), + usedTime: finishedAt ? formatTime(finishedAt - createdAt) : '', + commandCount: commands.length, + } + } + ) +} diff --git a/packages/analytics/src/router.js b/packages/analytics/src/router.js index b6c9b98..8194b55 100644 --- a/packages/analytics/src/router.js +++ b/packages/analytics/src/router.js @@ -3,11 +3,13 @@ import { Router } from 'express' import { homeController } from './controllers/index.js' import { userListController } from './controllers/users.js' import { commandListController } from './controllers/commands.js' +import { sessionListController } from './controllers/sessions.js' const router = Router() router.get('/', homeController) router.get('/users', userListController) router.get('/commands', commandListController) +router.get('/sessions', sessionListController) export default router diff --git a/packages/analytics/views/layouts/main.handlebars b/packages/analytics/views/layouts/main.handlebars index feb46cd..e269d7b 100644 --- a/packages/analytics/views/layouts/main.handlebars +++ b/packages/analytics/views/layouts/main.handlebars @@ -9,6 +9,7 @@
  • Home
  • Users
  • Commands
  • +
  • Sessions
  • {{{body}}} diff --git a/packages/analytics/views/sessions.handlebars b/packages/analytics/views/sessions.handlebars new file mode 100644 index 0000000..2d0c3f3 --- /dev/null +++ b/packages/analytics/views/sessions.handlebars @@ -0,0 +1,25 @@ +

    Sessions

    +
    +
    + + + + + + + + + + {{#each sessions}} + + + + + + + + + + {{/each}} +
    UserQuestStatusCreated AtFinished AtUsed TimeCommand Count
    {{user}}{{quest}}{{status}}{{createdAt}}{{finishedAt}}{{usedTime}}{{commandCount}}
    +
    \ No newline at end of file From 277a1aec79b323b7a61080e1c034e4fa33a0a21a Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 18:43:22 +0800 Subject: [PATCH 10/15] fix: remove unused populate --- packages/analytics/src/models/commands.js | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/analytics/src/models/commands.js b/packages/analytics/src/models/commands.js index 2ea16de..3abd2b0 100644 --- a/packages/analytics/src/models/commands.js +++ b/packages/analytics/src/models/commands.js @@ -2,25 +2,26 @@ import { Command } from '@linux-odyssey/models' // eslint-disable-next-line import/prefer-default-export export async function errorCommands() { - const commands = await Command.find({ error: { $ne: '' } }) + const commands = await Command.find({ + $and: [ + { error: { $exists: true } }, + { error: { $ne: null } }, + { error: { $ne: '' } }, + ], + }) .populate({ path: 'session', - populate: [ - { - path: 'user', - }, - { path: 'quest' }, - ], + populate: { path: 'user' }, }) .exec() return commands.map(({ command, error, createdAt, session }) => { const { user, quest } = session return { - command, - error, - createdAt: createdAt.toLocaleString(), - user: user.username, - quest: quest.id, + command: command.slice(0, 20), + error: error.slice(0, 50), + createdAt: createdAt?.toLocaleString(), + user: user?.username, + quest, } }) } From 4b2f20f384032757e8b8064d540bff33d94cb798 Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 18:43:38 +0800 Subject: [PATCH 11/15] fix: handle no value cases --- packages/analytics/src/models/sessions.js | 4 ++-- packages/analytics/src/models/users.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/analytics/src/models/sessions.js b/packages/analytics/src/models/sessions.js index 9b429a8..39988c7 100644 --- a/packages/analytics/src/models/sessions.js +++ b/packages/analytics/src/models/sessions.js @@ -57,10 +57,10 @@ export async function sessionList() { user: user.username, quest, status, - createdAt: createdAt.toLocaleString(), + createdAt: createdAt?.toLocaleString(), finishedAt: finishedAt?.toLocaleString(), usedTime: finishedAt ? formatTime(finishedAt - createdAt) : '', - commandCount: commands.length, + commandCount: commands?.length, } } ) diff --git a/packages/analytics/src/models/users.js b/packages/analytics/src/models/users.js index 9d1a545..0f7b81f 100644 --- a/packages/analytics/src/models/users.js +++ b/packages/analytics/src/models/users.js @@ -38,10 +38,10 @@ export async function userList() { return { username, email, - createdAt: createdAt.toLocaleString(), + createdAt: createdAt?.toLocaleString(), method: loginMethods(userData), sessionCount: count, - lastActivityAt: lastActivityAt.toLocaleString(), + lastActivityAt: lastActivityAt?.toLocaleString(), } }) } From a4f1c9fef1804f43664eff86654f07af17508ede Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 18:50:03 +0800 Subject: [PATCH 12/15] fix: remove debugging log --- packages/analytics/src/models/sessions.js | 1 - packages/analytics/src/models/users.js | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/analytics/src/models/sessions.js b/packages/analytics/src/models/sessions.js index 39988c7..2278f52 100644 --- a/packages/analytics/src/models/sessions.js +++ b/packages/analytics/src/models/sessions.js @@ -50,7 +50,6 @@ export async function sessionList() { }, }, ]) - console.log(sessions) return sessions.map( ({ user, quest, status, createdAt, finishedAt, commands }) => { return { diff --git a/packages/analytics/src/models/users.js b/packages/analytics/src/models/users.js index 0f7b81f..ae1aee6 100644 --- a/packages/analytics/src/models/users.js +++ b/packages/analytics/src/models/users.js @@ -32,7 +32,6 @@ export async function userList() { { $unwind: '$userData' }, { $sort: { 'userData.createdAt': 1 } }, ]) - console.log(users) return users.map(({ userData, count, lastActivityAt }) => { const { username, email, createdAt } = userData return { From 2257b4b8096cb0c09cb68224760538a987837591 Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 19:15:07 +0800 Subject: [PATCH 13/15] feat: session detail page --- .../analytics/src/controllers/sessions.js | 9 ++- packages/analytics/src/router.js | 6 +- .../analytics/views/sessionDetail.handlebars | 56 +++++++++++++++++++ packages/analytics/views/sessions.handlebars | 2 + 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 packages/analytics/views/sessionDetail.handlebars diff --git a/packages/analytics/src/controllers/sessions.js b/packages/analytics/src/controllers/sessions.js index 3da3ef4..47dc3bb 100644 --- a/packages/analytics/src/controllers/sessions.js +++ b/packages/analytics/src/controllers/sessions.js @@ -1,7 +1,12 @@ -import { sessionList } from '../models/sessions.js' +import { sessionList, sessionDetail } from '../models/sessions.js' -// eslint-disable-next-line import/prefer-default-export export async function sessionListController(req, res) { const sessions = await sessionList() res.render('sessions', { sessions }) } + +export async function sessionDetailController(req, res) { + const { id } = req.params + const session = await sessionDetail(id) + res.render('sessionDetail', { session }) +} diff --git a/packages/analytics/src/router.js b/packages/analytics/src/router.js index 8194b55..f5a458b 100644 --- a/packages/analytics/src/router.js +++ b/packages/analytics/src/router.js @@ -3,7 +3,10 @@ import { Router } from 'express' import { homeController } from './controllers/index.js' import { userListController } from './controllers/users.js' import { commandListController } from './controllers/commands.js' -import { sessionListController } from './controllers/sessions.js' +import { + sessionDetailController, + sessionListController, +} from './controllers/sessions.js' const router = Router() @@ -11,5 +14,6 @@ router.get('/', homeController) router.get('/users', userListController) router.get('/commands', commandListController) router.get('/sessions', sessionListController) +router.get('/sessions/:id', sessionDetailController) export default router diff --git a/packages/analytics/views/sessionDetail.handlebars b/packages/analytics/views/sessionDetail.handlebars new file mode 100644 index 0000000..71d8aa6 --- /dev/null +++ b/packages/analytics/views/sessionDetail.handlebars @@ -0,0 +1,56 @@ +

    {{title}}

    +
    + {{#with session}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Quest{{quest}}
    User{{user}}
    Status{{status}}
    Created At{{createdAt}}
    Finished At{{finishedAt}}
    Used Time{{usedTime}}
    Command Count{{commands.length}}
    + +

    Commands

    + + + + + + + + + + {{#each commands}} + + + + + + + + {{/each}} +
    CommandPWDOutputErrorCreated At
    {{command}}{{pwd}}{{output}}{{error}}{{createdAt}}
    + {{/with}} +
    \ No newline at end of file diff --git a/packages/analytics/views/sessions.handlebars b/packages/analytics/views/sessions.handlebars index 2d0c3f3..6fff971 100644 --- a/packages/analytics/views/sessions.handlebars +++ b/packages/analytics/views/sessions.handlebars @@ -4,6 +4,7 @@ User Quest + Status Created At Finished At @@ -14,6 +15,7 @@ {{user}} {{quest}} + Detail {{status}} {{createdAt}} {{finishedAt}} From ad08bde4c4c042b4b61c5047d866af8f8566d1b3 Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 19:15:24 +0800 Subject: [PATCH 14/15] feat: link error command to session detail page --- packages/analytics/src/models/commands.js | 1 + packages/analytics/src/models/sessions.js | 29 ++++++++++++++++++-- packages/analytics/views/commands.handlebars | 2 ++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/analytics/src/models/commands.js b/packages/analytics/src/models/commands.js index 3abd2b0..48ece73 100644 --- a/packages/analytics/src/models/commands.js +++ b/packages/analytics/src/models/commands.js @@ -22,6 +22,7 @@ export async function errorCommands() { createdAt: createdAt?.toLocaleString(), user: user?.username, quest, + session: session._id, } }) } diff --git a/packages/analytics/src/models/sessions.js b/packages/analytics/src/models/sessions.js index 2278f52..e290a8b 100644 --- a/packages/analytics/src/models/sessions.js +++ b/packages/analytics/src/models/sessions.js @@ -1,4 +1,4 @@ -import { Session } from '@linux-odyssey/models' +import { Command, Session } from '@linux-odyssey/models' export function sessionCount() { return Session.find().count() @@ -51,8 +51,9 @@ export async function sessionList() { }, ]) return sessions.map( - ({ user, quest, status, createdAt, finishedAt, commands }) => { + ({ _id, user, quest, status, createdAt, finishedAt, commands }) => { return { + _id, user: user.username, quest, status, @@ -64,3 +65,27 @@ export async function sessionList() { } ) } + +export async function sessionDetail(id) { + const session = await Session.findById(id).populate('user').exec() + const commands = (await Command.find({ session: id })).map( + ({ command, pwd, output, error, createdAt }) => ({ + command: command?.slice(0, 20), + pwd, + output: output?.slice(0, 50), + error: error?.slice(0, 50), + createdAt: createdAt?.toLocaleString(), + }) + ) + const { _id, user, quest, status, createdAt, finishedAt } = session + return { + _id, + user: user.username, + quest, + status, + createdAt: createdAt?.toLocaleString(), + finishedAt: finishedAt?.toLocaleString(), + usedTime: finishedAt ? formatTime(finishedAt - createdAt) : '', + commands, + } +} diff --git a/packages/analytics/views/commands.handlebars b/packages/analytics/views/commands.handlebars index ed7078f..16f23c2 100644 --- a/packages/analytics/views/commands.handlebars +++ b/packages/analytics/views/commands.handlebars @@ -6,6 +6,7 @@ Command User Quest + Session Error Created At @@ -14,6 +15,7 @@ {{command}} {{user}} {{quest}} + Detail {{error}} {{createdAt}} From 20927fe8aa15f5e81cfb283ec68117569a60237b Mon Sep 17 00:00:00 2001 From: wancat Date: Sat, 14 Oct 2023 19:43:13 +0800 Subject: [PATCH 15/15] feat: docker setup & deployment --- .github/workflows/ci_cd.yml | 8 ++++++++ docker-compose.prod.yml | 15 +++++++++++++++ docker-compose.yml | 17 +++++++++++++++++ packages/analytics/Dockerfile | 19 +++++++++++++++++++ packages/analytics/Dockerfile.dev | 16 ++++++++++++++++ packages/analytics/package.json | 2 +- packages/analytics/src/config.js | 8 +++++++- packages/analytics/src/index.js | 4 ++-- packages/models/package.json | 1 - packages/models/session.js | 5 ++--- 10 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 packages/analytics/Dockerfile create mode 100644 packages/analytics/Dockerfile.dev diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 87ab406..ec3dd98 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -80,6 +80,14 @@ jobs: push: true tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/linux-odyssey:app + - name: Build analytics + uses: docker/build-push-action@v2 + with: + context: . + file: ./packages/analytics/Dockerfile + push: true + tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/linux-odyssey:analytics + - name: Build base image uses: docker/build-push-action@v2 with: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 1883512..8eacdc4 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -25,6 +25,21 @@ services: environment: - MONGO_URL=mongodb://user:user-password@db:27017/odyssey-test - DOCKER_NETWORK=linux-odyssey-players + + analytics: + image: lancatlin/linux-odyssey:analytics + build: + context: . + dockerfile: packages/analytics/Dockerfile + depends_on: + - db + networks: + - internal + ports: + - '3001:3001' + environment: + - MONGO_URL=mongodb://user:user-password@db:27017/odyssey-test + db: image: mongo restart: always diff --git a/docker-compose.yml b/docker-compose.yml index 30253cf..a6483c9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,6 +39,23 @@ services: - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID} - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET} + + analytics: + build: + context: . + dockerfile: packages/analytics/Dockerfile.dev + depends_on: + - db + networks: + - internal + ports: + - '3001:3001' + environment: + - MONGO_URL=mongodb://db:27017/odyssey-test + volumes: + - ./packages/analytics:/app/packages/analytics + - ./packages/models:/app/packages/models + db: image: mongo networks: diff --git a/packages/analytics/Dockerfile b/packages/analytics/Dockerfile new file mode 100644 index 0000000..69f71f4 --- /dev/null +++ b/packages/analytics/Dockerfile @@ -0,0 +1,19 @@ +FROM node + +WORKDIR /app +COPY ./package.json yarn.lock ./ +COPY packages/analytics/package.json ./packages/analytics/package.json +COPY packages/models/package.json ./packages/models/package.json +RUN yarn install --frozen-lockfile --production + +COPY packages/analytics ./packages/analytics +COPY packages/models ./packages/models + +WORKDIR /app/packages/analytics + +ENV NODE_ENV=production +ENV HOST=0.0.0.0 +ENV PORT=3001 +EXPOSE 3001 + +CMD [ "yarn", "start" ] \ No newline at end of file diff --git a/packages/analytics/Dockerfile.dev b/packages/analytics/Dockerfile.dev new file mode 100644 index 0000000..1262872 --- /dev/null +++ b/packages/analytics/Dockerfile.dev @@ -0,0 +1,16 @@ +FROM node + +WORKDIR /app +COPY ./package.json yarn.lock ./ +COPY packages/analytics/package.json ./packages/analytics/package.json +COPY packages/models/package.json ./packages/models/package.json +RUN yarn install --frozen-lockfile + +WORKDIR /app/packages/analytics + +ENV NODE_ENV=development +ENV HOST=0.0.0.0 +ENV PORT=3001 +EXPOSE 3001 + +CMD [ "yarn", "dev" ] diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 56b62de..53eda5a 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -1,7 +1,7 @@ { "name": "analytics", "version": "1.0.0", - "main": "index.js", + "main": "src/index.js", "private": true, "type": "module", "license": "GPL", diff --git a/packages/analytics/src/config.js b/packages/analytics/src/config.js index fa291ff..00e1afd 100644 --- a/packages/analytics/src/config.js +++ b/packages/analytics/src/config.js @@ -1,3 +1,9 @@ -export default { +const config = { + host: process.env.HOST || 'localhost', + port: process.env.PORT || 3001, db: process.env.MONGO_URL || 'mongodb://localhost:27017/odyssey-test', } + +config.baseUrl = process.env.BASE_URL || `http://${config.host}:${config.port}` + +export default config diff --git a/packages/analytics/src/index.js b/packages/analytics/src/index.js index 463efca..6977ab0 100644 --- a/packages/analytics/src/index.js +++ b/packages/analytics/src/index.js @@ -16,8 +16,8 @@ async function main() { app.use(router) app.use(express.static('./public')) - app.listen(3001, () => { - console.log('Server started on http://localhost:3001') + app.listen(config.port, config.host, () => { + console.log(`Server started on ${config.baseUrl}`) }) } diff --git a/packages/models/package.json b/packages/models/package.json index 1dd49ae..d5f58b0 100644 --- a/packages/models/package.json +++ b/packages/models/package.json @@ -6,7 +6,6 @@ "license": "GPL", "exports": "./index.js", "dependencies": { - "@linux-odyssey/file-graph": "*", "mongoose": "^7.6.0" } } diff --git a/packages/models/session.js b/packages/models/session.js index ddb4fad..85568a1 100644 --- a/packages/models/session.js +++ b/packages/models/session.js @@ -1,5 +1,4 @@ import { model, Schema } from 'mongoose' -import { FileNode } from '@linux-odyssey/file-graph' const nodeSchema = new Schema({ path: String, @@ -58,10 +57,10 @@ const Session = model( hints: [String], graph: { type: nodeSchema, - default: new FileNode({ + default: { path: '/', type: 'folder', - }), + }, }, }, { timestamps: true }