kybernus 3.0.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/commands/ecommerce.d.ts +3 -0
- package/dist/cli/commands/ecommerce.d.ts.map +1 -0
- package/dist/cli/commands/ecommerce.js +164 -0
- package/dist/cli/commands/ecommerce.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/ecommerce/.env.example +10 -0
- package/templates/ecommerce/.github/workflows/ci.yml +102 -0
- package/templates/ecommerce/.github/workflows/deploy.yml +31 -0
- package/templates/ecommerce/.prettierrc +9 -0
- package/templates/ecommerce/Dockerfile +54 -0
- package/templates/ecommerce/README.md +295 -0
- package/templates/ecommerce/apps/api/.env.example +59 -0
- package/templates/ecommerce/apps/api/jest.config.ts +50 -0
- package/templates/ecommerce/apps/api/jest.integration.config.ts +45 -0
- package/templates/ecommerce/apps/api/package.json +59 -0
- package/templates/ecommerce/apps/api/prisma/migrations/20260306000137_init/migration.sql +184 -0
- package/templates/ecommerce/apps/api/prisma/migrations/migration_lock.toml +3 -0
- package/templates/ecommerce/apps/api/prisma/schema.prisma +181 -0
- package/templates/ecommerce/apps/api/prisma/seed.ts +159 -0
- package/templates/ecommerce/apps/api/src/__tests__/app.test.ts +39 -0
- package/templates/ecommerce/apps/api/src/__tests__/globalSetup.ts +34 -0
- package/templates/ecommerce/apps/api/src/__tests__/globalTeardown.ts +16 -0
- package/templates/ecommerce/apps/api/src/__tests__/setup.db.ts +18 -0
- package/templates/ecommerce/apps/api/src/__tests__/setup.env.ts +14 -0
- package/templates/ecommerce/apps/api/src/app.ts +133 -0
- package/templates/ecommerce/apps/api/src/application/admin/admin-user.service.ts +24 -0
- package/templates/ecommerce/apps/api/src/application/admin/dashboard.service.ts +102 -0
- package/templates/ecommerce/apps/api/src/application/auth/auth.service.ts +185 -0
- package/templates/ecommerce/apps/api/src/application/cart/cart.service.ts +151 -0
- package/templates/ecommerce/apps/api/src/application/cart/coupon.service.ts +51 -0
- package/templates/ecommerce/apps/api/src/application/catalog/catalog.service.ts +168 -0
- package/templates/ecommerce/apps/api/src/application/checkout/checkout.service.ts +114 -0
- package/templates/ecommerce/apps/api/src/application/orders/order.service.ts +93 -0
- package/templates/ecommerce/apps/api/src/application/ports/email.port.ts +3 -0
- package/templates/ecommerce/apps/api/src/application/ports/payment.port.ts +24 -0
- package/templates/ecommerce/apps/api/src/application/ports/shipping.port.ts +9 -0
- package/templates/ecommerce/apps/api/src/application/ports/storage.port.ts +3 -0
- package/templates/ecommerce/apps/api/src/application/ports/token-blacklist.port.ts +4 -0
- package/templates/ecommerce/apps/api/src/application/ports/token.port.ts +18 -0
- package/templates/ecommerce/apps/api/src/application/profile/profile.service.ts +76 -0
- package/templates/ecommerce/apps/api/src/domain/auth/user.entity.ts +109 -0
- package/templates/ecommerce/apps/api/src/domain/auth/user.repository.ts +11 -0
- package/templates/ecommerce/apps/api/src/domain/cart/cart.entity.ts +136 -0
- package/templates/ecommerce/apps/api/src/domain/cart/cart.repository.ts +8 -0
- package/templates/ecommerce/apps/api/src/domain/cart/coupon.entity.ts +58 -0
- package/templates/ecommerce/apps/api/src/domain/cart/coupon.repository.ts +10 -0
- package/templates/ecommerce/apps/api/src/domain/catalog/category.entity.ts +51 -0
- package/templates/ecommerce/apps/api/src/domain/catalog/category.repository.ts +10 -0
- package/templates/ecommerce/apps/api/src/domain/catalog/product.entity.ts +130 -0
- package/templates/ecommerce/apps/api/src/domain/catalog/product.repository.ts +28 -0
- package/templates/ecommerce/apps/api/src/domain/checkout/order.entity.ts +121 -0
- package/templates/ecommerce/apps/api/src/domain/checkout/order.repository.ts +11 -0
- package/templates/ecommerce/apps/api/src/domain/shared/AppError.ts +12 -0
- package/templates/ecommerce/apps/api/src/infrastructure/cache/redis.ts +16 -0
- package/templates/ecommerce/apps/api/src/infrastructure/config/registry/admin.registry.ts +13 -0
- package/templates/ecommerce/apps/api/src/infrastructure/config/registry/auth.registry.ts +34 -0
- package/templates/ecommerce/apps/api/src/infrastructure/config/registry/cart.registry.ts +49 -0
- package/templates/ecommerce/apps/api/src/infrastructure/config/registry/catalog.registry.ts +24 -0
- package/templates/ecommerce/apps/api/src/infrastructure/config/registry/checkout.registry.ts +47 -0
- package/templates/ecommerce/apps/api/src/infrastructure/config/registry/orders.registry.ts +6 -0
- package/templates/ecommerce/apps/api/src/infrastructure/config/registry/profile.registry.ts +4 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/in-memory/cart.memory.repository.ts +33 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/in-memory/category.memory.repository.ts +41 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/in-memory/coupon.memory.repository.ts +55 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/in-memory/order.memory.repository.ts +75 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/in-memory/product.memory.repository.ts +100 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/in-memory/user.memory.repository.ts +54 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/prisma/auth/user.prisma.repository.ts +83 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/prisma/catalog/category.prisma.repository.ts +69 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/prisma/catalog/product.prisma.repository.ts +185 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/prisma/checkout/order.prisma.repository.ts +149 -0
- package/templates/ecommerce/apps/api/src/infrastructure/persistence/prisma-client.ts +17 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/email/email.registry.ts +18 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/email/ethereal.email.service.ts +38 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/email/noop.email.service.ts +12 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/email/smtp.email.service.ts +36 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/payment/stripe-webhook.handler.ts +83 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/payment/stripe.adapter.ts +39 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/shipping/mock.shipping.service.ts +17 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/storage/in-memory.storage.service.ts +11 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/storage/local-disk.storage.service.ts +27 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/storage/s3.storage.service.ts +52 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/storage/storage.registry.ts +19 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/token/redis.token.blacklist.ts +23 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/token/token.blacklist.ts +30 -0
- package/templates/ecommerce/apps/api/src/infrastructure/services/token/token.service.ts +136 -0
- package/templates/ecommerce/apps/api/src/modules/admin/__tests__/admin.routes.integration.test.ts +250 -0
- package/templates/ecommerce/apps/api/src/modules/admin/admin.controller.ts +116 -0
- package/templates/ecommerce/apps/api/src/modules/admin/admin.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/admin/admin.routes.ts +21 -0
- package/templates/ecommerce/apps/api/src/modules/admin/admin.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/admin/admin.user.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/auth/__tests__/auth.logout.redis.test.ts +104 -0
- package/templates/ecommerce/apps/api/src/modules/auth/__tests__/auth.routes.integration.test.ts +211 -0
- package/templates/ecommerce/apps/api/src/modules/auth/__tests__/auth.service.unit.test.ts +260 -0
- package/templates/ecommerce/apps/api/src/modules/auth/__tests__/email.service.unit.test.ts +94 -0
- package/templates/ecommerce/apps/api/src/modules/auth/__tests__/token.blacklist.redis.test.ts +65 -0
- package/templates/ecommerce/apps/api/src/modules/auth/__tests__/user.entity.unit.test.ts +79 -0
- package/templates/ecommerce/apps/api/src/modules/auth/__tests__/user.prisma.repository.test.ts +138 -0
- package/templates/ecommerce/apps/api/src/modules/auth/auth.controller.ts +148 -0
- package/templates/ecommerce/apps/api/src/modules/auth/auth.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/auth/auth.routes.ts +17 -0
- package/templates/ecommerce/apps/api/src/modules/auth/auth.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/auth/redis.token.blacklist.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/auth/token.blacklist.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/auth/token.service.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/auth/user.entity.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/auth/user.prisma.repository.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/auth/user.repository.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/cart/__tests__/cart.entity.unit.test.ts +144 -0
- package/templates/ecommerce/apps/api/src/modules/cart/__tests__/cart.routes.integration.test.ts +242 -0
- package/templates/ecommerce/apps/api/src/modules/cart/__tests__/cart.service.unit.test.ts +151 -0
- package/templates/ecommerce/apps/api/src/modules/cart/__tests__/coupon.admin.integration.test.ts +136 -0
- package/templates/ecommerce/apps/api/src/modules/cart/cart.controller.ts +94 -0
- package/templates/ecommerce/apps/api/src/modules/cart/cart.entity.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/cart/cart.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/cart/cart.repository.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/cart/cart.routes.ts +17 -0
- package/templates/ecommerce/apps/api/src/modules/cart/cart.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/cart/coupon.entity.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/cart/coupon.repository.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/cart/coupon.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/cart/shipping.service.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/__tests__/catalog.routes.integration.test.ts +275 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/__tests__/catalog.service.unit.test.ts +223 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/__tests__/product.image.integration.test.ts +130 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/__tests__/product.prisma.repository.test.ts +174 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/catalog.controller.ts +176 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/catalog.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/catalog.routes.ts +38 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/catalog.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/category.entity.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/category.prisma.repository.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/category.repository.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/product.entity.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/product.prisma.repository.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/catalog/product.repository.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/__tests__/checkout.routes.integration.test.ts +163 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/__tests__/checkout.service.unit.test.ts +191 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/__tests__/order.prisma.repository.test.ts +150 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/checkout.controller.ts +59 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/checkout.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/checkout.routes.ts +18 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/checkout.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/order.entity.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/order.prisma.repository.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/order.repository.ts +2 -0
- package/templates/ecommerce/apps/api/src/modules/checkout/tax.service.ts +9 -0
- package/templates/ecommerce/apps/api/src/modules/orders/__tests__/order.entity.unit.test.ts +68 -0
- package/templates/ecommerce/apps/api/src/modules/orders/__tests__/order.routes.integration.test.ts +254 -0
- package/templates/ecommerce/apps/api/src/modules/orders/__tests__/order.service.email.unit.test.ts +142 -0
- package/templates/ecommerce/apps/api/src/modules/orders/order.controller.ts +96 -0
- package/templates/ecommerce/apps/api/src/modules/orders/order.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/orders/order.routes.ts +17 -0
- package/templates/ecommerce/apps/api/src/modules/orders/order.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/payment/__tests__/stripe-webhook.unit.test.ts +330 -0
- package/templates/ecommerce/apps/api/src/modules/payment/__tests__/stripe.adapter.unit.test.ts +84 -0
- package/templates/ecommerce/apps/api/src/modules/payment/adapters/stripe.adapter.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/payment/payment.port.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/payment/stripe-webhook.handler.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/profile/__tests__/profile.routes.integration.test.ts +180 -0
- package/templates/ecommerce/apps/api/src/modules/profile/__tests__/profile.service.unit.test.ts +187 -0
- package/templates/ecommerce/apps/api/src/modules/profile/profile.controller.ts +92 -0
- package/templates/ecommerce/apps/api/src/modules/profile/profile.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/modules/profile/profile.routes.ts +14 -0
- package/templates/ecommerce/apps/api/src/modules/profile/profile.service.ts +1 -0
- package/templates/ecommerce/apps/api/src/presentation/middlewares/authenticate.ts +37 -0
- package/templates/ecommerce/apps/api/src/presentation/middlewares/authorize.ts +23 -0
- package/templates/ecommerce/apps/api/src/presentation/middlewares/errorHandler.ts +48 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/admin/admin.controller.ts +116 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/admin/admin.routes.ts +21 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/auth/auth.controller.ts +147 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/auth/auth.routes.ts +17 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/cart/cart.controller.ts +94 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/cart/cart.routes.ts +17 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/catalog/catalog.controller.ts +176 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/catalog/catalog.routes.ts +38 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/checkout/checkout.controller.ts +59 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/checkout/checkout.routes.ts +18 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/orders/order.controller.ts +96 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/orders/order.routes.ts +17 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/profile/profile.controller.ts +92 -0
- package/templates/ecommerce/apps/api/src/presentation/modules/profile/profile.routes.ts +14 -0
- package/templates/ecommerce/apps/api/src/presentation/validators/uuidParam.ts +20 -0
- package/templates/ecommerce/apps/api/src/server.ts +47 -0
- package/templates/ecommerce/apps/api/src/shared/__tests__/uuid.validation.test.ts +111 -0
- package/templates/ecommerce/apps/api/src/shared/errors/AppError.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/email/EtherealEmailService.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/email/IEmailService.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/email/NoopEmailService.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/email/SmtpEmailService.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/email/__tests__/ethereal.email.integration.test.ts +32 -0
- package/templates/ecommerce/apps/api/src/shared/infra/email/email.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/prisma.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/redis.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/storage/IStorageService.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/storage/InMemoryStorageService.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/storage/LocalDiskStorageService.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/storage/S3StorageService.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/infra/storage/__tests__/s3.storage.unit.test.ts +73 -0
- package/templates/ecommerce/apps/api/src/shared/infra/storage/storage.registry.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/middlewares/authenticate.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/middlewares/authorize.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/middlewares/errorHandler.ts +1 -0
- package/templates/ecommerce/apps/api/src/shared/validators/uuidParam.ts +1 -0
- package/templates/ecommerce/apps/api/tsconfig.json +15 -0
- package/templates/ecommerce/apps/web/.env.example +8 -0
- package/templates/ecommerce/apps/web/index.html +19 -0
- package/templates/ecommerce/apps/web/jest.config.ts +45 -0
- package/templates/ecommerce/apps/web/package.json +38 -0
- package/templates/ecommerce/apps/web/src/App.tsx +133 -0
- package/templates/ecommerce/apps/web/src/__mocks__/fileMock.ts +1 -0
- package/templates/ecommerce/apps/web/src/__mocks__/styleMock.ts +1 -0
- package/templates/ecommerce/apps/web/src/index.css +159 -0
- package/templates/ecommerce/apps/web/src/main.tsx +13 -0
- package/templates/ecommerce/apps/web/src/modules/admin/__tests__/CouponsAdminPage.test.tsx +134 -0
- package/templates/ecommerce/apps/web/src/modules/admin/__tests__/DashboardPage.test.tsx +65 -0
- package/templates/ecommerce/apps/web/src/modules/admin/__tests__/OrdersAdminPage.test.tsx +79 -0
- package/templates/ecommerce/apps/web/src/modules/admin/__tests__/ProductsAdminPage.test.tsx +84 -0
- package/templates/ecommerce/apps/web/src/modules/admin/__tests__/UsersAdminPage.test.tsx +85 -0
- package/templates/ecommerce/apps/web/src/modules/admin/pages/CouponsAdminPage.tsx +179 -0
- package/templates/ecommerce/apps/web/src/modules/admin/pages/DashboardPage.tsx +58 -0
- package/templates/ecommerce/apps/web/src/modules/admin/pages/OrdersAdminPage.tsx +178 -0
- package/templates/ecommerce/apps/web/src/modules/admin/pages/ProductsAdminPage.tsx +444 -0
- package/templates/ecommerce/apps/web/src/modules/admin/pages/UsersAdminPage.tsx +87 -0
- package/templates/ecommerce/apps/web/src/modules/auth/LoginForm.tsx +91 -0
- package/templates/ecommerce/apps/web/src/modules/auth/RegisterForm.tsx +109 -0
- package/templates/ecommerce/apps/web/src/modules/auth/__tests__/ForgotPasswordPage.test.tsx +42 -0
- package/templates/ecommerce/apps/web/src/modules/auth/__tests__/LoginForm.test.tsx +76 -0
- package/templates/ecommerce/apps/web/src/modules/auth/__tests__/RegisterForm.test.tsx +62 -0
- package/templates/ecommerce/apps/web/src/modules/auth/__tests__/ResetPasswordPage.test.tsx +66 -0
- package/templates/ecommerce/apps/web/src/modules/auth/pages/ForgotPasswordPage.tsx +100 -0
- package/templates/ecommerce/apps/web/src/modules/auth/pages/LoginPage.tsx +39 -0
- package/templates/ecommerce/apps/web/src/modules/auth/pages/RegisterPage.tsx +39 -0
- package/templates/ecommerce/apps/web/src/modules/auth/pages/ResetPasswordPage.tsx +110 -0
- package/templates/ecommerce/apps/web/src/modules/auth/useAuthStore.ts +141 -0
- package/templates/ecommerce/apps/web/src/modules/cart/__tests__/CartPage.test.tsx +111 -0
- package/templates/ecommerce/apps/web/src/modules/cart/pages/CartPage.tsx +313 -0
- package/templates/ecommerce/apps/web/src/modules/catalog/__tests__/ProductCard.test.tsx +59 -0
- package/templates/ecommerce/apps/web/src/modules/catalog/__tests__/ProductFilters.test.tsx +56 -0
- package/templates/ecommerce/apps/web/src/modules/catalog/components/ProductCard.tsx +78 -0
- package/templates/ecommerce/apps/web/src/modules/catalog/components/ProductFilters.tsx +104 -0
- package/templates/ecommerce/apps/web/src/modules/catalog/pages/ProductDetailPage.tsx +179 -0
- package/templates/ecommerce/apps/web/src/modules/catalog/pages/ProductListPage.tsx +100 -0
- package/templates/ecommerce/apps/web/src/modules/checkout/__tests__/CheckoutPage.test.tsx +159 -0
- package/templates/ecommerce/apps/web/src/modules/checkout/__tests__/StripePaymentForm.test.tsx +79 -0
- package/templates/ecommerce/apps/web/src/modules/checkout/components/StripePaymentForm.tsx +55 -0
- package/templates/ecommerce/apps/web/src/modules/checkout/hooks/useCheckout.ts +56 -0
- package/templates/ecommerce/apps/web/src/modules/checkout/pages/CheckoutPage.tsx +344 -0
- package/templates/ecommerce/apps/web/src/modules/checkout/pages/CheckoutSuccessPage.tsx +12 -0
- package/templates/ecommerce/apps/web/src/modules/legal/pages/PrivacyPolicyPage.tsx +207 -0
- package/templates/ecommerce/apps/web/src/modules/legal/pages/TermsOfServicePage.tsx +175 -0
- package/templates/ecommerce/apps/web/src/modules/orders/__tests__/OrderDetailPage.test.tsx +75 -0
- package/templates/ecommerce/apps/web/src/modules/orders/__tests__/OrderHistoryPage.test.tsx +87 -0
- package/templates/ecommerce/apps/web/src/modules/orders/pages/OrderDetailPage.tsx +73 -0
- package/templates/ecommerce/apps/web/src/modules/orders/pages/OrderHistoryPage.tsx +97 -0
- package/templates/ecommerce/apps/web/src/modules/profile/__tests__/ProfilePage.test.tsx +150 -0
- package/templates/ecommerce/apps/web/src/modules/profile/pages/ProfilePage.tsx +275 -0
- package/templates/ecommerce/apps/web/src/setupTests.ts +10 -0
- package/templates/ecommerce/apps/web/src/shared/components/CookieConsent.tsx +108 -0
- package/templates/ecommerce/apps/web/src/shared/components/ErrorBoundary.tsx +112 -0
- package/templates/ecommerce/apps/web/src/shared/components/Layout.tsx +143 -0
- package/templates/ecommerce/apps/web/src/shared/components/ProtectedRoute.tsx +21 -0
- package/templates/ecommerce/apps/web/src/shared/config/siteConfig.ts +57 -0
- package/templates/ecommerce/apps/web/src/shared/hooks/usePageTitle.ts +16 -0
- package/templates/ecommerce/apps/web/src/shared/lib/apiFetch.ts +16 -0
- package/templates/ecommerce/apps/web/src/shared/pages/NotFoundPage.tsx +42 -0
- package/templates/ecommerce/apps/web/src/shared/theme/ThemeProvider.tsx +45 -0
- package/templates/ecommerce/apps/web/src/shared/theme/__tests__/ThemeProvider.test.tsx +78 -0
- package/templates/ecommerce/apps/web/src/shared/theme/createTheme.ts +58 -0
- package/templates/ecommerce/apps/web/src/shared/theme/tokens.ts +81 -0
- package/templates/ecommerce/apps/web/src/vite-env.d.ts +1 -0
- package/templates/ecommerce/apps/web/tsconfig.jest.json +12 -0
- package/templates/ecommerce/apps/web/tsconfig.json +25 -0
- package/templates/ecommerce/apps/web/tsconfig.node.json +11 -0
- package/templates/ecommerce/apps/web/vite.config.ts +30 -0
- package/templates/ecommerce/docker-compose.yml +85 -0
- package/templates/ecommerce/package-lock.json +11255 -0
- package/templates/ecommerce/package.json +27 -0
- package/templates/ecommerce/packages/shared-types/package.json +13 -0
- package/templates/ecommerce/packages/shared-types/src/index.ts +3 -0
- package/templates/ecommerce/packages/shared-types/src/theme.ts +44 -0
- package/templates/ecommerce/packages/shared-types/tsconfig.json +11 -0
- package/templates/ecommerce/scripts/customize.sh +201 -0
- package/templates/ecommerce/tsconfig.json +14 -0
- package/templates/java-spring/clean/.gitignore.hbs +72 -0
- package/templates/java-spring/clean/docker-compose.yml.hbs +6 -3
- package/templates/java-spring/clean/src/main/java/{{packagePath}}/application/usecase/PaymentUseCase.java.hbs +21 -17
- package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/persistence/entity/UserEntity.java.hbs +52 -0
- package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/persistence/repository/JpaUserRepository.java.hbs +12 -0
- package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/security/JwtAuthenticationFilter.java.hbs +64 -0
- package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/security/SecurityConfig.java.hbs +36 -0
- package/templates/java-spring/clean/src/main/java/{{packagePath}}/infrastructure/stripe/StripeGateway.java.hbs +63 -0
- package/templates/java-spring/clean/src/main/resources/application.properties.hbs +6 -7
- package/templates/java-spring/hexagonal/.gitignore.hbs +72 -0
- package/templates/java-spring/hexagonal/docker-compose.yml.hbs +6 -3
- package/templates/java-spring/hexagonal/src/main/java/{{packagePath}}/adapters/outbound/security/JwtFilter.java.hbs +71 -0
- package/templates/java-spring/hexagonal/src/main/java/{{packagePath}}/adapters/outbound/security/SecurityConfig.java.hbs +35 -0
- package/templates/java-spring/hexagonal/src/main/java/{{packagePath}}/core/service/PaymentService.java.hbs +3 -3
- package/templates/java-spring/hexagonal/src/main/resources/application.properties.hbs +4 -4
- package/templates/java-spring/mvc/.gitignore.hbs +72 -0
- package/templates/java-spring/mvc/docker-compose.yml.hbs +6 -3
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/config/SecurityConfig.java.hbs +13 -12
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/AuthController.java.hbs +9 -8
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/controller/PaymentsController.java.hbs +5 -6
- package/templates/java-spring/mvc/src/main/java/{{packagePath}}/service/StripeService.java.hbs +3 -3
- package/templates/java-spring/mvc/src/main/resources/application.yml.hbs +29 -26
- package/templates/nestjs/clean/.gitignore.hbs +42 -0
- package/templates/nestjs/clean/Dockerfile.hbs +6 -3
- package/templates/nestjs/clean/docker-compose.yml.hbs +1 -11
- package/templates/nestjs/clean/src/app.module.ts.hbs +2 -1
- package/templates/nestjs/clean/src/application/payment.service.ts.hbs +72 -72
- package/templates/nestjs/clean/src/domain/entities/user.entity.ts.hbs +2 -2
- package/templates/nestjs/clean/src/domain/repositories/user.repository.ts.hbs +2 -2
- package/templates/nestjs/clean/src/infrastructure/database/repositories/prisma.user.repository.ts.hbs +18 -18
- package/templates/nestjs/clean/src/infrastructure/http/health.controller.ts.hbs +9 -0
- package/templates/nestjs/clean/src/main.ts.hbs +1 -4
- package/templates/nestjs/clean/src/payment.module.ts.hbs +12 -12
- package/templates/nestjs/hexagonal/.gitignore.hbs +42 -0
- package/templates/nestjs/hexagonal/Dockerfile.hbs +6 -3
- package/templates/nestjs/hexagonal/docker-compose.yml.hbs +1 -11
- package/templates/nestjs/hexagonal/src/adapters/inbound/health.controller.ts.hbs +9 -0
- package/templates/nestjs/hexagonal/src/app.module.ts.hbs +2 -1
- package/templates/nestjs/hexagonal/src/core/domain/user.entity.ts.hbs +6 -6
- package/templates/nestjs/hexagonal/src/core/ports/ports.ts.hbs +4 -4
- package/templates/nestjs/hexagonal/src/main.ts.hbs +1 -4
- package/templates/nestjs/mvc/.gitignore.hbs +42 -0
- package/templates/nestjs/mvc/Dockerfile.hbs +6 -3
- package/templates/nestjs/mvc/docker-compose.yml.hbs +1 -11
- package/templates/nestjs/mvc/src/auth/auth.controller.ts.hbs +11 -1
- package/templates/nestjs/mvc/src/auth/auth.service.ts.hbs +3 -1
- package/templates/nestjs/mvc/src/controllers/health.controller.ts.hbs +6 -6
- package/templates/nestjs/mvc/src/main.ts.hbs +1 -4
- package/templates/nestjs/mvc/src/models/create-item.dto.ts.hbs +5 -2
- package/templates/nestjs/mvc/src/prisma/prisma.service.ts.hbs +1 -0
- package/templates/nextjs/mvc/.gitignore.hbs +42 -0
- package/templates/nextjs/mvc/Dockerfile.hbs +23 -8
- package/templates/nextjs/mvc/docker-compose.yml.hbs +1 -1
- package/templates/nodejs-express/clean/.gitignore.hbs +42 -0
- package/templates/nodejs-express/clean/Dockerfile.hbs +6 -1
- package/templates/nodejs-express/clean/docker-compose.yml.hbs +2 -2
- package/templates/nodejs-express/clean/package.json.hbs +69 -69
- package/templates/nodejs-express/clean/src/config.ts.hbs +11 -0
- package/templates/nodejs-express/clean/src/domain/entities/User.ts.hbs +46 -8
- package/templates/nodejs-express/hexagonal/.gitignore.hbs +42 -0
- package/templates/nodejs-express/hexagonal/Dockerfile.hbs +1 -1
- package/templates/nodejs-express/hexagonal/docker-compose.yml.hbs +2 -2
- package/templates/nodejs-express/hexagonal/package.json.hbs +69 -69
- package/templates/nodejs-express/hexagonal/src/adapters/inbound/http/PaymentController.ts.hbs +21 -38
- package/templates/nodejs-express/hexagonal/src/adapters/outbound/persistence/prisma.ts.hbs +2 -0
- package/templates/nodejs-express/hexagonal/src/config.ts.hbs +9 -0
- package/templates/nodejs-express/hexagonal/src/core/AuthService.ts.hbs +5 -5
- package/templates/nodejs-express/hexagonal/src/core/PaymentService.ts.hbs +7 -22
- package/templates/nodejs-express/hexagonal/src/core/domain/entities/User.ts.hbs +24 -4
- package/templates/nodejs-express/mvc/.gitignore.hbs +42 -0
- package/templates/nodejs-express/mvc/package.json.hbs +67 -67
- package/templates/python-fastapi/clean/.gitignore.hbs +76 -0
- package/templates/python-fastapi/clean/app/application/services/payment_service.py.hbs +3 -3
- package/templates/python-fastapi/clean/app/config.py.hbs +6 -7
- package/templates/python-fastapi/clean/app/domain/usecases/login_user.py.hbs +15 -0
- package/templates/python-fastapi/clean/app/infrastructure/http/auth_controller.py.hbs +40 -6
- package/templates/python-fastapi/clean/app/infrastructure/http/payment_controller.py.hbs +5 -4
- package/templates/python-fastapi/clean/app/infrastructure/security/jwt.py.hbs +23 -0
- package/templates/python-fastapi/clean/app/main.py.hbs +3 -0
- package/templates/python-fastapi/clean/docker-compose.yml.hbs +5 -12
- package/templates/python-fastapi/clean/requirements.txt.hbs +3 -0
- package/templates/python-fastapi/hexagonal/.gitignore.hbs +76 -0
- package/templates/python-fastapi/hexagonal/app/adapters/inbound/http_adapter.py.hbs +6 -9
- package/templates/python-fastapi/hexagonal/app/adapters/inbound/payment_http_adapter.py.hbs +4 -3
- package/templates/python-fastapi/hexagonal/app/adapters/outbound/stripe_adapter.py.hbs +30 -19
- package/templates/python-fastapi/hexagonal/app/config.py.hbs +14 -4
- package/templates/python-fastapi/hexagonal/app/core/domain/user.py.hbs +3 -1
- package/templates/python-fastapi/hexagonal/app/core/payment_service.py.hbs +28 -18
- package/templates/python-fastapi/hexagonal/app/core/ports/__init__.py.hbs +3 -0
- package/templates/python-fastapi/hexagonal/app/core/ports/user_repository.py.hbs +15 -0
- package/templates/python-fastapi/hexagonal/app/infrastructure/database/session.py.hbs +7 -0
- package/templates/python-fastapi/hexagonal/app/infrastructure/database/user_repository.py.hbs +53 -0
- package/templates/python-fastapi/hexagonal/app/infrastructure/security/__init__.py.hbs +0 -0
- package/templates/python-fastapi/hexagonal/app/infrastructure/security/adapters.py.hbs +23 -0
- package/templates/python-fastapi/hexagonal/app/infrastructure/security/jwt.py.hbs +23 -0
- package/templates/python-fastapi/hexagonal/docker-compose.yml.hbs +5 -12
- package/templates/python-fastapi/hexagonal/requirements.txt.hbs +4 -0
- package/templates/python-fastapi/mvc/.gitignore.hbs +76 -0
- package/templates/python-fastapi/mvc/app/controllers/payments.py.hbs +3 -17
- package/templates/python-fastapi/mvc/app/middleware/security.py.hbs +24 -3
- package/templates/python-fastapi/mvc/app/schemas/item.py.hbs +3 -1
- package/templates/python-fastapi/mvc/docker-compose.yml.hbs +5 -12
- package/templates/python-fastapi/mvc/requirements.txt.hbs +3 -1
- package/templates/nodejs-express/hexagonal/src/adapters/outbound/persistence/prisma.ts +0 -5
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ecommerce",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"workspaces": [
|
|
6
|
+
"apps/*",
|
|
7
|
+
"packages/*"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev:api": "npm run dev --workspace=apps/api",
|
|
11
|
+
"dev:web": "npm run dev --workspace=apps/web",
|
|
12
|
+
"test": "npm run test --workspaces --if-present",
|
|
13
|
+
"test:api": "npm run test --workspace=apps/api",
|
|
14
|
+
"test:web": "npm run test --workspace=apps/web",
|
|
15
|
+
"test:coverage": "npm run test:coverage --workspaces --if-present",
|
|
16
|
+
"build": "npm run build --workspaces --if-present",
|
|
17
|
+
"lint": "npm run lint --workspaces --if-present",
|
|
18
|
+
"format": "prettier --write \"**/*.{ts,tsx,json,md}\" --ignore-path .gitignore",
|
|
19
|
+
"db:migrate": "npm run db:migrate --workspace=apps/api",
|
|
20
|
+
"db:seed": "npm run db:seed --workspace=apps/api",
|
|
21
|
+
"db:studio": "npm run db:studio --workspace=apps/api",
|
|
22
|
+
"db:reset": "npm run db:reset --workspace=apps/api"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"prettier": "^3.4.2"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface ThemeColors {
|
|
2
|
+
primary: string;
|
|
3
|
+
secondary: string;
|
|
4
|
+
accent: string;
|
|
5
|
+
background: string;
|
|
6
|
+
surface: string;
|
|
7
|
+
error: string;
|
|
8
|
+
text: string;
|
|
9
|
+
textMuted: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ThemeTypography {
|
|
13
|
+
fontFamily: string;
|
|
14
|
+
fontSize: {
|
|
15
|
+
xs: string;
|
|
16
|
+
sm: string;
|
|
17
|
+
base: string;
|
|
18
|
+
lg: string;
|
|
19
|
+
xl: string;
|
|
20
|
+
'2xl': string;
|
|
21
|
+
'3xl': string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ThemeBorderRadius {
|
|
26
|
+
sm: string;
|
|
27
|
+
md: string;
|
|
28
|
+
lg: string;
|
|
29
|
+
full: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ThemeLogo {
|
|
33
|
+
src: string;
|
|
34
|
+
alt: string;
|
|
35
|
+
width: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ThemeConfig {
|
|
39
|
+
storeName: string;
|
|
40
|
+
colors: ThemeColors;
|
|
41
|
+
typography: ThemeTypography;
|
|
42
|
+
borderRadius: ThemeBorderRadius;
|
|
43
|
+
logo: ThemeLogo;
|
|
44
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# customize.sh — Personalizador white-label do template de e-commerce
|
|
4
|
+
# =============================================================================
|
|
5
|
+
# Uso: bash scripts/customize.sh
|
|
6
|
+
# Execute na raiz do projeto após clonar o repositório.
|
|
7
|
+
# =============================================================================
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# ── helpers ────────────────────────────────────────────────────────────────────
|
|
11
|
+
BOLD='\033[1m'
|
|
12
|
+
GREEN='\033[0;32m'
|
|
13
|
+
CYAN='\033[0;36m'
|
|
14
|
+
YELLOW='\033[1;33m'
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
RESET='\033[0m'
|
|
17
|
+
|
|
18
|
+
info() { echo -e "${CYAN}ℹ $*${RESET}"; }
|
|
19
|
+
success() { echo -e "${GREEN}✔ $*${RESET}"; }
|
|
20
|
+
warn() { echo -e "${YELLOW}⚠ $*${RESET}"; }
|
|
21
|
+
error() { echo -e "${RED}✖ $*${RESET}" >&2; }
|
|
22
|
+
|
|
23
|
+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
24
|
+
SITE_CONFIG="$REPO_ROOT/apps/web/src/shared/config/siteConfig.ts"
|
|
25
|
+
TOKENS_FILE="$REPO_ROOT/apps/web/src/shared/theme/tokens.ts"
|
|
26
|
+
|
|
27
|
+
# ── check files exist ──────────────────────────────────────────────────────────
|
|
28
|
+
for f in "$SITE_CONFIG" "$TOKENS_FILE"; do
|
|
29
|
+
if [[ ! -f "$f" ]]; then
|
|
30
|
+
error "Arquivo não encontrado: $f"
|
|
31
|
+
error "Execute este script na raiz do projeto."
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
done
|
|
35
|
+
|
|
36
|
+
# ── portable sed-in-place ──────────────────────────────────────────────────────
|
|
37
|
+
# macOS usa `sed -i ''`, Linux usa `sed -i`
|
|
38
|
+
sedi() {
|
|
39
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
40
|
+
LC_ALL=C sed -i '' "$@"
|
|
41
|
+
else
|
|
42
|
+
LC_ALL=C sed -i "$@"
|
|
43
|
+
fi
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# ── banner ─────────────────────────────────────────────────────────────────────
|
|
47
|
+
echo ""
|
|
48
|
+
echo -e "${BOLD}╔══════════════════════════════════════════════════════╗${RESET}"
|
|
49
|
+
echo -e "${BOLD}║ Personalizador de Loja — White-Label Setup ║${RESET}"
|
|
50
|
+
echo -e "${BOLD}╚══════════════════════════════════════════════════════╝${RESET}"
|
|
51
|
+
echo ""
|
|
52
|
+
info "Este script irá atualizar as configurações da sua loja."
|
|
53
|
+
info "Pressione ENTER para manter o valor atual (mostrado entre colchetes)."
|
|
54
|
+
echo ""
|
|
55
|
+
|
|
56
|
+
# ── prompt helpers ─────────────────────────────────────────────────────────────
|
|
57
|
+
ask() {
|
|
58
|
+
local prompt="$1"
|
|
59
|
+
local default="$2"
|
|
60
|
+
local var_name="$3"
|
|
61
|
+
echo -en "${BOLD}${prompt}${RESET} [${default}]: "
|
|
62
|
+
read -r input
|
|
63
|
+
if [[ -z "$input" ]]; then
|
|
64
|
+
eval "$var_name=\"\$default\""
|
|
65
|
+
else
|
|
66
|
+
eval "$var_name=\"\$input\""
|
|
67
|
+
fi
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
validate_hex_color() {
|
|
71
|
+
local color="$1"
|
|
72
|
+
if [[ ! "$color" =~ ^#[0-9A-Fa-f]{6}$ ]]; then
|
|
73
|
+
error "'$color' não é uma cor hex válida. Use o formato #RRGGBB (ex: #6366F1)"
|
|
74
|
+
return 1
|
|
75
|
+
fi
|
|
76
|
+
return 0
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
validate_cnpj() {
|
|
80
|
+
local cnpj="$1"
|
|
81
|
+
# Aceita formato XX.XXX.XXX/XXXX-XX ou sem formatação
|
|
82
|
+
if [[ ! "$cnpj" =~ ^[0-9]{2}\.[0-9]{3}\.[0-9]{3}/[0-9]{4}-[0-9]{2}$ ]] && \
|
|
83
|
+
[[ ! "$cnpj" =~ ^[0-9]{14}$ ]]; then
|
|
84
|
+
warn "CNPJ '$cnpj' não está no formato padrão (XX.XXX.XXX/XXXX-XX)."
|
|
85
|
+
warn "Continuando mesmo assim — você pode corrigir manualmente depois."
|
|
86
|
+
fi
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# ── coleta de dados ────────────────────────────────────────────────────────────
|
|
90
|
+
echo -e "${BOLD}── Informações da loja ─────────────────────────────────${RESET}"
|
|
91
|
+
echo ""
|
|
92
|
+
|
|
93
|
+
ask "Nome da loja" "Minha Loja" STORE_NAME
|
|
94
|
+
ask "Razão social (para documentos legais)" "Minha Loja LTDA" COMPANY_NAME
|
|
95
|
+
|
|
96
|
+
echo -en "${BOLD}CNPJ${RESET} [00.000.000/0001-00]: "
|
|
97
|
+
read -r CNPJ_INPUT
|
|
98
|
+
if [[ -z "$CNPJ_INPUT" ]]; then
|
|
99
|
+
CNPJ="00.000.000/0001-00"
|
|
100
|
+
else
|
|
101
|
+
CNPJ="$CNPJ_INPUT"
|
|
102
|
+
validate_cnpj "$CNPJ"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
ask "Endereço comercial" "Rua Exemplo, 123 — São Paulo, SP, CEP 01000-000" COMPANY_ADDRESS
|
|
106
|
+
|
|
107
|
+
echo ""
|
|
108
|
+
echo -e "${BOLD}── Contato ─────────────────────────────────────────────${RESET}"
|
|
109
|
+
echo ""
|
|
110
|
+
ask "E-mail de suporte" "suporte@minhaloja.com.br" SUPPORT_EMAIL
|
|
111
|
+
ask "E-mail de privacidade" "privacidade@minhaloja.com.br" PRIVACY_EMAIL
|
|
112
|
+
ask "URL da loja" "https://minhaloja.com.br" STORE_URL
|
|
113
|
+
|
|
114
|
+
echo ""
|
|
115
|
+
echo -e "${BOLD}── Identidade visual ────────────────────────────────────${RESET}"
|
|
116
|
+
echo ""
|
|
117
|
+
|
|
118
|
+
# Cor primária com validação
|
|
119
|
+
while true; do
|
|
120
|
+
ask "Cor primária (hex, ex: #6366F1)" "#6366F1" PRIMARY_COLOR
|
|
121
|
+
if validate_hex_color "$PRIMARY_COLOR"; then
|
|
122
|
+
break
|
|
123
|
+
fi
|
|
124
|
+
done
|
|
125
|
+
|
|
126
|
+
# ── resumo ─────────────────────────────────────────────────────────────────────
|
|
127
|
+
echo ""
|
|
128
|
+
echo -e "${BOLD}╔══════════════════════════════════════════════════════╗${RESET}"
|
|
129
|
+
echo -e "${BOLD}║ Resumo das alterações ║${RESET}"
|
|
130
|
+
echo -e "${BOLD}╚══════════════════════════════════════════════════════╝${RESET}"
|
|
131
|
+
echo ""
|
|
132
|
+
echo -e " Nome da loja : ${CYAN}${STORE_NAME}${RESET}"
|
|
133
|
+
echo -e " Razão social : ${CYAN}${COMPANY_NAME}${RESET}"
|
|
134
|
+
echo -e " CNPJ : ${CYAN}${CNPJ}${RESET}"
|
|
135
|
+
echo -e " Endereço : ${CYAN}${COMPANY_ADDRESS}${RESET}"
|
|
136
|
+
echo -e " E-mail suporte : ${CYAN}${SUPPORT_EMAIL}${RESET}"
|
|
137
|
+
echo -e " E-mail privac. : ${CYAN}${PRIVACY_EMAIL}${RESET}"
|
|
138
|
+
echo -e " URL : ${CYAN}${STORE_URL}${RESET}"
|
|
139
|
+
echo -e " Cor primária : ${CYAN}${PRIMARY_COLOR}${RESET}"
|
|
140
|
+
echo ""
|
|
141
|
+
echo -en "${BOLD}Aplicar estas configurações? [S/n]: ${RESET}"
|
|
142
|
+
read -r CONFIRM
|
|
143
|
+
if [[ "$CONFIRM" =~ ^[Nn]$ ]]; then
|
|
144
|
+
warn "Operação cancelada. Nenhum arquivo foi modificado."
|
|
145
|
+
exit 0
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
# ── apply changes ──────────────────────────────────────────────────────────────
|
|
149
|
+
echo ""
|
|
150
|
+
info "Aplicando alterações…"
|
|
151
|
+
|
|
152
|
+
# ---------- siteConfig.ts ----------
|
|
153
|
+
# name
|
|
154
|
+
sedi "s|name: '.*',$|name: '${STORE_NAME}',|" "$SITE_CONFIG"
|
|
155
|
+
|
|
156
|
+
# tagline (preserve original — usuário pode editar depois)
|
|
157
|
+
|
|
158
|
+
# url
|
|
159
|
+
sedi "s|url: '.*',$|url: '${STORE_URL}',|" "$SITE_CONFIG"
|
|
160
|
+
|
|
161
|
+
# supportEmail
|
|
162
|
+
sedi "s|supportEmail: '.*',$|supportEmail: '${SUPPORT_EMAIL}',|" "$SITE_CONFIG"
|
|
163
|
+
|
|
164
|
+
# privacyEmail
|
|
165
|
+
sedi "s|privacyEmail: '.*',$|privacyEmail: '${PRIVACY_EMAIL}',|" "$SITE_CONFIG"
|
|
166
|
+
|
|
167
|
+
# companyName
|
|
168
|
+
sedi "s|companyName: '.*',$|companyName: '${COMPANY_NAME}',|" "$SITE_CONFIG"
|
|
169
|
+
|
|
170
|
+
# cnpj
|
|
171
|
+
sedi "s|cnpj: '.*',$|cnpj: '${CNPJ}',|" "$SITE_CONFIG"
|
|
172
|
+
|
|
173
|
+
# address
|
|
174
|
+
sedi "s|address: '.*',$|address: '${COMPANY_ADDRESS}',|" "$SITE_CONFIG"
|
|
175
|
+
|
|
176
|
+
success "siteConfig.ts atualizado"
|
|
177
|
+
|
|
178
|
+
# ---------- tokens.ts ----------
|
|
179
|
+
# storeName
|
|
180
|
+
sedi "s|storeName: '.*',$|storeName: '${STORE_NAME}',|" "$TOKENS_FILE"
|
|
181
|
+
|
|
182
|
+
# primary color
|
|
183
|
+
sedi "s|primary: '#[0-9A-Fa-f]\{6\}',$|primary: '${PRIMARY_COLOR}',|" "$TOKENS_FILE"
|
|
184
|
+
|
|
185
|
+
success "tokens.ts atualizado"
|
|
186
|
+
|
|
187
|
+
# ── done ───────────────────────────────────────────────────────────────────────
|
|
188
|
+
echo ""
|
|
189
|
+
echo -e "${BOLD}${GREEN}╔══════════════════════════════════════════════════════╗${RESET}"
|
|
190
|
+
echo -e "${BOLD}${GREEN}║ Personalização concluída com sucesso! ║${RESET}"
|
|
191
|
+
echo -e "${BOLD}${GREEN}╚══════════════════════════════════════════════════════╝${RESET}"
|
|
192
|
+
echo ""
|
|
193
|
+
echo -e " Arquivos atualizados:"
|
|
194
|
+
echo -e " - apps/web/src/shared/config/siteConfig.ts"
|
|
195
|
+
echo -e " - apps/web/src/shared/theme/tokens.ts"
|
|
196
|
+
echo ""
|
|
197
|
+
echo -e " Próximos passos:"
|
|
198
|
+
echo -e " 1. Atualize os arquivos ${BOLD}.env${RESET} com as suas chaves (Stripe, SMTP, etc.)"
|
|
199
|
+
echo -e " 2. Execute ${CYAN}npm run dev${RESET} para iniciar o ambiente"
|
|
200
|
+
echo -e " 3. Acesse ${CYAN}http://localhost:5173${RESET} para visualizar a loja"
|
|
201
|
+
echo ""
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022"],
|
|
5
|
+
"strict": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"resolveJsonModule": true,
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"sourceMap": true
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Compiled class files
|
|
2
|
+
*.class
|
|
3
|
+
|
|
4
|
+
# Log files
|
|
5
|
+
*.log
|
|
6
|
+
|
|
7
|
+
# Package files
|
|
8
|
+
*.jar
|
|
9
|
+
*.war
|
|
10
|
+
*.nar
|
|
11
|
+
*.ear
|
|
12
|
+
*.zip
|
|
13
|
+
*.tar.gz
|
|
14
|
+
*.rar
|
|
15
|
+
|
|
16
|
+
# Virtual machine crash logs
|
|
17
|
+
hs_err_pid*
|
|
18
|
+
replay_pid*
|
|
19
|
+
|
|
20
|
+
# Maven
|
|
21
|
+
target/
|
|
22
|
+
.mvn/wrapper/maven-wrapper.jar
|
|
23
|
+
!**/src/main/**/target/
|
|
24
|
+
!**/src/test/**/target/
|
|
25
|
+
|
|
26
|
+
# Gradle
|
|
27
|
+
.gradle
|
|
28
|
+
build/
|
|
29
|
+
!gradle/wrapper/gradle-wrapper.jar
|
|
30
|
+
!**/src/main/**/build/
|
|
31
|
+
!**/src/test/**/build/
|
|
32
|
+
|
|
33
|
+
# Spring Boot
|
|
34
|
+
spring-shell.log
|
|
35
|
+
|
|
36
|
+
# STS / Eclipse
|
|
37
|
+
.apt_generated
|
|
38
|
+
.classpath
|
|
39
|
+
.factorypath
|
|
40
|
+
.project
|
|
41
|
+
.settings
|
|
42
|
+
.springBeans
|
|
43
|
+
.sts4-cache
|
|
44
|
+
|
|
45
|
+
# IntelliJ IDEA
|
|
46
|
+
.idea/
|
|
47
|
+
*.iws
|
|
48
|
+
*.iml
|
|
49
|
+
*.ipr
|
|
50
|
+
|
|
51
|
+
# VS Code
|
|
52
|
+
.vscode/
|
|
53
|
+
|
|
54
|
+
# NetBeans
|
|
55
|
+
/nbproject/private/
|
|
56
|
+
/nbbuild/
|
|
57
|
+
/nbdist/
|
|
58
|
+
/.nb-gradle/
|
|
59
|
+
|
|
60
|
+
# Environment
|
|
61
|
+
.env
|
|
62
|
+
.env.local
|
|
63
|
+
.env.*.local
|
|
64
|
+
!.env.example
|
|
65
|
+
application-local.yml
|
|
66
|
+
application-local.properties
|
|
67
|
+
application-dev.yml
|
|
68
|
+
application-dev.properties
|
|
69
|
+
|
|
70
|
+
# OS
|
|
71
|
+
.DS_Store
|
|
72
|
+
Thumbs.db
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
version: '3.8'
|
|
2
|
-
|
|
3
1
|
services:
|
|
4
|
-
|
|
2
|
+
db:
|
|
5
3
|
image: postgres:15-alpine
|
|
6
4
|
container_name: {{projectNameKebabCase}}-db
|
|
7
5
|
environment:
|
|
@@ -13,6 +11,11 @@ services:
|
|
|
13
11
|
volumes:
|
|
14
12
|
- postgres_data:/var/lib/postgresql/data
|
|
15
13
|
restart: unless-stopped
|
|
14
|
+
healthcheck:
|
|
15
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
16
|
+
interval: 10s
|
|
17
|
+
timeout: 5s
|
|
18
|
+
retries: 5
|
|
16
19
|
|
|
17
20
|
volumes:
|
|
18
21
|
postgres_data:
|
|
@@ -22,23 +22,24 @@ public class PaymentUseCase {
|
|
|
22
22
|
this.stripeGateway = stripeGateway;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
public String createCheckoutSession(String userId, String
|
|
26
|
-
|
|
27
|
-
import {{packageName}}.domain.l.UUID.fromString(userId))
|
|
25
|
+
public String createCheckoutSession(String userId, String priceId) throws Exception {
|
|
26
|
+
User user = userRepository.findById(userId)
|
|
28
27
|
.orElseThrow(() -> new RuntimeException("User not found"));
|
|
29
28
|
|
|
30
29
|
String customerId = user.getStripeCustomerId();
|
|
31
30
|
|
|
32
31
|
if (customerId == null || customerId.isEmpty()) {
|
|
33
|
-
|
|
32
|
+
customerId = stripeGateway.createCustomer(user.getEmail(), userId).getId();
|
|
34
33
|
user.setStripeCustomerId(customerId);
|
|
35
34
|
userRepository.save(user);
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
Session session = stripeGateway.createCheckoutSession(customerId, priceId, userId);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
return session.getUrl();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public String createPortalSession(String userId) throws Exception {
|
|
42
|
+
User user = userRepository.findById(userId)
|
|
42
43
|
.orElseThrow(() -> new RuntimeException("User not found"));
|
|
43
44
|
|
|
44
45
|
if (user.getStripeCustomerId() == null) {
|
|
@@ -56,7 +57,7 @@ import {{packageName}}.domain.l.UUID.fromString(userId))
|
|
|
56
57
|
Session session = (Session) event.getDataObjectDeserializer().getObject().orElse(null);
|
|
57
58
|
if (session != null && session.getClientReferenceId() != null) {
|
|
58
59
|
String userId = session.getClientReferenceId();
|
|
59
|
-
userRepository.findById(
|
|
60
|
+
userRepository.findById(userId).ifPresent(user -> {
|
|
60
61
|
user.setStripeCustomerId(session.getCustomer());
|
|
61
62
|
userRepository.save(user);
|
|
62
63
|
});
|
|
@@ -65,21 +66,24 @@ import {{packageName}}.domain.l.UUID.fromString(userId))
|
|
|
65
66
|
break;
|
|
66
67
|
}
|
|
67
68
|
case "customer.subscription.updated": {
|
|
68
|
-
com.stripe.model.Subscription sub =
|
|
69
|
-
|
|
70
|
-
if (sub != null)
|
|
69
|
+
com.stripe.model.Subscription sub = (com.stripe.model.Subscription) event.getDataObjectDeserializer()
|
|
70
|
+
.getObject().orElse(null);
|
|
71
|
+
if (sub != null)
|
|
72
|
+
logger.info("Subscription updated: {} | Status: {}", sub.getId(), sub.getStatus());
|
|
71
73
|
break;
|
|
72
74
|
}
|
|
73
75
|
case "customer.subscription.deleted": {
|
|
74
|
-
com.stripe.model.Subscription sub =
|
|
75
|
-
|
|
76
|
-
if (sub != null)
|
|
76
|
+
com.stripe.model.Subscription sub = (com.stripe.model.Subscription) event.getDataObjectDeserializer()
|
|
77
|
+
.getObject().orElse(null);
|
|
78
|
+
if (sub != null)
|
|
79
|
+
logger.info("Subscription deleted: {}", sub.getId());
|
|
77
80
|
break;
|
|
78
81
|
}
|
|
79
82
|
case "invoice.payment_failed": {
|
|
80
|
-
com.stripe.model.Invoice invoice =
|
|
81
|
-
|
|
82
|
-
if (invoice != null)
|
|
83
|
+
com.stripe.model.Invoice invoice = (com.stripe.model.Invoice) event.getDataObjectDeserializer()
|
|
84
|
+
.getObject().orElse(null);
|
|
85
|
+
if (invoice != null)
|
|
86
|
+
logger.info("Payment failed for invoice: {}", invoice.getId());
|
|
83
87
|
break;
|
|
84
88
|
}
|
|
85
89
|
default:
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
package {{packageName}}.infrastructure.persistence.entity;
|
|
2
|
+
|
|
3
|
+
import {{packageName}}.domain.entity.User;
|
|
4
|
+
import jakarta.persistence.Entity;
|
|
5
|
+
import jakarta.persistence.Id;
|
|
6
|
+
import jakarta.persistence.Table;
|
|
7
|
+
import lombok.AllArgsConstructor;
|
|
8
|
+
import lombok.Builder;
|
|
9
|
+
import lombok.Data;
|
|
10
|
+
import lombok.NoArgsConstructor;
|
|
11
|
+
|
|
12
|
+
import java.time.LocalDateTime;
|
|
13
|
+
|
|
14
|
+
@Entity
|
|
15
|
+
@Table(name = "users")
|
|
16
|
+
@Data
|
|
17
|
+
@NoArgsConstructor
|
|
18
|
+
@AllArgsConstructor
|
|
19
|
+
@Builder
|
|
20
|
+
public class UserEntity {
|
|
21
|
+
|
|
22
|
+
@Id
|
|
23
|
+
private String id;
|
|
24
|
+
|
|
25
|
+
private String email;
|
|
26
|
+
private String name;
|
|
27
|
+
private String password;
|
|
28
|
+
private String stripeCustomerId;
|
|
29
|
+
private LocalDateTime createdAt;
|
|
30
|
+
|
|
31
|
+
public static UserEntity fromDomain(User user) {
|
|
32
|
+
return UserEntity.builder()
|
|
33
|
+
.id(user.getId())
|
|
34
|
+
.email(user.getEmail())
|
|
35
|
+
.name(user.getName())
|
|
36
|
+
.password(user.getPassword())
|
|
37
|
+
.stripeCustomerId(user.getStripeCustomerId())
|
|
38
|
+
.createdAt(user.getCreatedAt())
|
|
39
|
+
.build();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public User toDomain() {
|
|
43
|
+
return User.restore(
|
|
44
|
+
this.id,
|
|
45
|
+
this.email,
|
|
46
|
+
this.name,
|
|
47
|
+
this.password,
|
|
48
|
+
this.stripeCustomerId,
|
|
49
|
+
this.createdAt
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package {{packageName}}.infrastructure.persistence.repository;
|
|
2
|
+
|
|
3
|
+
import {{packageName}}.infrastructure.persistence.entity.UserEntity;
|
|
4
|
+
import org.springframework.data.jpa.repository.JpaRepository;
|
|
5
|
+
import org.springframework.stereotype.Repository;
|
|
6
|
+
|
|
7
|
+
import java.util.Optional;
|
|
8
|
+
|
|
9
|
+
@Repository
|
|
10
|
+
public interface JpaUserRepository extends JpaRepository<UserEntity, String> {
|
|
11
|
+
Optional<UserEntity> findByEmail(String email);
|
|
12
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
package {{packageName}}.infrastructure.security;
|
|
2
|
+
|
|
3
|
+
import io.jsonwebtoken.Claims;
|
|
4
|
+
import io.jsonwebtoken.Jwts;
|
|
5
|
+
import io.jsonwebtoken.security.Keys;
|
|
6
|
+
import jakarta.servlet.FilterChain;
|
|
7
|
+
import jakarta.servlet.ServletException;
|
|
8
|
+
import jakarta.servlet.http.HttpServletRequest;
|
|
9
|
+
import jakarta.servlet.http.HttpServletResponse;
|
|
10
|
+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
11
|
+
import org.springframework.security.core.context.SecurityContextHolder;
|
|
12
|
+
import org.springframework.security.core.userdetails.User;
|
|
13
|
+
import org.springframework.security.core.userdetails.UserDetails;
|
|
14
|
+
import org.springframework.stereotype.Component;
|
|
15
|
+
import org.springframework.web.filter.OncePerRequestFilter;
|
|
16
|
+
|
|
17
|
+
import javax.crypto.SecretKey;
|
|
18
|
+
import java.io.IOException;
|
|
19
|
+
import java.nio.charset.StandardCharsets;
|
|
20
|
+
import java.util.ArrayList;
|
|
21
|
+
|
|
22
|
+
@Component
|
|
23
|
+
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|
24
|
+
|
|
25
|
+
private final String jwtSecret;
|
|
26
|
+
|
|
27
|
+
public JwtAuthenticationFilter(
|
|
28
|
+
@org.springframework.beans.factory.annotation.Value("${jwt.secret:your-super-secret-jwt-key-change-in-production}") String jwtSecret) {
|
|
29
|
+
this.jwtSecret = jwtSecret;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private SecretKey getSigningKey() {
|
|
33
|
+
return Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Override
|
|
37
|
+
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
|
38
|
+
throws ServletException, IOException {
|
|
39
|
+
String header = request.getHeader("Authorization");
|
|
40
|
+
|
|
41
|
+
if (header != null && header.startsWith("Bearer ")) {
|
|
42
|
+
String token = header.substring(7);
|
|
43
|
+
try {
|
|
44
|
+
Claims claims = Jwts.parser()
|
|
45
|
+
.verifyWith(getSigningKey())
|
|
46
|
+
.build()
|
|
47
|
+
.parseSignedClaims(token)
|
|
48
|
+
.getPayload();
|
|
49
|
+
|
|
50
|
+
String userId = claims.getSubject();
|
|
51
|
+
if (userId != null) {
|
|
52
|
+
UserDetails userDetails = new User(userId, "", new ArrayList<>());
|
|
53
|
+
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
|
54
|
+
userDetails, null, userDetails.getAuthorities());
|
|
55
|
+
SecurityContextHolder.getContext().setAuthentication(authentication);
|
|
56
|
+
}
|
|
57
|
+
} catch (Exception e) {
|
|
58
|
+
logger.warn("Invalid JWT token: " + e.getMessage());
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
filterChain.doFilter(request, response);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
package {{packageName}}.infrastructure.security;
|
|
2
|
+
|
|
3
|
+
import org.springframework.context.annotation.Bean;
|
|
4
|
+
import org.springframework.context.annotation.Configuration;
|
|
5
|
+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
6
|
+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
7
|
+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
8
|
+
import org.springframework.security.config.http.SessionCreationPolicy;
|
|
9
|
+
import org.springframework.security.web.SecurityFilterChain;
|
|
10
|
+
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
11
|
+
|
|
12
|
+
@Configuration
|
|
13
|
+
@EnableWebSecurity
|
|
14
|
+
public class SecurityConfig {
|
|
15
|
+
|
|
16
|
+
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
|
17
|
+
|
|
18
|
+
public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
|
|
19
|
+
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Bean
|
|
23
|
+
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
|
24
|
+
http
|
|
25
|
+
.csrf(AbstractHttpConfigurer::disable)
|
|
26
|
+
.authorizeHttpRequests(auth -> auth
|
|
27
|
+
.requestMatchers("/api/auth/**").permitAll()
|
|
28
|
+
.requestMatchers("/api/payments/webhook").permitAll()
|
|
29
|
+
.requestMatchers("/actuator/**").permitAll()
|
|
30
|
+
.anyRequest().authenticated()
|
|
31
|
+
)
|
|
32
|
+
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
33
|
+
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
|
34
|
+
return http.build();
|
|
35
|
+
}
|
|
36
|
+
}
|