{"id":21310080,"url":"https://github.com/bahattincinic/deeplink-challenge","last_synced_at":"2026-04-06T21:34:16.201Z","repository":{"id":67257671,"uuid":"254962339","full_name":"bahattincinic/deeplink-challenge","owner":"bahattincinic","description":"Deeplink challenge with clean architecture","archived":false,"fork":false,"pushed_at":"2020-04-13T21:01:55.000Z","size":118,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-15T20:29:44.581Z","etag":null,"topics":["clean-architecture","docker","github-actions","nodejs","postgresql","rabbitmq","redis"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/bahattincinic.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":"2020-04-11T21:57:21.000Z","updated_at":"2021-03-13T19:25:59.000Z","dependencies_parsed_at":"2023-02-25T17:46:09.082Z","dependency_job_id":null,"html_url":"https://github.com/bahattincinic/deeplink-challenge","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bahattincinic/deeplink-challenge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahattincinic%2Fdeeplink-challenge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahattincinic%2Fdeeplink-challenge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahattincinic%2Fdeeplink-challenge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahattincinic%2Fdeeplink-challenge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bahattincinic","download_url":"https://codeload.github.com/bahattincinic/deeplink-challenge/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahattincinic%2Fdeeplink-challenge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31491097,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"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":["clean-architecture","docker","github-actions","nodejs","postgresql","rabbitmq","redis"],"created_at":"2024-11-21T17:12:21.786Z","updated_at":"2026-04-06T21:34:16.184Z","avatar_url":"https://github.com/bahattincinic.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Deeplink Challenge\n\nI developed this challenge with clean architecture principles.\n(Please check uncle bob blog post https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)\n\n### Understanding the Folder Structure\n\n```\n.\n├── app.js            // main koajs app\n├── config.js         // application configs.\n├── controllers       // HTTP layer\n├── data              // Database layer\n│   ├── config.js     // sequelize config file\n│   ├── migrations    // database migrations file\n│   ├── models        // database models\n│   └── seeders       // fixture/dummy data\n├── logger.js         // app logger\n├── middlewares       // API middlewares\n├── queue             // rabbitmq implementation\n├── repositories      // Database abstruction for busines logics\n├── routes.js         // API Routes\n├── services          // App services\n│   └── cache.js      // Redis service\n└── usecases          // Business layer\n```\n\n### Requirements\n\n* Node 10+ (`You don't need to install if you use docker`)\n* Postgres 11+ (`You don't need to install if you use docker`)\n* Redis 5 (`You don't need to install if you use docker`)\n* Rabbitmq 3 (`You don't need to install if you use docker`)\n* Docker (https://docs.docker.com/install/)\n\n### Building the Project (with Docker)\n\nClone the repository\n\n```\n$ git clone git@github.com:bahattincinic/deeplink-challenge.git\n$ cd deeplink-challenge\n```\n\nbuild docker images with the following link\n\n```\n$ docker-compose up -d --build\n``` \n\nApply Database migrations\n```\n$ docker exec -it webapi bash\n$ npx sequelize-cli db:migrate\n```\n\nImport initial data\n```\n$ docker exec -it webapi bash\n$ npx sequelize-cli db:seed:all\n```\n\nCheck eslint errors\n\n```\n$ docker exec -it webapi bash -c \"npm run lint\"\n```\n\n### Environment Variables\n\n- NODE_ENV (default: `development`)\n- BROKER_URL (default: `amqp://172.18.0.1`)\n- DATABASE_URL (default: `postgres://postgres:postgres@172.18.0.1:5432/challenge`)\n- CACHE_URL (default: `redis://172.18.0.1:6379`)\n- PORT (default: `4000`)\n\nYou can override these variables with dotenv (https://github.com/motdotla/dotenv) or manually.\n\n### Docker Container\n\nWhen we check which docker containers are running, we see 5 different docker containers are running. \n\n- `webapi`: This is a main application container\n- `apiworker`: This is a rabbitmq worker. When the customer reached the endpoint,\nwe add a request log to the database. We don't need to wait for customer for this operation.\nAlso sometimes it causes a performance problem.\nThat's why we are processing this action in the background.\n- `rediscache`: This is a Redis container. We are caching short links for performance improvements.\nThat's why we need Redis.\n- `rabbitmq`: This is a rabbitmq container.\n- `postgre`: This is a PostgreSQL container.\n\n### Docker Tips\n\nCheck logs:\n\n```\n$ docker logs -f apiworker --tail 20\n$ docker logs -f webapi --tail 20\n```\n\nStart/stop:\n\n```\n$ docker-compose start\n$ docker-compose stop\n$ docker stop webapi\n```\n\nAttach the container:\n\n```\n$ docker exec -it webapi bash\n```\n\n### API\n\nCreate short link:\n\n```\nURL: POST http://localhost:4000/short-link/create/\nBody:\n{\n    \"deeplink\": \"dl://?Page=Search\u0026Query=apple\"\n}\n```\n\nGet shortlist detail:\n\n```\nURL: POST http://localhost:4000/short-link/get/\nBody:\n{\n\"shortlink\": \"http://localhost:4040/xssas\"\n}\n```\n\nGet Web url from deeplink:\n\n```\nURL: POST http://localhost:4000/api/v1/deeplink-to-web-url\nBody:\n{\n\"deeplink\": \"dl://?Page=Home\u0026SectionId=2\"\n}\n```\n\nGet deeplink from web url:\n\n```\nURL: POST http://localhost:4000/api/v1/web-url-to-deeplink\nBody:\n{\n\"webURL\" : \"https://www.example.com/boutique/list/man\"\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahattincinic%2Fdeeplink-challenge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbahattincinic%2Fdeeplink-challenge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahattincinic%2Fdeeplink-challenge/lists"}