diff --git a/.gitignore b/.gitignore
index d9bf8f57..ffbfbdb0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ node_modules/
**/package-lock.json
# Environment files
+.stack.env
.env
.env.local
.env.development
diff --git a/apps/portal/src/lib/providers.tsx b/apps/portal/src/lib/providers.tsx
index 8cde2984..552dd61a 100644
--- a/apps/portal/src/lib/providers.tsx
+++ b/apps/portal/src/lib/providers.tsx
@@ -51,7 +51,7 @@ export function QueryProvider({ children, nonce }: QueryProviderProps) {
return (
{children}
- {process.env.NODE_ENV === "development" && }
+ {process.env.NODE_ENV === "development" && }
);
}
diff --git a/docker/Prod - Portainer/README.md b/docker/Prod - Portainer/README.md
index db3c4726..fb78db25 100644
--- a/docker/Prod - Portainer/README.md
+++ b/docker/Prod - Portainer/README.md
@@ -23,7 +23,7 @@ docker images | grep portal
2. Name: `customer-portal`
3. Paste contents of `docker-compose.yml`
4. Scroll down to **Environment Variables**
-5. Copy variables from `stack.env.example` and fill in your values
+5. Copy variables from `stack.env.example` and fill in your production values
### 3. Generate Secrets
diff --git a/docker/Prod - Portainer/docker-compose.yml b/docker/Prod - Portainer/docker-compose.yml
index a1e1016f..aa42ad71 100644
--- a/docker/Prod - Portainer/docker-compose.yml
+++ b/docker/Prod - Portainer/docker-compose.yml
@@ -25,7 +25,7 @@ services:
links:
- backend
healthcheck:
- test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"]
+ test: ["CMD", "node", "-e", "fetch('http://localhost:3000/api/health').then(r=>r.ok||process.exit(1)).catch(()=>process.exit(1))"]
interval: 30s
timeout: 10s
start_period: 40s
@@ -117,7 +117,7 @@ services:
# - Database migration when RUN_MIGRATIONS=true
# - Waiting for dependencies (nc checks in entrypoint)
healthcheck:
- test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/health"]
+ test: ["CMD", "node", "-e", "fetch('http://localhost:4000/health').then(r=>r.ok||process.exit(1)).catch(()=>process.exit(1))"]
interval: 30s
timeout: 10s
start_period: 60s
diff --git a/docker/Prod - Portainer/stack.env.example b/docker/Prod - Portainer/env.example
similarity index 73%
rename from docker/Prod - Portainer/stack.env.example
rename to docker/Prod - Portainer/env.example
index a6a80259..8bfbbf0b 100644
--- a/docker/Prod - Portainer/stack.env.example
+++ b/docker/Prod - Portainer/env.example
@@ -1,8 +1,8 @@
# =============================================================================
-# Customer Portal - Portainer Environment Variables (TEMPLATE)
+# Customer Portal - Portainer Environment Variables
# =============================================================================
-# Copy this file and fill in your actual values.
-# DO NOT commit files with real secrets to version control.
+# Copy these into Portainer UI when creating/updating the stack
+# Replace all placeholder values with your actual secrets
# =============================================================================
# -----------------------------------------------------------------------------
@@ -18,26 +18,24 @@ BACKEND_PORT=4000
# Application
# -----------------------------------------------------------------------------
APP_NAME=customer-portal-bff
-APP_BASE_URL=https://your-domain.com
-CORS_ORIGIN=https://your-domain.com
+APP_BASE_URL=https://asolutions.jp
+CORS_ORIGIN=https://asolutions.jp
# -----------------------------------------------------------------------------
# Database (PostgreSQL)
# -----------------------------------------------------------------------------
POSTGRES_DB=portal_prod
POSTGRES_USER=portal
-# Generate with: openssl rand -base64 24
-POSTGRES_PASSWORD=
+POSTGRES_PASSWORD=
# -----------------------------------------------------------------------------
# Security & Auth
# -----------------------------------------------------------------------------
# Generate with: openssl rand -base64 32
-JWT_SECRET=
+JWT_SECRET=
JWT_EXPIRES_IN=7d
BCRYPT_ROUNDS=12
-# Generate with: openssl rand -base64 32
-CSRF_SECRET_KEY=
+CSRF_SECRET_KEY=
# Auth Settings
AUTH_ALLOW_REDIS_TOKEN_FAILOPEN=false
@@ -51,45 +49,44 @@ RATE_LIMIT_LIMIT=100
# -----------------------------------------------------------------------------
# WHMCS Integration
# -----------------------------------------------------------------------------
-WHMCS_BASE_URL=https://your-whmcs-instance.com
-WHMCS_API_IDENTIFIER=
-WHMCS_API_SECRET=
-
+WHMCS_BASE_URL=https://accounts.asolutions.co.jp
+WHMCS_API_IDENTIFIER=
+WHMCS_API_SECRET=
# -----------------------------------------------------------------------------
# Salesforce Integration
# -----------------------------------------------------------------------------
-SF_LOGIN_URL=https://your-org.my.salesforce.com
-SF_CLIENT_ID=
-SF_USERNAME=
+SF_LOGIN_URL=https://asolutions.my.salesforce.com
+SF_CLIENT_ID=
+SF_USERNAME=
SF_EVENTS_ENABLED=true
# Salesforce Private Key (Base64 encoded)
# To encode: base64 -w 0 < sf-private.key
-SF_PRIVATE_KEY_BASE64=
+SF_PRIVATE_KEY_BASE64=
+
# -----------------------------------------------------------------------------
# Freebit SIM API
# -----------------------------------------------------------------------------
FREEBIT_BASE_URL=https://i1.mvno.net/emptool/api
-FREEBIT_OEM_ID=
-FREEBIT_OEM_KEY=
+FREEBIT_OEM_ID=PASI
+FREEBIT_OEM_KEY=
# -----------------------------------------------------------------------------
# Email (SendGrid)
# -----------------------------------------------------------------------------
EMAIL_ENABLED=true
-EMAIL_FROM=no-reply@your-domain.com
-EMAIL_FROM_NAME=Your Company Name
+EMAIL_FROM=no-reply@asolutions.jp
+EMAIL_FROM_NAME=Assist Solutions
SENDGRID_API_KEY=
# -----------------------------------------------------------------------------
# Salesforce Portal Config
# -----------------------------------------------------------------------------
-PORTAL_PRICEBOOK_ID=
+PORTAL_PRICEBOOK_ID=
PORTAL_PRICEBOOK_NAME=Portal
# -----------------------------------------------------------------------------
# Logging
# -----------------------------------------------------------------------------
LOG_LEVEL=info
-
diff --git a/docker/Prod - Portainer/stack.env b/docker/Prod - Portainer/stack.env
deleted file mode 100644
index e3634cfc..00000000
--- a/docker/Prod - Portainer/stack.env
+++ /dev/null
@@ -1,112 +0,0 @@
-# =============================================================================
-# Customer Portal - Portainer Environment Variables
-# =============================================================================
-# Copy these into Portainer UI when creating/updating the stack
-# Replace all placeholder values with your actual secrets
-# =============================================================================
-
-# -----------------------------------------------------------------------------
-# Images & Ports
-# -----------------------------------------------------------------------------
-FRONTEND_IMAGE=portal-frontend
-BACKEND_IMAGE=portal-backend
-IMAGE_TAG=latest
-FRONTEND_PORT=3000
-BACKEND_PORT=4000
-
-# -----------------------------------------------------------------------------
-# Application
-# -----------------------------------------------------------------------------
-APP_NAME=customer-portal-bff
-APP_BASE_URL=https://asolutions.jp
-CORS_ORIGIN=https://asolutions.jp
-
-# -----------------------------------------------------------------------------
-# Database (PostgreSQL)
-# -----------------------------------------------------------------------------
-POSTGRES_DB=portal_prod
-POSTGRES_USER=portal
-POSTGRES_PASSWORD=wf8vVNxaGXqJbE4AMwBg8olJtUptLNcH
-
-# -----------------------------------------------------------------------------
-# Security & Auth
-# -----------------------------------------------------------------------------
-# Generate with: openssl rand -base64 32
-JWT_SECRET=N+HXXwJBM93omVC8mCbrrWKNR/deCmSe5q4TTwMFur8=
-JWT_EXPIRES_IN=7d
-BCRYPT_ROUNDS=12
-CSRF_SECRET_KEY=/W6PPJ0DeduasE4GqeLIxfdSNg9TDNwyuVNz0IWz0Bs=
-
-# Auth Settings
-AUTH_ALLOW_REDIS_TOKEN_FAILOPEN=false
-AUTH_REQUIRE_REDIS_FOR_TOKENS=false
-AUTH_MAINTENANCE_MODE=false
-
-# Rate Limiting
-RATE_LIMIT_TTL=60
-RATE_LIMIT_LIMIT=100
-
-# -----------------------------------------------------------------------------
-# WHMCS Integration
-# -----------------------------------------------------------------------------
-WHMCS_BASE_URL=https://dev-wh.asolutions.co.jp
-WHMCS_API_IDENTIFIER=WZckHGfzAQEum3v5SAcSfzgvVkPJEF2M
-WHMCS_API_SECRET=YlqKyynJ6I1088DV6jufFj6cJiW0N0y4
-# -----------------------------------------------------------------------------
-# Salesforce Integration
-# -----------------------------------------------------------------------------
-SF_LOGIN_URL=https://asolutions.my.salesforce.com
-SF_CLIENT_ID=3MVG9n_HvETGhr3Af33utEHAR_KbKEQh_.KRzVBBA6u3tSIMraIlY9pqNqKJgUILstAPS4JASzExj3OpCRbLz
-SF_USERNAME=portal.integration@asolutions.co.jp
-SF_EVENTS_ENABLED=true
-
-# Salesforce Private Key (Base64 encoded)
-# To encode: base64 -w 0 < sf-private.key
-SF_PRIVATE_KEY_BASE64=MIIDvzCCAqegAwIBAgIUWD/Nx/Tem+FbPzsowuIYP6eioWwwDQYJKoZIhvcNAQEL
-BQAwbzELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMQ4wDAYDVQQHDAVUb2t5
-bzEZMBcGA1UECgwQQXNzaXN0IFNvbHV0aW9uczELMAkGA1UECwwCSVQxGDAWBgNV
-BAMMD0N1c3RvbWVyIFBvcnRhbDAeFw0yNTA4MTUwNTAxMDNaFw0yNjA4MTUwNTAx
-MDNaMG8xCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEOMAwGA1UEBwwFVG9r
-eW8xGTAXBgNVBAoMEEFzc2lzdCBTb2x1dGlvbnMxCzAJBgNVBAsMAklUMRgwFgYD
-VQQDDA9DdXN0b21lciBQb3J0YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQCtBK38ZXzz3LA8dKqHbwz+ucWLPqz8sjoXY4V0W+fMhifn5Oi4u3k2mlqg
-J2bGFPn8DH5cRafM0+CCwO9TV6PbYxolsO7NKjFxSERJPqj5tZ0bpZljul4J0wiJ
-ZyT8NWK+WV9aga+zrHOThgvUSPJAb3I1FbRSSha9k2UsaZ5Ubo43EFMRAoAU1DqV
-tRvG9UW+Ditrlr/8hhDT8WREwzwdGc4GVtM2AsiNNbKM5kcjhu8sgKZ2j+ZCM+0l
-yk0JUcciSYUWgY79XEvCVAAiUGiL3qtxurEe02f9/ISWawbJne1SQIhaXZycsehm
-VHN4ySW5uj2waOu4IzDXOqW75e+1AgMBAAGjUzBRMB0GA1UdDgQWBBTOBfxQ/VS+
-MtjqnY2ielB6n4qHVDAfBgNVHSMEGDAWgBTOBfxQ/VS+MtjqnY2ielB6n4qHVDAP
-BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAcpPfUF4kPuiB91Igq
-gwpRZmUJjq0+fIv2Llyn3Q+srk/IOcnkjJgaksGTXPwsMErtcD60z1tIzp39aDl2
-wUmTxssXg41X7jBpy9Q7wXduvZwpSHbwrz8GShGKnwBCITTVHg0PRCIMn9DvJg3H
-So/A2TQyazhWSh1yz4P6hAn7UKAG4rzMPjyzq+RYFOSKKCtdJ5ImqIkrNnHhQj/4
-py/E6K6/ZkroKWr6z1gFU2E8xQQ+u1YNAEjL8U+vd0ftLmYTHCciaZdy4emo5BRg
-V8oZp81Kw1Da+nVuBCMtZ4ICYLBI8LVtfkzdFDr3MShRWcPe+k6/lbDfT98qy01O
-26sJ
-
-
-# -----------------------------------------------------------------------------
-# Freebit SIM API
-# -----------------------------------------------------------------------------
-FREEBIT_BASE_URL=https://i1-q.mvno.net/emptool/api
-FREEBIT_OEM_ID=PASI
-FREEBIT_OEM_KEY=6Au3o7wrQNR07JxFHPmf0YfFqN9a31t5
-
-# -----------------------------------------------------------------------------
-# Email (SendGrid)
-# -----------------------------------------------------------------------------
-EMAIL_ENABLED=true
-EMAIL_FROM=no-reply@asolutions.jp
-EMAIL_FROM_NAME=Assist Solutions
-SENDGRID_API_KEY=
-
-# -----------------------------------------------------------------------------
-# Salesforce Portal Config
-# -----------------------------------------------------------------------------
-PORTAL_PRICEBOOK_ID=01sTL000008eLVlYAM
-PORTAL_PRICEBOOK_NAME=Portal
-
-# -----------------------------------------------------------------------------
-# Logging
-# -----------------------------------------------------------------------------
-LOG_LEVEL=info