{"id":49587257,"url":"https://github.com/theastralprogrammer0/minter-test","last_synced_at":"2026-05-03T23:02:45.219Z","repository":{"id":300328410,"uuid":"1005896963","full_name":"theAstralProgrammer0/minter-test","owner":"theAstralProgrammer0","description":"This is the minting engine backend API prototype test-drive for Ticqquete NFTs.","archived":false,"fork":false,"pushed_at":"2025-06-21T03:47:22.000Z","size":0,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-21T04:31:51.021Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theAstralProgrammer0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-21T03:31:31.000Z","updated_at":"2025-06-21T03:47:25.000Z","dependencies_parsed_at":"2025-06-21T04:31:52.504Z","dependency_job_id":"c5b66707-df13-4acb-96fd-31881e3a2de9","html_url":"https://github.com/theAstralProgrammer0/minter-test","commit_stats":null,"previous_names":["theastralprogrammer0/minter-test"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/theAstralProgrammer0/minter-test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAstralProgrammer0%2Fminter-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAstralProgrammer0%2Fminter-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAstralProgrammer0%2Fminter-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAstralProgrammer0%2Fminter-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theAstralProgrammer0","download_url":"https://codeload.github.com/theAstralProgrammer0/minter-test/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theAstralProgrammer0%2Fminter-test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32587824,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T22:12:39.696Z","status":"ssl_error","status_checked_at":"2026-05-03T22:09:10.534Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-03T23:02:44.277Z","updated_at":"2026-05-03T23:02:45.214Z","avatar_url":"https://github.com/theAstralProgrammer0.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"I want to create a project called ``files_manager`` using the tasks and\ntutorials given in the File Manager project below...:\n\nTask-Tutorials:\n\u003cblockquote\u003e\nThis project is a summary of this back-end trimester:\nauthentication, NodeJS, MongoDB, Redis, pagination and background processing.\n\nThe objective is to build a simple platform to upload and view files:\n\n- User authentication via a token\n\n- List all files\n\n- Upload a new file\n\n- Change permission of a file\n\n- View a file\n\n- Generate thumbnails for images\n\nYou will be guided step by step for building it, but you have some freedoms of\nimplementation, split in more files etc… (utils folder will be your friend)\n\nOf course, this kind of service already exists in the real life - it’s a\nlearning purpose to assemble each piece and build a full product.\n\nEnjoy!\n\n### Resources\n\n#### Read or watch:\n\n[Node JS getting started](https://nodejs.org/en/learn/getting-started/introduction-to-nodejs)\n[Process API doc](https://node.readthedocs.io/en/latest/api/process/)\n[Express getting started](https://expressjs.com/en/starter/installing.html)\n[Mocha documentation](https://mochajs.org/)\n[Nodemon documentation](https://github.com/remy/nodemon#nodemon)\n[MongoDB](https://github.com/mongodb/node-mongodb-native)\n[Bull](https://github.com/OptimalBits/bull)\n[Image thumbnail](https://www.npmjs.com/package/image-thumbnail)\n[Mime-Types](https://www.npmjs.com/package/mime-types)\n[Redis](https://github.com/redis/node-redis)\n\n\n### Learning Objectives\n\nAt the end of this project, you are expected to be able to explain to anyone,\nwithout the help of Google:\n\n- how to create an API with Express\n- how to authenticate a user\n- how to store data in MongoDB\n- how to store temporary data in Redis\n- how to setup and use a background worker\n\n### Requirements\n\n- Allowed editors: vi, vim, emacs, Visual Studio Code\n- All your files will be interpreted/compiled on Ubuntu 18.04 LTS using node (version 12.x.x)\n- All your files should end with a new line\n- A README.md file, at the root of the folder of the project, is mandatory\n- Your code should use the js extension\n- Your code will be verified against lint using ESLint\n\n### Provided Files\n\n**package.json**\n```package.json\n{\n  \"name\": \"files_manager\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"lint\": \"./node_modules/.bin/eslint\",\n    \"check-lint\": \"lint [0-9]*.js\",\n    \"start-server\": \"nodemon --exec babel-node --presets @babel/preset-env ./server.js\",\n    \"start-worker\": \"nodemon --exec babel-node --presets @babel/preset-env ./worker.js\",\n    \"dev\": \"nodemon --exec babel-node --presets @babel/preset-env\",\n    \"test\": \"./node_modules/.bin/mocha --require @babel/register --exit\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"bull\": \"^3.16.0\",\n    \"chai-http\": \"^4.3.0\",\n    \"express\": \"^4.17.1\",\n    \"image-thumbnail\": \"^1.0.10\",\n    \"mime-types\": \"^2.1.27\",\n    \"mongodb\": \"^3.5.9\",\n    \"redis\": \"^2.8.0\",\n    \"sha1\": \"^1.1.1\",\n    \"uuid\": \"^8.2.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.8.0\",\n    \"@babel/core\": \"^7.8.0\",\n    \"@babel/node\": \"^7.8.0\",\n    \"@babel/preset-env\": \"^7.8.2\",\n    \"@babel/register\": \"^7.8.0\",\n    \"chai\": \"^4.2.0\",\n    \"chai-http\": \"^4.3.0\",\n    \"mocha\": \"^6.2.2\",\n    \"nodemon\": \"^2.0.2\",\n    \"eslint\": \"^6.4.0\",\n    \"eslint-config-airbnb-base\": \"^14.0.0\",\n    \"eslint-plugin-import\": \"^2.18.2\",\n    \"eslint-plugin-jest\": \"^22.17.0\",\n    \"request\": \"^2.88.0\",\n    \"sinon\": \"^7.5.0\"\n  }\n}\n```\n\n**.eslintrc.js**\n```.eslintrc.js\nmodule.exports = {\n    env: {\n      browser: false,\n      es6: true,\n      jest: true,\n    },\n    extends: [\n      'airbnb-base',\n      'plugin:jest/all',\n    ],\n    globals: {\n      Atomics: 'readonly',\n      SharedArrayBuffer: 'readonly',\n    },\n    parserOptions: {\n      ecmaVersion: 2018,\n      sourceType: 'module',\n    },\n    plugins: ['jest'],\n    rules: {\n      'max-classes-per-file': 'off',\n      'no-underscore-dangle': 'off',\n      'no-console': 'off',\n      'no-shadow': 'off',\n      'no-restricted-syntax': [\n        'error',\n        'LabeledStatement',\n        'WithStatement',\n      ],\n    },\n    overrides:[\n      {\n        files: ['*.js'],\n        excludedFiles: 'babel.config.js',\n      }\n    ]\n};\n```\n\n**babel.config.js**\n```babel.config.js\nmodule.exports = {\n    presets: [\n      [\n        '@babel/preset-env',\n        {\n          targets: {\n            node: 'current',\n          },\n        },\n      ],\n    ],\n};\n```\n-------------------\u003e Can I provide the tasks?\n\n### Tasks\n\n#### 0. Redis utils\nInside the folder ``utils``, create a file ``redis.js`` that contains the class\n``RedisClient``.\n\n``RedisClient`` should have:\n\n- the constructor that creates a client to Redis:\n  - any error of the redis client must be displayed in the console (you should\n    use ``on('error')`` of the redis client)\n- a function ``isAlive`` that returns ``true`` when the connection to Redis is a\n  success otherwise, ``false``\n- an asynchronous function ``get`` that takes a string key as argument and returns\n  the Redis value stored for this key\n- an asynchronous function ``set`` that takes a string key, a value and a duration\n  in second as arguments to store it in Redis (with an expiration set by the\n  duration argument)\n- an asynchronous function ``del`` that takes a string key as argument and remove\n  the value in Redis for this key\n\nAfter the class definition, create and export an instance of ``RedisClient`` called ``redisClient``.\n\n```terminal\nbob@dylan:~$ cat main.js\nimport redisClient from './utils/redis';\n\n(async () =\u003e {\n    console.log(redisClient.isAlive());\n    console.log(await redisClient.get('myKey'));\n    await redisClient.set('myKey', 12, 5);\n    console.log(await redisClient.get('myKey'));\n\n    setTimeout(async () =\u003e {\n        console.log(await redisClient.get('myKey'));\n    }, 1000*10)\n})();\n\nbob@dylan:~$ npm run dev main.js\ntrue\nnull\n12\nnull\nbob@dylan:~$\n```\n\n**Repo:**\n\n- GitHub repository: ``minter_test``\n- File: ``utils/redis.js``\n\n#### 1. MongoDB utils\nInside the folder ``utils``, create a file ``db.js`` that contains the class\n``DBClient``.\n\n``DBClient`` should have:\n\n- the constructor that creates a client to MongoDB:\n  - host: from the environment variable ``DB_HOST`` or default: ``localhost``\n  - port: from the environment variable ``DB_PORT`` or default: ``27017``\n  - database: from the environment variable ``DB_DATABASE`` or default:\n    ``files_manager``\n- a function ``isAlive`` that returns ``true`` when the connection to MongoDB is a\n  success otherwise, ``false``\n- an asynchronous function ``nbUsers`` that returns the number of documents in the\n  collection ``users``\n- an asynchronous function ``nbFiles`` that returns the number of documents in the\n  collection ``files``\n\nAfter the class definition, create and export an instance of ``DBClient called\n``dbClient``.\n\n```terminal\nbob@dylan:~$ cat main.js\nimport dbClient from './utils/db';\n\nconst waitConnection = () =\u003e {\n    return new Promise((resolve, reject) =\u003e {\n        let i = 0;\n        const repeatFct = async () =\u003e {\n            await setTimeout(() =\u003e {\n                i += 1;\n                if (i \u003e= 10) {\n                    reject()\n                }\n                else if(!dbClient.isAlive()) {\n                    repeatFct()\n                }\n                else {\n                    resolve()\n                }\n            }, 1000);\n        };\n        repeatFct();\n    })\n};\n\n(async () =\u003e {\n    console.log(dbClient.isAlive());\n    await waitConnection();\n    console.log(dbClient.isAlive());\n    console.log(await dbClient.nbUsers());\n    console.log(await dbClient.nbFiles());\n})();\n\nbob@dylan:~$ npm run dev main.js\nfalse\ntrue\n4\n30\nbob@dylan:~$\n```\n\n**Repo:**\n\n- GitHub repository: alx-files_manager\n- File: utils/db.js\n\n#### 2. First API\nInside server.js, create the Express server:\n\nit should listen on the port set by the environment variable PORT or by default 5000\nit should load all routes from the file routes/index.js\nInside the folder routes, create a file index.js that contains all endpoints of our API:\n\nGET /status =\u003e AppController.getStatus\nGET /stats =\u003e AppController.getStats\nInside the folder controllers, create a file AppController.js that contains the definition of the 2 endpoints:\n\nGET /status should return if Redis is alive and if the DB is alive too by using the 2 utils created previously: { \"redis\": true, \"db\": true } with a status code 200\nGET /stats should return the number of users and files in DB: { \"users\": 12, \"files\": 1231 } with a status code 200\nusers collection must be used for counting all users\nfiles collection must be used for counting all files\nTerminal 1:\n\nbob@dylan:~$ npm run start-server\nServer running on port 5000\n...\nTerminal 2:\n\nbob@dylan:~$ curl 0.0.0.0:5000/status ; echo \"\"\n{\"redis\":true,\"db\":true}\nbob@dylan:~$ \nbob@dylan:~$ curl 0.0.0.0:5000/stats ; echo \"\"\n{\"users\":4,\"files\":30}\nbob@dylan:~$ \nRepo:\n\nGitHub repository: alx-files_manager\nFile: server.js, routes/index.js, controllers/AppController.js\n\n#### 3. Create a new user\nNow that we have a simple API, it’s time to add users to our database.\n\nIn the file routes/index.js, add a new endpoint:\n\nPOST /users =\u003e UsersController.postNew\nInside controllers, add a file UsersController.js that contains the new endpoint:\n\nPOST /users should create a new user in DB:\n\nTo create a user, you must specify an email and a password\nIf the email is missing, return an error Missing email with a status code 400\nIf the password is missing, return an error Missing password with a status code 400\nIf the email already exists in DB, return an error Already exist with a status code 400\nThe password must be stored after being hashed in SHA1\nThe endpoint is returning the new user with only the email and the id (auto generated by MongoDB) with a status code 201\nThe new user must be saved in the collection users:\nemail: same as the value received\npassword: SHA1 value of the value received\nbob@dylan:~$ curl 0.0.0.0:5000/users -XPOST -H \"Content-Type: application/json\" -d '{ \"email\": \"bob@dylan.com\", \"password\": \"toto1234!\" }' ; echo \"\"\n{\"id\":\"5f1e7d35c7ba06511e683b21\",\"email\":\"bob@dylan.com\"}\nbob@dylan:~$ \nbob@dylan:~$ echo 'db.users.find()' | mongo files_manager\n{ \"_id\" : ObjectId(\"5f1e7d35c7ba06511e683b21\"), \"email\" : \"bob@dylan.com\", \"password\" : \"89cad29e3ebc1035b29b1478a8e70854f25fa2b2\" }\nbob@dylan:~$ \nbob@dylan:~$ \nbob@dylan:~$ curl 0.0.0.0:5000/users -XPOST -H \"Content-Type: application/json\" -d '{ \"email\": \"bob@dylan.com\", \"password\": \"toto1234!\" }' ; echo \"\"\n{\"error\":\"Already exist\"}\nbob@dylan:~$ \nbob@dylan:~$ curl 0.0.0.0:5000/users -XPOST -H \"Content-Type: application/json\" -d '{ \"email\": \"bob@dylan.com\" }' ; echo \"\"\n{\"error\":\"Missing password\"}\nbob@dylan:~$ \nRepo:\n\nGitHub repository: alx-files_manager\nFile: utils/, routes/index.js, controllers/UsersController.js\n\n\n#### 4. Authenticate a user\n\n#### 5. First File\n\n#### 6. Get and list file\n\n#### 7. File publish/unpublish\n\n#### 8. File data\n\n#### 9. Image Thumbnails\n\n#### 10. Tests!\n\n#### 11. New user - welcome email\n\n\u003c/blockquote\u003e]\n\n\n...to be aligned with \nCompose a readme that allows me\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheastralprogrammer0%2Fminter-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheastralprogrammer0%2Fminter-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheastralprogrammer0%2Fminter-test/lists"}