{"id":15728812,"url":"https://github.com/tiagostutz/demo-warehouse-software","last_synced_at":"2025-05-13T05:06:07.142Z","repository":{"id":45944424,"uuid":"384937613","full_name":"tiagostutz/demo-warehouse-software","owner":"tiagostutz","description":"A simple demo of a warehouse software with Typescript, PostgreSQL, Prisma, Golang, NextJS...","archived":false,"fork":false,"pushed_at":"2023-06-15T17:59:22.000Z","size":2342,"stargazers_count":6,"open_issues_count":13,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-13T05:05:59.366Z","etag":null,"topics":["golang","jest","nextjs","postgresql","prisma","testing","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tiagostutz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2021-07-11T12:03:22.000Z","updated_at":"2025-04-24T10:59:18.000Z","dependencies_parsed_at":"2024-10-24T21:22:45.765Z","dependency_job_id":"2fa12b05-d340-4418-b9d9-7b65de0b479c","html_url":"https://github.com/tiagostutz/demo-warehouse-software","commit_stats":{"total_commits":41,"total_committers":3,"mean_commits":"13.666666666666666","dds":"0.12195121951219512","last_synced_commit":"4144b82c16778521b8e3871a7c20abbda94df4a9"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiagostutz%2Fdemo-warehouse-software","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiagostutz%2Fdemo-warehouse-software/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiagostutz%2Fdemo-warehouse-software/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tiagostutz%2Fdemo-warehouse-software/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tiagostutz","download_url":"https://codeload.github.com/tiagostutz/demo-warehouse-software/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253877508,"owners_count":21977643,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["golang","jest","nextjs","postgresql","prisma","testing","typescript"],"created_at":"2024-10-03T23:06:32.051Z","updated_at":"2025-05-13T05:06:07.126Z","avatar_url":"https://github.com/tiagostutz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![This is a Poppins project](https://raw.githubusercontent.com/bancodobrasil/poppins/master/badge-poppins.svg)](https://github.com/bancodobrasil/poppins)\n## This project was made for first-time contributors and open source beginners\n\nThis project follows the [Poppins manifesto guidelines](https://github.com/bancodobrasil/poppins) as part of it's community principles and policies, focusing all the decisions and interactions on providing open source beginners mentorship with real and relevant experiences, respecting each learning pace, background experience, academic formation, questions, suggestions, doubts and opinion. \n\n## Contribute now!\n\nSo, let's start contributing! **Open an issue asking for a task to be done by you**. A mentor/maintainer will come and provide a technical overview of the project and what are the possibles ways of contributing to the project. You will discuss the options and a suitable issue will be assigned or created to you. \n\nThat's it. Just make yourself at home and good luck!\n\n\u003cbr/\u003e\n\n# Demo Warehouse Software\nA simple demo of a warehouse software with TypeScript, PostgreSQL, Prisma, Go, NextJS...\n\n![sample interaction](assets/simple-interaction.gif)\n\n## Getting started\n\n### Option 1\n\n```bash\ngit clone https://github.com/tiagostutz/demo-warehouse-software\n```\n\n```bash\ndocker-compose up\n```\n\nWait for the services to be ready and then populate the database with using the file watch:\n\n```bash\ncp assets/inventory.json local-data/incoming/article/\n```\n\n```bash\ncp assets/products.json local-data/incoming/product/\n```\n\n```bash\ncd web-app\nyarn install\nyarn build\nyarn start\n```\n\nOpen [http://localhost:3000](http://localhost:3000) on your Browser and check\n\n### Option 2\n\n1) Create this docker-compose.yml:\n\n```yaml\nversion: \"3.7\"\n\nservices:\n  db:\n    image: tiagostutz/warehouse-demo-postgres:0.0.3\n    environment:\n      - POSTGRES_DB=demo-warehouse\n      - POSTGRES_PASSWORD=123456\n      - POSTGRES_INITDB_ARGS=--debug\n    ports:\n      - 5432:5432\n\n  api-backend:\n    image: tiagostutz/warehouse-demo-api-backend:0.0.3\n    ports:\n      - 4000:4000\n    environment:\n      - DATABASE_URL=postgres://postgres:123456@db:5432/demo-warehouse\n\n  database-updater:\n    image: tiagostutz/warehouse-demo-database-updater:0.0.3\n    volumes:\n      - ./local-data:/app/data\n    environment:\n      - LOG_LEVEL=debug\n      - WAREHOUSE_ARTICLE_ENDPOINT=http://api-backend:4000/article\n      - WAREHOUSE_PRODUCT_ENDPOINT=http://api-backend:4000/product\n```\n\nAnd bring it up:\n\n```bash\ndocker-compose up\n```\n\n2) After all the services are up, check that the database is clean by executing:\n\n```bash\ncurl http://localhost:4000/article\n```\n\n```bash\ncurl http://localhost:4000/product\n```\n\nThey should return and empty array `[]` as the response.\n\n3) Now let's put some Articles from the [inventory.json](assets/inventory.json) file. To do this, you need to copy this file to the folder the database auto-updater is watching for. Execute this:\n\n```bash\ncp assets/inventory.json local-data/incoming/article/\n```\n\nCheck again the return of the API:\n\n```bash\ncurl http://localhost:4000/article\n```\n\n4) Now let's put some Products from the [products.json](assets/products.json) file. To do this, you need to copy this file to the folder the database auto-updater is watching for. Execute this:\n\n```bash\ncp assets/products.json local-data/incoming/product/\n```\n\nCheck again the return of the API:\n\n```bash\ncurl http://localhost:4000/product\n```\n\n5) Let's get some details on the products created, like the quantity available based on the invetory stock:\n\n```bash\ncurl http://localhost:4000/product/1\n```\n\n```bash\ncurl http://localhost:4000/product/2\n```\n\nIf all went as expected, the `quantityAvailable` of this Product with **id=1** should be `2` and of the Product with **id=2** should be `1`.\n\n6) Finally, let's update the inventory stock (reduce) simulating as if a second product was bought and let's check the quantity of the first:\n\n```bash\ncurl --location --request POST 'http://localhost:4000/article/stock-update/by/product/2' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"quantity\": 1\n}'\n```\n\nAnd let's check how the quantity available of the Products we have now:\n\n```bash\ncurl http://localhost:4000/product/1\n```\n\nProduct with **id=1** should have **quantityAvailable=1**\n\n```bash\ncurl http://localhost:4000/product/2\n```\n\nProduct with **id=2** should have **quantityAvailable=0**\n\n\n## Overview of the Stack\n\n* **Frontend:** NextJS with FaaS that makes the requests to the **API Backend**\n* **API Backend**: Typescript application that uses **ExpressJS** to handle API routing, **Prisma** as ORM to access Database and **JEST** for testing.\n* **Database Auto-updater**: Golang application that watches for files being placed on a given folder and starts a Pipeline that will end up making a request to the **API Backend** to create Article and Products read and converted from files\n\n## Development Mode\n\nTo run each part individually in development mode, follow the steps bellow\n### API Backend\n\nTo run api-backend in development mode, first clone this repo:\n\n```bash\ngit clone https://github.com/tiagostutz/demo-warehouse-software.git\n```\n\nBring the database up:\n\n```bash\ndocker-compose up db\n```\n\nThen go to the [api-backend](api-backend) folder and run\n\n```bash\nyarn install\n```\n\nRun the tests:\n\n```bash\nyarn test\n```\n\nStart the API in development mode:\n\n```bash\nyarn run dev\n```\n\n### Database auto-updater\n\nFirst, bring the database and the api-backend up (described in the previous session).\n\nAfter that, run\n\n```bash\ngo mod download\n```\n\nThen, to run the tests run:\n\n```bash\ngo test ./...\n```\n\n## Evolution Stages\n\n**Stage 1** (current implementation): no security, no load handling, no caching\n![stage 1 overview](assets/system-design-stage-1.jpg)\n\n**Stage 2** (goal of this project): security, load balancing one level (API Gateway), no caching\n![stage 2 overview](assets/system-design-stage-2.jpg)\n\n**Stage 3** (start production): security, load balancing one level (API Gateway), observability, caching\n![stage 3 overview](assets/system-design-stage-3.jpg)\n\n**Stage 4** (scaling to the cloud): security, load handling, caching, observability, database replica/shard, job scheduling with queues and workflow management\n![stage 4 overview](assets/system-design-stage-4.jpg)\n\n## Testing\n\nThere are two levels of tests: component/service/unit level and integration/API level test.\n\nRunning **API Backend** tests:\n\n```bash\nyarn run test\n```\n\nTo run the **Database Auto-updater** integrated tests, you need the database and one instance of the API Backend up at **localhost:4000**, then run:\n\n```bash\ngo test ./...\n```\n\n### API Backend\n\nThe tests here are at folders names `tests` and the files has a `.test.ts` suffix. To run the tests:\n\n```bash\nyarn run test\n```\n\n### Database Auto-updater\n\n## Architecture overview and Design decisions\n\n- Pros and cons\n- Other possibilities\n- Kong API Gateway\n- Sidecar/Ambassador to hide from the Business Logic this complexity\n\n### Observability\n\n- Healthcheck\n  - `/health`\n  - `/ready`\n- Prometheus Metrics:\n  - Database updater\n  - API Backend\n- Grafana\n\n### Prisma as an ORM (and why not GraphQL?)\n\nWhat happens when running:\n\n```bash\nyarn install @prisma/client\n```\n\nThe install command automatically invokes prisma generate for you which reads your Prisma schema and generates a version of Prisma Client that is tailored to your models.\nWhenever you make changes to your Prisma schema in the future, you manually need to invoke `npx prisma generate` in order to accomodate the changes in your Prisma Client API.\n\n- More at [https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/install-prisma-client-typescript-postgres/](https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/install-prisma-client-typescript-postgres/)\n\n- Used the defaults of Prisma to generate a Database, but if the data modeling would be subject to a Data Administration process with data/terms dictionary, conventions, abbreviations and that kind of stuff, some additional configuration would be needed on the [schema.prisma](api-backend/schema.prisma) definition.\n\n```bash\nDATABASE_URL=postgres://postgres:123456@localhost:5432/demo-warehouse npx prisma migrate dev --name init\n```\n\n- **GraphQL**: definitely would be a good option, but there are some scenarios we need specific business logic that would need some code working. But for data fecthing and mutation to database, good one. The endpoints that need additional logic could expose those endpoints as regular APIs and use the GraphQL to fetch and mutate data.\n- **Migration tool demo**:\n  - started with ON DELETE CASCADE for all FKs\n  - then ON DELETE RESTRICT for all FKs\n  - then ON DELETE RESTRICT for Article ON DELETE CASCADE for Product\n\n```bash\nDATABASE_URL=postgres://postgres:123456@localhost:5432/demo-warehouse npx prisma migrate dev --name init\n```\n\n### TypeScript mixed with pure JavaScript\n\nIf there's no domain involved or for a more integration and \"flow setup\" kind of code, go with vanilla JavaScript. If there's model, business logic or heavy componentization, go with TypeScript.\n\n### Thoughts on scaling the solution\n\n- Change the load from watching files to consuming a queue\n- If a need for a more complex enrichment of the data, consider using a Workflow/pipeline orchestrator (like Netflix Conductor)\n\n## Software Highlevel Spec\n\nThis software should hold **articles**, and the articles should contain:\n\n- identification number\n- name\n- available stock\n\nIt should be possible to **load articles into the software from a file**, see the provided [inventory.json](inventory.json) sample file.\n\nThe warehouse software should also have **products**, products are made of different articles. Products should have:\n\n- name\n- price\n- list of articles of which they are made from with a quantity\n\nThe products should also be **loaded from a file**, see the provided [products.json](products.json) sample file.\n\nThe warehouse should have at least the following functionality;\n\n- Get all products and quantity of each that is available with the current inventory\n- Remove(Sell) a product and update the inventory accordingly\n\n\n## Awesome Poppins projects looking for contributors:\n\nHere's a list of some more curated Poppins projects:\n- [First Contributions Repository](https://github.com/firstcontributions/first-contributions): This project is designed to help beginners make their very first contributions to open source projects. \n- [Contribute to this Project](https://github.com/Syknapse/Contribute-To-This-Project): This is for absolute beginners. If you know how to write and edit an anchor tag \u003ca href=\"\" target=\"\"\u003e\u003c/a\u003e then you're ready to start contributing! \n- [Contribute to open source](https://github.com/danthareja/contribute-to-open-source):\nLearn the GitHub workflow by contributing code in a fun simulation project.\n- [goodfirstissue.dev](https://github.com/deepsourcelabs/good-first-issue): goodfirstissue.dev has a list of project repositories with the `good first issue` tag. Project moderators add this tag to help beginners get involved with their projects. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiagostutz%2Fdemo-warehouse-software","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftiagostutz%2Fdemo-warehouse-software","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiagostutz%2Fdemo-warehouse-software/lists"}