Backend:
- Multi-branch shop management: SetDefaultShop, TransferShop commands, GetMerchantShops paginated query
- Shop aggregate: IsDefault field, SetAsDefault/ClearDefault/TransferOwnership behavior methods
- 2 new domain events: ShopSetAsDefaultDomainEvent, ShopTransferredDomainEvent
Frontend:
- Revenue Dashboard (MudChart line/donut/bar, 4 KPI cards, top products table)
- Staff Performance (sortable table, color-coded completion rates, CSV export)
- Customer QR Menu page (/menu/{ShopId}, mobile-first, Vietnamese labels)
- QR Code Generator admin page (batch generate, print-all, per-table QR)
- Responsive POS layout (collapsible sidebar, slide-out order drawer, touch-friendly CSS)
- ResponsiveOrderPanel component (desktop inline / tablet drawer / mobile overlay)
Infrastructure:
- Production K8s manifests: 8 services (3 replicas, 512Mi-1Gi, HPA min3/max10), Redis with persistence
- Production ingress: api.goodgo.vn, cert-manager TLS, rate-limit middleware
- Deploy script: pre-flight checks, dry-run, single-service deploy, rollback support
- CI/CD: deploy-production.yml with environment approval, commit SHA tags
- Prometheus full scrape config (11 targets), docker-compose observability stack
- Production deployment checklist (80+ items)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
65 lines
3.8 KiB
Plaintext
65 lines
3.8 KiB
Plaintext
# EN: Kubernetes Secrets Template for GoodGo Production
|
|
# VI: Template Secrets Kubernetes cho GoodGo Production
|
|
#
|
|
# DO NOT commit actual secrets to Git.
|
|
# Use this as a template to create secrets via kubectl or sealed-secrets.
|
|
#
|
|
# =============================================================================
|
|
# Option 1: Create secrets using kubectl (manual)
|
|
# =============================================================================
|
|
#
|
|
# kubectl create secret generic goodgo-secrets \
|
|
# --from-literal=Jwt__Secret='your-production-jwt-secret-min-64-chars-strong-random' \
|
|
# --from-literal=Jwt__RefreshSecret='your-production-refresh-secret-min-64-chars-strong-random' \
|
|
# --from-literal=IdentityServer__IssuerUri='https://api.goodgo.vn' \
|
|
# --from-literal=IAM_DATABASE_URL='postgresql://user:pass@ep-xxx.region.neon.tech/iam_production?sslmode=require&pgbouncer=true' \
|
|
# --from-literal=MERCHANT_DATABASE_URL='postgresql://user:pass@ep-xxx.region.neon.tech/merchant_production?sslmode=require&pgbouncer=true' \
|
|
# --from-literal=ORDER_DATABASE_URL='postgresql://user:pass@ep-xxx.region.neon.tech/order_production?sslmode=require&pgbouncer=true' \
|
|
# --from-literal=FNB_DATABASE_URL='postgresql://user:pass@ep-xxx.region.neon.tech/fnb_production?sslmode=require&pgbouncer=true' \
|
|
# --from-literal=INVENTORY_DATABASE_URL='postgresql://user:pass@ep-xxx.region.neon.tech/inventory_production?sslmode=require&pgbouncer=true' \
|
|
# --from-literal=WALLET_DATABASE_URL='postgresql://user:pass@ep-xxx.region.neon.tech/wallet_production?sslmode=require&pgbouncer=true' \
|
|
# --from-literal=CATALOG_DATABASE_URL='postgresql://user:pass@ep-xxx.region.neon.tech/catalog_production?sslmode=require&pgbouncer=true' \
|
|
# --from-literal=BOOKING_DATABASE_URL='postgresql://user:pass@ep-xxx.region.neon.tech/booking_production?sslmode=require&pgbouncer=true' \
|
|
# --from-literal=Redis__Password='your-strong-redis-password' \
|
|
# --from-literal=ConnectionStrings__Redis='redis:6379,password=your-strong-redis-password,abortConnect=false' \
|
|
# --from-literal=Storage__MinIO__Endpoint='minio.goodgo.vn' \
|
|
# --from-literal=Storage__MinIO__AccessKey='your-minio-access-key' \
|
|
# --from-literal=Storage__MinIO__SecretKey='your-minio-secret-key' \
|
|
# --from-literal=RabbitMQ__Host='rabbitmq' \
|
|
# --from-literal=RabbitMQ__Username='goodgo' \
|
|
# --from-literal=RabbitMQ__Password='your-strong-rabbitmq-password' \
|
|
# -n production
|
|
#
|
|
# =============================================================================
|
|
# Option 2: Use GitHub Secrets in CI/CD (for automated deployments)
|
|
# =============================================================================
|
|
#
|
|
# Required GitHub Secrets:
|
|
# - KUBECONFIG_PRODUCTION (base64 encoded kubeconfig)
|
|
# - DOCKER_USERNAME / DOCKER_PASSWORD
|
|
# - NEON_IAM_DATABASE_URL_PRODUCTION
|
|
# - NEON_MERCHANT_DATABASE_URL_PRODUCTION
|
|
# - NEON_ORDER_DATABASE_URL_PRODUCTION
|
|
# - NEON_FNB_DATABASE_URL_PRODUCTION
|
|
# - NEON_INVENTORY_DATABASE_URL_PRODUCTION
|
|
# - NEON_WALLET_DATABASE_URL_PRODUCTION
|
|
# - NEON_CATALOG_DATABASE_URL_PRODUCTION
|
|
# - NEON_BOOKING_DATABASE_URL_PRODUCTION
|
|
# - JWT_SECRET_PRODUCTION
|
|
# - JWT_REFRESH_SECRET_PRODUCTION
|
|
# - REDIS_PASSWORD_PRODUCTION
|
|
# - MINIO_ACCESS_KEY_PRODUCTION
|
|
# - MINIO_SECRET_KEY_PRODUCTION
|
|
# - RABBITMQ_PASSWORD_PRODUCTION
|
|
#
|
|
# =============================================================================
|
|
# Option 3: Use sealed-secrets or external-secrets operator (RECOMMENDED for production)
|
|
# =============================================================================
|
|
#
|
|
# Install sealed-secrets controller:
|
|
# kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.5/controller.yaml
|
|
#
|
|
# Create sealed secret:
|
|
# kubeseal --format yaml < secret.yaml > sealed-secret.yaml
|
|
# kubectl apply -f sealed-secret.yaml
|