{"id":29436889,"url":"https://github.com/bpato/senior_code_challengue","last_synced_at":"2026-04-12T12:41:14.034Z","repository":{"id":304119161,"uuid":"1005015388","full_name":"bpato/senior_code_challengue","owner":"bpato","description":"Cart \u0026 Checkout API in Symfony: Technical Challenge with DDD, CQRS \u0026 Testing","archived":false,"fork":false,"pushed_at":"2025-07-11T06:47:19.000Z","size":1354,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-11T10:29:14.929Z","etag":null,"topics":["cqrs","cqrs-pattern","ddd","ddd-patterns","hexagonal-architecture","openapi-specification","php","php83","phpunit","phpunit-tests","symfony","symfony73"],"latest_commit_sha":null,"homepage":"","language":"PHP","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/bpato.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-06-19T14:28:32.000Z","updated_at":"2025-07-11T06:47:22.000Z","dependencies_parsed_at":"2025-07-11T10:31:30.865Z","dependency_job_id":"ee05f5be-b2de-40d2-93b9-bebf2aad84f0","html_url":"https://github.com/bpato/senior_code_challengue","commit_stats":null,"previous_names":["bpato/senior_code_challengue"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bpato/senior_code_challengue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpato%2Fsenior_code_challengue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpato%2Fsenior_code_challengue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpato%2Fsenior_code_challengue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpato%2Fsenior_code_challengue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bpato","download_url":"https://codeload.github.com/bpato/senior_code_challengue/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bpato%2Fsenior_code_challengue/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265091734,"owners_count":23710033,"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":["cqrs","cqrs-pattern","ddd","ddd-patterns","hexagonal-architecture","openapi-specification","php","php83","phpunit","phpunit-tests","symfony","symfony73"],"created_at":"2025-07-13T05:08:08.114Z","updated_at":"2026-04-12T12:41:08.979Z","avatar_url":"https://github.com/bpato.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Senior Code Challengue\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/bpato/senior_code_challengue)\n\n![Senior Code Challengue](https://github.com/bpato/senior_code_challengue/blob/master/senior_code_challengue.png?raw=true)\n\n## Breve descripción del proyecto\n\nEsta aplicación es un ejemplo de api desacoplada con la funcionalidad de un sistema de carrito de compras. \nEsta implementada siguiendo una arquitectura hexagonal, aplicando un diseño CQRS y DDD y siguiendo los principios solid.\n\nPermite crear carritos, agregar y modificar items, y establecer órdenes de compra.\n\nLos carritos no tienen persistencia en base de datos, están almacenados en cache con un tiempo de vida de 24h o hasta que se realiza su borrado.\n\nSe implementa CQRS con handlers específicos para comandos y consultas, separados de la lógica de infraestructura.\n\nSe implementa un ejemplo de eventos y subscribers con comunicación entre contextos, al momento de establecer un order se comunica desde el contexto del checkout y en el contexto de Cart se elimina el carrito correspondiente.\n\nSe han generado diferentes DTO para mostrar y enriquecer la respuesta de la api con información más completa a la estrictamente necesaria para el trabajo de los modelos del domino.\n\n\n\\\nEjemplo del json de respuesta del carrito:\n```json\n    {\n        \"cart\": {\n            \"id\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n            \"items\": [\n                {\n                    \"product_id\": 0,\n                    \"quantity\": 0,\n                    \"name\": \"string\",\n                    \"unit_price\": 0,\n                    \"price\": 0\n                }\n            ],\n            \"total_items\": 0,\n            \"total_price\": 0\n        }\n    }\n```\n\n\\\nEjemplo del json de respuesta de un pedido:\n```json\n    {\n    \"order\": {\n            \"id\": 0,\n            \"cart_reference\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n            \"email\": \"user@example.com\",\n            \"total_price\": 0,\n            \"total_items\": 0,\n            \"created_at\": \"2025-06-19T14:23:24.696Z\",\n            \"products\": [\n                {\n                    \"product_id\": 0,\n                    \"name\": \"string\",\n                    \"unit_price\": 0,\n                    \"total_price\": 0,\n                    \"quantity\": 0\n                }\n            ]\n        }\n    }\n```\n\n---\n\n## OpenAPI Specification\n\nLa especificación OpenAPI se encuentra en el archivo `/docs/openapi.yaml`. Describe todos los endpoints disponibles, los parámetros, las cabeceras, los esquemas de request y response, así como los posibles errores HTTP.\n\nPara visualizarla, podés usar herramientas como [Swagger UI](https://swagger.io/tools/swagger-ui/) o [Redoc](https://github.com/Redocly/redoc).\n\n---\n\n## Modelado del dominio\n\nLa estructura establece dos contextos principales `Cart` y `Checkout`\n\n`Cart` engloba todos los casos de uso relativos a la gestión del carrito añadir, actualizar y eliminar items.\nEl dominio cuenta con las siguientes entidades:\n\n    Cart\n    - id\n    - items (CartItem[])\n\n    CartItem\n    - product_id\n    - quantity\n\n`Checkout` engloba los casos de uso relativos a la creación del pedido desde un carrito\nEl dominio cuenta con las siguientes entidades:\n\n    Order\n    - id\n    - cart_reference\n    - email\n    - crated_at\n    - total_price\n    - total_quantity\n    - products (OrderProduct[])\n\n    OrderProduct\n    - id\n    - product_id\n    - name\n    - price\n    - quantity\n    - total_price\n\n    Product\n    - id\n    - name\n    - price\n\n---\n\n## Tecnología utilizada\n\n- PHP 8.3  \n- Symfony 7.3  \n- Doctrine ORM (solo para entidades persistentes, no para carrito en cache)  \n- Messenger Component para mensajería interna  \n- PHPUnit para testing  \n- Faker para generación de datos de prueba\n- Fixture para generar 100 productos de prueba en BD  \n- Docker \u0026 Docker Compose para el entorno de desarrollo\n\n---\n\n## Levantar el entorno\n\nPara levantar la aplicación con Docker, ejecutar:\n\n```bash\n    # levantar el proyecto\n    # automaticamente genera ya los migratios y puebla la bd\n    docker-compose up -d\n\n    ## apaga el proyecto y elimina los contenedores para que se cree la bd sin problemas\n    docker-compose down -v\n\n    ## ejecutar los test\n    docker-compose exec -it application_app php /var/www/app/bin/phpunit\n\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpato%2Fsenior_code_challengue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbpato%2Fsenior_code_challengue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbpato%2Fsenior_code_challengue/lists"}