{"id":17004175,"url":"https://github.com/zerc/dotos","last_synced_at":"2025-03-22T10:16:41.867Z","repository":{"id":233438185,"uuid":"658463686","full_name":"zerc/dotos","owner":"zerc","description":"POC of distributed todo application","archived":false,"fork":false,"pushed_at":"2023-06-25T22:41:03.000Z","size":94,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-27T10:08:33.091Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/zerc.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}},"created_at":"2023-06-25T20:18:22.000Z","updated_at":"2023-06-25T20:18:47.000Z","dependencies_parsed_at":"2024-04-16T07:00:14.645Z","dependency_job_id":"5ff9fb29-40a9-42ba-8d07-8253af5e23de","html_url":"https://github.com/zerc/dotos","commit_stats":null,"previous_names":["zerc/dotos"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerc%2Fdotos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerc%2Fdotos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerc%2Fdotos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerc%2Fdotos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zerc","download_url":"https://codeload.github.com/zerc/dotos/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244937835,"owners_count":20535127,"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":[],"created_at":"2024-10-14T04:42:55.744Z","updated_at":"2025-03-22T10:16:41.846Z","avatar_url":"https://github.com/zerc.png","language":"TypeScript","readme":"# Distributed Todo list\n\n\u003e **Disclaimer** this is not a product but rather proof-of-concept a (somewhat) distributed\n\u003e application. It's unlikely it will be of any use to anyone and is not going to be maintained\n\u003e going forward.\n\n## Requirements\n\nThe application provides two entities - `Todo` and `Category`. A user can create both of them using GraphQL API. \n\n### Functional requirements\n\n* CRUD for `Category`\n* CRUD for `Todo`, in particular:\n* * query a list (paginated) of todos with filtration by completion\n* * query a todo by ID\n* * update the todo / mark it as completed / assign to a group\n* Integration with another service provider in a way that:\n* * todos created in the third-party service are created in the service\n* * status of todos is synced between the service and the integration\n* The code should be structured\n\n### Non-functional requirements\n\nThe tech stack is the following:\n\n* Typescript\n* [Apollo](https://www.apollographql.com/docs/react/get-started) as GraphQL server\n* [Prisma](https://www.prisma.io/typescript) ORM\n* PostgreSQL database\n\nThe code should be structured to allow a small team (~10ppl) to be effective in contributing to it.\n\n### Assumptions\n\n**There can be more than one integration**\n\nThis would mean the following:\n\n* Content and the status of the todos should be cross-synced between all the integrations and the local service.\n* There will be no \"linking\" of the todos from different integrations if they were created *before* the integration was enabled i.e. it could create duplicated entries after a new integration is added. The approach was chosen for the sake of simplicity.\n\n\u003e In the real product, however, there could be a setting exposed where a user could specify how to handle this case (it could be part of the process of enabling the integration by the user)\n\n**Other**\n* No public API for enabling / disabling / configuring the integrations.\n* No authorisation \u0026\u0026 any user-management functionality\n* No deployment setup for production. The service is expected to run locally in the development mode.\n\n## Outcome\n\n### Design\n\nA high-level overview of the design:\n\n![design overview](docs/design_overview.png)\n\nA few things to note:\n\n* Database is shared between services for simplicity. However, each component uses a separate set of tables without foreign keys between them. Also, the code is structured in a way that it is easy to configure different databases per component if needed.\n* There isn't much difference between **our** service and **3rd-party** integraiton. Each component encapsulates its logic but uses a predefined set of events to communicate with others.\n* Every component\n* * should store any data required to ensure todos are linked together but do not leak anything outside\n* * can have its way to fetch data e.g. webhooks, polling or API\n\nData flow between components can be seen like this:\n\n![data flow](docs/data_flow.png)\n\n### Specifications\n\nThe service has two integrations:\n\n* `dummy` - generates a random todo and submits it to the bus.\n* `todoist` - a simple integration with [Todoist](https://todoist.com/). It only syncs `content` and completion of the items from the default project via [Sync API](https://developer.todoist.com/sync/v9/#items)\n\nA little demo:\n\n![demo](https://github.com/zerc/dotos/assets/306862/e549b0b9-a921-4b3c-a142-b047826e64c4)\n\n\n\n### Shortcuts\n\nHere are the things I'd like to do but decided to de-prioritise due to limited time:\n\n* **There are no tests**. There probably a few bugs because of that. I planned to use [jest](https://jestjs.io/docs/getting-started) for that.\n* Data consistency. The current implementation does not tolerate well when third-party service is not available and it may lead to data inconsistency. One way this can be addressed is by replacing the in-memory channel implementation for the [message bus](https://github.com/Dashlane/ts-event-bus) to ensure it can retry `onError` and persist events. However, the application is designed in a way that can be improved without rewriting everything.\n* `uuid4` is used to generate a distributed ID for the todos stored locally (in the API layer). In the production system, however, there might be a need for a more sophisticated solution to ensure data integrity.\n* Data design could be improved in many ways e.g. index for search optimisation (FTS for example), more complex query builder to avoid extra queries etc.\n\n## Local setup\n\n### Integrations\n\n#### Todoist\n\nCreate a [new app](https://developer.todoist.com/appconsole.html) and get **Test token** to get started quickly:\n\n```shell\nexport TODOIST_TOKEN=\u003cyour token\u003e\n```\n\n### Database\n\nTo start the database run.\n\n```shell\ndocker compose up -d\n```\n\nIt may take a few seconds for the database to start, check logs - `docker compose logs -f db`.\n\nThe admin interface will be available on http://localhost:8080/ and credentials can be found [here](./.env).\n\n### Install and run\n\n```shell\nnpm install\nnpx prisma db push\nnpm run start:app:dev\n```\n\nBy default `dummy` integration is enabled and it will push one todo item which then will be synced between the API layer and Todoist (if enabled).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerc%2Fdotos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzerc%2Fdotos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerc%2Fdotos/lists"}