{"id":51579186,"url":"https://github.com/dessima/aws-serverless-order-management","last_synced_at":"2026-07-11T04:01:58.950Z","repository":{"id":365698243,"uuid":"1272810211","full_name":"DessimA/aws-serverless-order-management","owner":"DessimA","description":"Sistema escalável de gestão de pedidos utilizando arquitetura orientada a eventos (EDA) com AWS Lambda, EventBridge, SQS e DynamoDB.","archived":false,"fork":false,"pushed_at":"2026-06-26T02:13:57.000Z","size":678,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-26T02:16:20.163Z","etag":null,"topics":["aws","cloud-computing","event-driven","eventbridge","infraestructure-as-a-code","lambda","serverless"],"latest_commit_sha":null,"homepage":"","language":"Shell","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/DessimA.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-18T00:40:03.000Z","updated_at":"2026-06-25T00:14:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/DessimA/aws-serverless-order-management","commit_stats":null,"previous_names":["dessima/aws-serverless-order-management"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DessimA/aws-serverless-order-management","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DessimA%2Faws-serverless-order-management","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DessimA%2Faws-serverless-order-management/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DessimA%2Faws-serverless-order-management/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DessimA%2Faws-serverless-order-management/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DessimA","download_url":"https://codeload.github.com/DessimA/aws-serverless-order-management/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DessimA%2Faws-serverless-order-management/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35350133,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"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":["aws","cloud-computing","event-driven","eventbridge","infraestructure-as-a-code","lambda","serverless"],"created_at":"2026-07-11T04:01:54.792Z","updated_at":"2026-07-11T04:01:58.941Z","avatar_url":"https://github.com/DessimA.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AWS Serverless Order Management System\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/Python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3120/)\n[![AWS Serverless](https://img.shields.io/badge/AWS-Serverless-orange.svg)](https://aws.amazon.com/serverless/)\n[![LocalStack](https://img.shields.io/badge/LocalStack-Pro-purple.svg)](https://localstack.cloud/)\n\n## Sobre o Projeto\n\nUm sistema serverless de gerenciamento de pedidos para cursos e vouchers de certificação em nuvem. Clientes se cadastram, navegam por um catálogo de cursos (AWS, Azure, GCP), compram com um clique e acompanham o ciclo de vida completo do pedido (processamento, atualização, cancelamento). A arquitetura e orientada a eventos: o barramento central EventBridge desacopla produtores de consumidores, filas SQS absorvem picos de carga e garantem resiliência a falhas temporárias, e o DynamoDB lida com idempotência via ConditionExpression. Nenhuma chamada síncrona cruza fronteiras de serviço. O projeto opera exclusivamente via AWS CLI e shell scripts, sem frameworks de Infrastructure as Code, expondo os parâmetros reais de cada serviço AWS.\n\nEste projeto e material de portfolio. Cada decisão técnica foi tomada com consciência dos trade-offs, documentada em [ARCHITECTURE.md](ARCHITECTURE.md), O objetivo e demonstrar pensamento sistêmico sobre arquitetura serverless, não apenas a implementação funcional.\n\n## Demo Rapida\n\n**Fluxo completo:** cadastro \u003e catálogo \u003e compra \u003e meus pedidos \u003e cancelar\n\n1. Acesse o frontend (URL exibida apos deploy).\n2. Cadastre-se com email e senha.\n3. Navegue pelo catálogo, filtre por provedor (AWS/Azure/GCP) ou tipo (Curso/Voucher).\n4. Clique em \"Comprar\" em qualquer curso.\n5. Va para \"Meus Pedidos\" para ver o status.\n6. Clique em um pedido para detalhe: cancele ou atualize os itens.\n\n**Links apos deploy:** Os endpoints sao exibidos no terminal ao final do deploy (./run.sh).\n\n## Arquitetura\n\n```mermaid\n%%{init: {'flowchart': {'nodeSpacing': 15, 'rankSpacing': 25, 'padding': 6}}}%%\nflowchart LR\n    Browser[\"Browser index.html\"]:::s_cliente\n    QA[\"Browser qa.html\"]:::s_qa\n    STATICSITE[\"S3 Static Website\"]:::s_s3fe\n\n    subgraph APIGW[\"API Gateway (order-ingestion-api)\"]\n        GW_POST[\"/orders POST\"]\n        GW_GET[\"/orders GET\"]\n        GW_GET_ID[\"/orders/{id} GET\"]\n        GW_CANCEL[\"/orders/{id}/cancel POST\"]\n        GW_PATCH[\"/orders/{id} PATCH\"]\n        GW_CAT[\"/catalog GET\"]\n        GW_CAT_ID[\"/catalog/{id} GET\"]\n        GW_REG[\"/customers/register POST\"]\n        GW_LOGIN[\"/customers/login POST\"]\n        GW_ME[\"/customers/me GET\"]\n        GW_TEST[\"/test POST (API Key)\"]\n    end\n\n    subgraph LambdaIngestao[\"Lambdas de Ingestao\"]\n        PRE[\"pre_validator\"]\n        VAL[\"order_validator\"]\n    end\n\n    subgraph LambdaProduto[\"Lambdas de Produto\"]\n        GWL[\"order_gateway\"]\n        CAT[\"catalog_reader\"]\n        AUTH[\"customer_auth\"]\n        CTRL[\"test_controller\"]\n    end\n\n    subgraph LambdaProcessamento[\"Lambdas de Processamento\"]\n        PROC[\"order_processor\"]\n        CANCEL[\"lifecycle_ops (cancel)\"]\n        UPDATE[\"lifecycle_ops (update)\"]\n        BATCH[\"batch_processor\"]\n    end\n\n    subgraph SQS_Filas[\"Filas SQS\"]\n        FIFO[\"order-validation-buffer (FIFO)\"]\n        PERSQ[\"order-persister-queue (Standard)\"]\n        CANCELQ[\"cancel-order-queue (Standard)\"]\n        UPDATEQ[\"update-order-queue (Standard)\"]\n        BATCHQUEUE[\"order-s3-batch-queue (Standard)\"]\n    end\n\n    subgraph DynamoDB_Tables[\"DynamoDB\"]\n        PROD[\"order-production-data + GSI clientId-index\"]\n        AUDIT[\"order-batch-audit (TTL 90 dias)\"]\n        CATALOG[\"course-catalog\"]\n        CUSTOMERS[\"customer-data\"]\n    end\n\n    EB[\"orders-event-bus\"]:::s_eb\n\n    subgraph SNS_CW[\"SNS + CloudWatch\"]\n        SNS[\"order-notifications (email)\"]\n        CW[\"CloudWatch Alarms (5 DLQs)\"]\n    end\n\n    DATABUCKET[\"order-files-bucket\"]:::s_s3d\n\n    Browser --\u003e STATICSITE\n    QA --\u003e STATICSITE\n    Browser --\u003e GW_POST \u0026 GW_GET \u0026 GW_GET_ID \u0026 GW_CANCEL \u0026 GW_PATCH \u0026 GW_CAT \u0026 GW_CAT_ID \u0026 GW_REG \u0026 GW_LOGIN \u0026 GW_ME\n    QA --\u003e GW_TEST\n\n    GW_POST --\u003e PRE --\u003e FIFO --\u003e VAL --\u003e EB\n    GW_GET \u0026 GW_GET_ID \u0026 GW_CANCEL \u0026 GW_PATCH --\u003e GWL\n    GW_CAT \u0026 GW_CAT_ID --\u003e CAT\n    GW_REG \u0026 GW_LOGIN \u0026 GW_ME --\u003e AUTH\n    GW_TEST --\u003e CTRL\n\n    GWL --\u003e PROD\n    GWL --\u003e EB\n    CAT --\u003e CATALOG\n    AUTH --\u003e CUSTOMERS\n    CTRL --\u003e EB \u0026 DATABUCKET\n\n    EB --\u003e PERSQ --\u003e PROC --\u003e PROD\n    EB --\u003e CANCELQ --\u003e CANCEL --\u003e PROD\n    EB --\u003e UPDATEQ --\u003e UPDATE --\u003e PROD\n    DATABUCKET --\u003e BATCHQUEUE --\u003e BATCH --\u003e AUDIT\n\n    subgraph Legend[\"Legenda\"]\n        L1[\"Acesso do Cliente (HTTP)\"]:::l_http\n        L2[\"Pipeline de Ingestao\"]:::l_ing\n        L3[\"Roteamento para Lambdas de Dominio\"]:::l_route\n        L4[\"Consultas e Persistencia em Dados\"]:::l_data\n        L5[\"Processamento Orientado a Eventos\"]:::l_event\n        L6[\"Processamento Batch S3\"]:::l_batch\n    end\n\n    style APIGW fill:#3F51B5,color:#fff,stroke:#3949AB\n    style LambdaIngestao fill:#3949AB,color:#fff,stroke:#303F9F\n    style LambdaProduto fill:#303F9F,color:#fff,stroke:#283593\n    style LambdaProcessamento fill:#283593,color:#fff,stroke:#1A237E\n    style SQS_Filas fill:#00838F,color:#fff,stroke:#006064\n    style DynamoDB_Tables fill:#1A237E,color:#fff,stroke:#283593\n    style SNS_CW fill:#37474F,color:#fff,stroke:#455A64\n    style Legend fill:#F5F5F5,color:#333,stroke:#9E9E9E\n\n    classDef s_cliente fill:#7986CB,color:#fff,stroke:#5C6BC0\n    classDef s_qa fill:#9FA8DA,color:#fff,stroke:#7986CB\n    classDef s_s3fe fill:#5C6BC0,color:#fff,stroke:#3F51B5\n    classDef s_eb fill:#006064,color:#fff,stroke:#00838F\n    classDef s_s3d fill:#283593,color:#fff,stroke:#1A237E\n    classDef l_http fill:#5C6BC0,color:#fff,stroke:#5C6BC0\n    classDef l_ing fill:#3949AB,color:#fff,stroke:#3949AB\n    classDef l_route fill:#303F9F,color:#fff,stroke:#303F9F\n    classDef l_data fill:#1A237E,color:#fff,stroke:#1A237E\n    classDef l_event fill:#00838F,color:#fff,stroke:#00838F\n    classDef l_batch fill:#006064,color:#fff,stroke:#006064\n\n    linkStyle 0,1,2,3,4,5,6,7,8,9,10,11,12 stroke:#5C6BC0,stroke-width:2px\n    linkStyle 13,14,15,16 stroke:#3949AB,stroke-width:2px\n    linkStyle 17,18,19,20,21,22,23,24,25,26 stroke:#303F9F,stroke-width:2px\n    linkStyle 27,28,29,30,31,32 stroke:#1A237E,stroke-width:2px\n    linkStyle 33,34,35,36,37,38,39,40,41 stroke:#00838F,stroke-width:2px\n    linkStyle 42,43,44 stroke:#006064,stroke-width:2px\n```\n\nPara decisões detalhadas de design, veja [ARCHITECTURE.md](ARCHITECTURE.md).\n\n## Stack e Servicos AWS\n\n| Servico | Papel no sistema | Alternativa avaliada |\n|---|---|---|\n| **API Gateway** | Ponto de entrada REST (11 endpoints) com Request Validator, CORS, API Key para /test | N/A (único serviço de API HTTP serverless da AWS) |\n| **Lambda** | 11 funções Python 3.12 para lógica de negócio serverless | ECS/Fargate: overhead operacional desnecessário para funções de curta duração |\n| **SQS FIFO** | Buffer de validação com ordenação por pedido e ContentBasedDeduplication | Processamento síncrono: sem resiliência a falhas temporárias |\n| **SQS Standard** | 3 filas de processamento + 1 fila S3 batch, paralelismo garantido | FIFO para processamento: forjava sequencial sem ganho de corretude |\n| **EventBridge** | Barramento central de eventos, roteia por detail-type e source | SNS fanout: menor expressividade de filtro e sem suporte a Content-Based Filtering |\n| **DynamoDB** | 4 tabelas: pedidos (com GSI), auditoria (TTL 90d), catálogo, clientes | RDS: custo e operação mais altos para volume variável de laboratório |\n| **SNS** | Notificações de erro (duplicata, schema inválido, DLQ) para email | N/A (único serviço de pub/sub email da AWS) |\n| **S3** | 2 buckets: dados (batch files) e frontend (static website) | EFS: sem necessidade de sistema de arquivos compartilhado |\n| **IAM** | 11 roles com politicas de menor privilegio, inline e gerenciadas | N/A (único serviço de autorização AWS) |\n| **CloudWatch** | Logs (retenção 14d), Alarmes (5 DLQs), métricas | X-Ray: não disponível na conta de laboratório |\n| **LocalStack** | Emulação local de serviços AWS via Docker | AWS real: custo para desenvolvimento iterativo |\n\n## Estrutura do Repositorio\n\n```text\n.\n├── scripts/              # IaC: deploy, validação, utilitários (26 funções lib.sh)\n├── src/                  # Codigo-fonte das 11 Lambdas + modulo common/\n├── frontend/             # 2 frontends: CloudCert (index.html) + QA Dashboard (qa.html)\n├── samples/              # Payloads de teste (api_request.json, batch JSONs)\n├── docs/                 # Documentação individual por componente (16 arquivos)\n├── ARCHITECTURE.md       # Decisões de design por tema (este documento)\n├── run.sh                # Orquestrador principal: deploy completo + validação\n└── cleanup.sh            # Remoção completa de recursos (idempotente)\n```\n\n## Como Executar\n\n### Pre-requisitos\n\n- AWS CLI v2 configurado\n- Python 3.12\n- Docker e Docker Compose (para LocalStack)\n- Utilitário `zip`\n\n### Deploy Local (LocalStack)\n\n```bash\ncp .env.example .env\ndocker-compose up -d\n./run.sh\n```\n\n### Deploy na AWS\n\nEdite `.env`: defina `DEPLOY_TARGET=aws`, preencha `AWS_REGION`, `RESOURCE_SUFFIX`, `NOTIFICATION_EMAIL`.\n\n```bash\n./run.sh\n```\n\n### Executar testes E2E\n\n```bash\n./scripts/validate-flow.sh\n```\n\n25 testes que cobrem: criação de pedidos, processamento S3 batch, lifecycle (cancelar/atualizar), duplicatas, consultas, alertas SNS, filas DLQ, catálogo, autenticação JWT, gateway de pedidos, e frontends.\n\n## Decisões de Design em Destaque\n\n**Idempotência por ConditionExpression no DynamoDB em vez de deduplicação na fila.** A janela de 5 minutos do SQS FIFO impedia testes de duplicidade no frontend. A solução foi usar `MessageDeduplicationId = uuid4()` (sempre único) e delegar a deduplicação de negócio ao `ConditionExpression: attribute_not_exists(orderId)` no DynamoDB, que e permanente e gera alerta SNS. Detalhes em [ARCHITECTURE.md#3-idempotência-conditionexpression-vs-deduplicação-na-fila](ARCHITECTURE.md#3-idempotência-conditionexpression-vs-deduplicação-na-fila).\n\n**JWT implementado manualmente em stdlib Python sem dependencias externas.** A conta de laboratório não tem Cognito, Secrets Manager nem KMS CMK. O modulo `common/auth.py` implementa PBKDF2-SHA256 (200.000 iterações), HMAC-SHA256, e `compare_digest` contra timing attack. Sem `requirements.txt` ou camada Lambda. Detalhes em [ARCHITECTURE.md#4-seguranca-sem-waf-cognito-e-kms](ARCHITECTURE.md#4-seguranca-sem-waf-cognito-e-kms).\n\n**Resource Policy do API Gateway com padrão Allow geral + Deny condicional.** A implementação inicial usava Allow-only com `IpAddress`, que bloqueava endpoints públicos (`POST /orders`, `GET /orders`) quando a restrição de IP era ativada. A correção usou o padrão Allow geral para toda a API + Deny condicional restrito a `*/*/POST/test`, respeitando a precedência do Deny sobre Allow. Detalhes em [ARCHITECTURE.md#4-seguranca-sem-waf-cognito-e-kms](ARCHITECTURE.md#4-seguranca-sem-waf-cognito-e-kms).\n\n**batchItemFailures em todas as Lambdas SQS para reprocessamento parcial de lote.** Sem essa configuração, uma falha em uma das 5 mensagens do lote derrubava o lote inteiro, reprocessando mensagens ja bem-sucedidas. Com `ReportBatchItemFailures`, apenas os `messageId` com erro retornam na resposta, e as mensagens bem-sucedidas são confirmadas. Detalhes em [ARCHITECTURE.md#2-resiliência-dlq-batchitemfailures-e-visibilitytimeout](ARCHITECTURE.md#2-resiliência-dlq-batchitemfailures-e-visibilitytimeout).\n\n## Licenca e Contato\n\nDistribuido sob licença MIT. Projeto desenvolvido por [Jose Anderson](https://github.com/DessimA).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdessima%2Faws-serverless-order-management","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdessima%2Faws-serverless-order-management","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdessima%2Faws-serverless-order-management/lists"}