{"id":18000866,"url":"https://github.com/josecelano/ddd-aggregates-and-zombies","last_synced_at":"2026-05-19T09:09:28.058Z","repository":{"id":49893258,"uuid":"369899250","full_name":"josecelano/ddd-aggregates-and-zombies","owner":"josecelano","description":"Use case for DDD aggregates without persisting objects in DB.","archived":false,"fork":false,"pushed_at":"2021-06-25T12:45:25.000Z","size":590,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-28T17:02:02.479Z","etag":null,"topics":["aggregates","ddd","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/josecelano.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}},"created_at":"2021-05-22T20:23:24.000Z","updated_at":"2021-06-25T12:45:28.000Z","dependencies_parsed_at":"2022-09-09T11:11:27.988Z","dependency_job_id":null,"html_url":"https://github.com/josecelano/ddd-aggregates-and-zombies","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/josecelano/ddd-aggregates-and-zombies","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josecelano%2Fddd-aggregates-and-zombies","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josecelano%2Fddd-aggregates-and-zombies/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josecelano%2Fddd-aggregates-and-zombies/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josecelano%2Fddd-aggregates-and-zombies/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/josecelano","download_url":"https://codeload.github.com/josecelano/ddd-aggregates-and-zombies/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/josecelano%2Fddd-aggregates-and-zombies/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263980177,"owners_count":23538922,"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":["aggregates","ddd","nodejs"],"created_at":"2024-10-29T23:14:59.522Z","updated_at":"2026-05-19T09:09:23.036Z","avatar_url":"https://github.com/josecelano.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DDD aggregates \u0026 zombies\n\n![example workflow](https://github.com/josecelano/ddd-aggregates-and-zombies/actions/workflows/main.yml/badge.svg)\n\n![Screenshot](doc/img/screenshot.png)\n\nWhy this repo? I think there are two main sources to learn about DDD agregates or at least those were the sources where I got a better understanding about aggregates from. In both cases the authors use an example with database and transactions. I wonder if:\n\n * DDD aggregates design makes sense without persisting objects. I mean, can we use the same design principles to keep consistency only having objects in memory?\n * Can I came up with a simpler sample to explain DDD agregates without using databases?\n\n I decided to write this small sample to learn more about DDD aggregates. I think the problem they solve it's a generic concurrency problem, in the sense of having 2 entities trying to update a shared state in a context where race conditions can happen. My idea was:\n\n 1. First, try to reproduce such scenario where I have a domain invariant and 2 objects updating a shared state.\n 2. Second, try to find out if what I learnt from both articles also apply only to objects in memory and if I can keep domain invariant designing the rigth aggregates.\n 3. Finally, if they also apply, try to explain the example step by step in order to have the most simple possible example about DDD aggregates (withput involving databases).\n\n Althougth the sample is finished the resoning about this topic (or learning) is a WIP. I would like to write the:\n\n [Full explanation about this example](doc/ddd-agregates.md)\n\n## Requirements\n\n* Node 14.17.0\n* Docker 20.10.5\n\n## Run\n\nWith docker:\n```\ndocker run --rm -it josecelano/ddd-aggregates-and-zombies\n```\n\nDockerhub image: https://hub.docker.com/r/josecelano/ddd-aggregates-and-zombies\n\nYou can also install the project (clone, build and run).\n\n## Install\n\nFrom repo:\n```\ngit clone git@github.com:josecelano/ddd-aggregates-and-zombies.git\n./bin/docker/build.sh\n./bin/docker/run.sh\n```\n\n## Development\n\nBuild docker image:\n```\n./bin/docker/build.sh\n```\n\nRun app with concurrency problem:\n```\n./bin/docker/run.sh\n```\n\nAfter some seconds you will get this error:\n```\n/usr/src/app/lib/apocalyptic_world.js:83\n      throw new RangeError(`The cell ${coordinate.toString()} is already occupied by another zombie`);\n      ^\n\nRangeError: The cell (7,17) is already occupied by another zombie\n    at ApocalypticWorld.guardThatCellIsNotMarkedAsOccupiedTwice (/usr/src/app/lib/apocalyptic_world.js:83:13)\n    at ApocalypticWorld.markCellAsOccupiedByAZombie (/usr/src/app/lib/apocalyptic_world.js:51:10)\n    at ApocalypticWorld.moveZombie (/usr/src/app/lib/apocalyptic_world.js:38:10)\n    at Timeout._onTimeout (/usr/src/app/lib/game.js:76:20)\n    at listOnTimeout (internal/timers.js:557:17)\n    at processTimers (internal/timers.js:498:7)\nerror Command failed with exit code 1.\n```\n\nRun app with mutual exclusivity to avoid race contitions using the Game aggregate:\n```\n./bin/docker/run-aggregate.sh\n```\n\nRun and connect to docker image on development environment:\n```\n./bin/docker/up.sh\n```\n\nRun tests:\n```\n./bin/docker/test.sh\n```\n\n## Links\n\n * [Vaughn Vernon - Effective Aggregate Design](https://www.dddcommunity.org/library/vernon_2011/)\n * [Buenosvinos/Soronellas/Akbary - DDD in PHP book](https://leanpub.com/ddd-in-php)\n\n## TODO\n\n * Add missing tests for new changes.\n * Code review: add a wrapper method to the world for `zombie.thinkWhereToWalk(world);` like this `world.makeZombieWalk(zombie)`\n * Code review: rename `world.moveZombie(zombie);` to `world.makeZombieWalk(zombie);`?\n * Test intervals. The current test coverage report shows that the intervals functions are not being covered althougth in fact, they are:\n\n ```\n --------------------------|---------|----------|---------|---------|-------------------\nFile                      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n--------------------------|---------|----------|---------|---------|-------------------\nAll files                 |   95.68 |    93.48 |   97.26 |   96.13 |                   \n apocalyptic_world.js     |     100 |      100 |     100 |     100 |                   \n coordinate.js            |     100 |      100 |     100 |     100 |                   \n coordinate_collection.js |     100 |      100 |     100 |     100 |                   \n game.js                  |   85.11 |     62.5 |   89.47 |   86.96 | 61,73-79          \n grid.js                  |     100 |      100 |     100 |     100 |                   \n print_world.js           |     100 |      100 |     100 |     100 |                   \n random.js                |     100 |      100 |     100 |     100 |                   \n zombie.js                |     100 |      100 |     100 |     100 |                   \n--------------------------|---------|----------|---------|---------|-------------------\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosecelano%2Fddd-aggregates-and-zombies","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjosecelano%2Fddd-aggregates-and-zombies","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosecelano%2Fddd-aggregates-and-zombies/lists"}