{"id":25508122,"url":"https://github.com/alejogs4/go-products","last_synced_at":"2025-09-18T22:48:59.085Z","repository":{"id":278219688,"uuid":"934911980","full_name":"alejogs4/go-products","owner":"alejogs4","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-18T16:41:18.000Z","size":3698,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-20T05:08:30.640Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","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/alejogs4.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-02-18T15:51:54.000Z","updated_at":"2025-02-18T16:41:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"e9d9426e-49d3-40ab-9a66-d98393f4100a","html_url":"https://github.com/alejogs4/go-products","commit_stats":null,"previous_names":["alejogs4/go-products"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alejogs4/go-products","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alejogs4%2Fgo-products","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alejogs4%2Fgo-products/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alejogs4%2Fgo-products/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alejogs4%2Fgo-products/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alejogs4","download_url":"https://codeload.github.com/alejogs4/go-products/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alejogs4%2Fgo-products/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275846208,"owners_count":25539155,"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","status":"online","status_checked_at":"2025-09-18T02:00:09.552Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":"2025-02-19T07:56:35.553Z","updated_at":"2025-09-18T22:48:59.068Z","avatar_url":"https://github.com/alejogs4.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Products API\n\n## Instructions\n\n### Running production\nTo run the application in production mode, use the following command:\n\n```sh\n  ./bin/products_app\n```\n\nNote that if you modify the code you will need to recompile the application with the following command:\n\n```sh\n  make build\n```\n\n### Running the application\nTo run execute\n    \n```sh\n  make run\n```\n\nThis will start the Golang application with the current code\n\n### Running Tests\nTo run the tests for the Golang application, use the following command:\n\n```sh\n  make test\n```\n\n### Technical decisions\n\n#### Domain as logic center\nThe domain inside products reside all the code needed to validate product input integrity and calculate product discount.\nI did it this way so in the innermost layer of the application we have the business logic and the domain rules detached of any external dependencies such as databases or http requests.\n\nThis also includes the repository interface that is used to abstract the database (infra) layer from the domain layer.\n\n#### SQLite\nI chose SQLite as the database for this project because it is a simple database that it is easy to setup and use in this case it is entirely self contained\nthis means that no installation is needed by the user since sqlite is self contained in the library.\n\nBesides offers easily an in memory database that can be used for testing purposes so integrations tests are easy to do without any extra setup.\n\n#### Clean Architecture\n\nA clean architecture was applied here to separate the concerns of the application in layers, the main layers are:\n- Domain\n- Use cases\n- Infra\n\nThe main goal with this was abstract every layer from the other so that the application can be easily tested and maintained following the dependency direction rule\nthus outermost layer can be tested with or without dependencies of the innermost layer since the details of these dependencies are hidden through interfaces.\n\n#### Streaming of json data at initialization\n\nJsonStream type allows function ReadJson to send a stream of json data to the channel, this is useful to read a large json file without loading it all in memory at once. so if files\ngrows to 20k rows or any arbitrary number of rows the application will not crash due to memory issues since it will be kept stable, besides thanks to concurrency use, json read and product insertion\ncan potentially happen simultaneously.\n\n#### init function at Database connection generation\nThis function allows optionally to execute any function at database initialization, in this case it is used to create the table if it does not exist.\n\n#### Detach domain model from response model\n\nDomain model only contains the fields needed by its own nature of being a product in the another hand the response model contains the fields needed to be returned to the client the more\nobvious is price field which contains the price with and discount information, business model offers a method to calculate the discount on the fly so response can contain the price with discount\nbut how it will be finally represented is http response responsibility and not a domain concerned.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falejogs4%2Fgo-products","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falejogs4%2Fgo-products","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falejogs4%2Fgo-products/lists"}