From 22e98ebd4b22d71c733482be240a338a06535cc6 Mon Sep 17 00:00:00 2001 From: "ahmed.mujtaba" Date: Mon, 24 Aug 2026 16:22:37 +0000 Subject: [PATCH 1/6] ,. --- .env | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 94335dc..0000000 --- a/.env +++ /dev/null @@ -1,5 +0,0 @@ -# Compose pointer only — NO secrets here. -# Makes `docker compose up -d --build` read ${FRONTEND_PORT}, ${BACKEND_PORT}, … -# from backend/.env without typing --env-file every time. -# All credentials and app config live in backend/.env. -COMPOSE_ENV_FILES=./backend/.env From fa1fb7c5a443c67ab84f884576578bf290fdf43a Mon Sep 17 00:00:00 2001 From: "ahmed.mujtaba" Date: Mon, 24 Aug 2026 16:23:00 +0000 Subject: [PATCH 2/6] . --- backend/.env | 105 --------------------------------------------------- 1 file changed, 105 deletions(-) delete mode 100644 backend/.env diff --git a/backend/.env b/backend/.env deleted file mode 100644 index 2cca649..0000000 --- a/backend/.env +++ /dev/null @@ -1,105 +0,0 @@ - -# true → RDS over SSL (asyncpg). false → local Postgres over asyncpg (no SSH). -PROD_ENV=false - -DB_USERNAME=postgres -DB_PASSWORD=ambaig123 -DB_HOST=localhost -DB_PORT=5432 -DB_NAME=dev_hrms -# Blank: require when PROD_ENV=true, off when local. Override only if needed. -DB_SSLMODE= -# DB_USERNAME=utopiaaiadmin -# DB_PASSWORD=cOIYBbjeRpb5rZigZBYX -# DB_HOST=utopia-ai-hr-ats-portal-db.co658idowpql.us-east-2.rds.amazonaws.com -# DB_PORT=5432 -# DB_NAME=dev_hrms -# DB_SSLMODE=require - -EMAIL_URL=http://172.16.204.191:5000 -EMAIL_API_TOKEN=vn1a9sx6tI3L5LVXgblOiVpxn3gAiJXTVYvO5GICUNo -EMAIL_SYNC_FOLDER=inbox -EMAIL_SYNC_SINCE= -EMAIL_SYNC_CRON=* * * * * -JWT_SECRET_KEY=8B6lep0TuSrGp__2SFDCqKGyEluuUWV7SxvobhG5ECQYvN4o4P0OakRW0VWmiflZ6hgNK7RGdOVmi4H8LnSLwA -JWT_ALGORITHM=HS256 -JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 -JWT_REFRESH_TOKEN_EXPIRE_DAYS=7 - -TEAMS_MAIL_API_URL=http://ec2-13-222-174-68.compute-1.amazonaws.com:8000/mail/send -TEAMS_API_TOKEN=wt139Dg1bm0lXoYszzwCcMmkjQrkuP -RESET_CODE_TTL_SECONDS=60 -RESET_CODE_RESEND_SECONDS=30 -RESET_CODE_MAX_ATTEMPTS=5 -JWT_RESET_TOKEN_EXPIRE_MINUTES=10 - -# Vite / email links. Docker SPA publishes on FRONTEND_PORT (5173). -FRONTEND_URL=http://127.0.0.1:5173 -CONFIRM_EMAIL_PATH=/auth/confirm-email -CONFIRM_TOKEN_TTL_SECONDS=86400 -CONFIRM_TOKEN_RESEND_SECONDS=60 - -BUFFER_API=1aF1d6NQ3qTsjtfA_mdNwqfhK6myTqXK0vwSySiPRrK -BUFFER_API_URL=https://api.buffer.com -BUFFER_CHANNEL_ID=6a73328399afb4434907444f -CLIENT_ID=6a7331dc2d90e07071891bfc - -# OpenAI API Key -OPENAI_API_KEY=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 -OPENAI_BASE_URL=https://api.openai.com/v1 -OPENAI_MAX_OUTPUT_TOKENS=32768 -OPENAI_MODEL=gpt-5.4-mini -OPENAI_TIMEOUT=60 -OPENAI_MAX_RETRIES=3 -OPENAI_CONNECT_RETRIES=3 -OPENAI_TEMPERATURE=0.3 - -REDIS_URL=redis://redis:6379/0 -TASKIQ_QUEUE_NAME=inbox -TASKIQ_MAX_RETRIES=3 -TASKIQ_RETRY_DELAY=5 -TASKIQ_MAX_DELAY=120 -TASKIQ_DLQ_STREAM=taskiq:dlq -TASKIQ_IDLE_TIMEOUT_MS=600000 -APP_VERSION=dev - - -# Google Sheet -SPREADSHEET_NAME=Product Hiring -SPREADSHEET_ID=1yjRueJjA1NbW8rS-KsSCJxxnkqh6cPiJjwcmXbTLusk -SPREADSHEET_URL=https://docs.google.com/spreadsheets/d/1yjRueJjA1NbW8rS-KsSCJxxnkqh6cPiJjwcmXbTLusk/edit - -# Google Cloud project -GOOGLE_CLOUD_PROJECT=hrms-ats-portal -GOOGLE_ACCOUNT=ahmed.mujtaba@utopiabrands.com - -# OAuth client (Desktop) -GOOGLE_CLIENT_ID=679334897177-ufal3rogbg8cgm3qcren6pv20phqd7nl.apps.googleusercontent.com -GOOGLE_CLIENT_SECRET=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 -GOOGLE_OAUTH_CLIENT_ID_FILE=credentials/client_secret.json - -# Application Default Credentials (used by google-auth) -GOOGLE_APPLICATION_CREDENTIALS=credentials/application_default_credentials.json -GOOGLE_REFRESH_TOKEN=1//038IfgCu3D42fCgYIARAAGAMSNwF-L9IrYAZ_DJUqwC9ETwLtH23D46j61gWMwFQjRWPklFZIiLmv7Q3-TOgcNxTrjO30jgkeYOo -GOOGLE_CREDENTIALS_TYPE=authorized_user - - - -BACKEND_URL=http://backend-api:8000 -DB_AUTOGENERATE=false - -# --------------------------------------------------------------------------- - -DB_AUTO_MIGRATE=false - -# Compose host ports (docker compose --env-file ./backend/.env …). -FRONTEND_PORT=5173 -BACKEND_PORT=8000 -ATS_PORT=8100 -REDIS_PORT=6379 -POSTGRES_PORT=5433 - -UVICORN_WORKERS=2 - -# Empty = same-origin; frontend nginx proxies API paths to backend-api. -VITE_API_BASE= From fb27ec3bb3b6f2b6d997f7768558e421bb392115 Mon Sep 17 00:00:00 2001 From: "ahmed.mujtaba" Date: Mon, 24 Aug 2026 21:25:09 +0500 Subject: [PATCH 3/6] . --- .env | 5 --- backend/.env | 105 --------------------------------------------------- 2 files changed, 110 deletions(-) delete mode 100644 .env delete mode 100644 backend/.env diff --git a/.env b/.env deleted file mode 100644 index 94335dc..0000000 --- a/.env +++ /dev/null @@ -1,5 +0,0 @@ -# Compose pointer only — NO secrets here. -# Makes `docker compose up -d --build` read ${FRONTEND_PORT}, ${BACKEND_PORT}, … -# from backend/.env without typing --env-file every time. -# All credentials and app config live in backend/.env. -COMPOSE_ENV_FILES=./backend/.env diff --git a/backend/.env b/backend/.env deleted file mode 100644 index 2cca649..0000000 --- a/backend/.env +++ /dev/null @@ -1,105 +0,0 @@ - -# true → RDS over SSL (asyncpg). false → local Postgres over asyncpg (no SSH). -PROD_ENV=false - -DB_USERNAME=postgres -DB_PASSWORD=ambaig123 -DB_HOST=localhost -DB_PORT=5432 -DB_NAME=dev_hrms -# Blank: require when PROD_ENV=true, off when local. Override only if needed. -DB_SSLMODE= -# DB_USERNAME=utopiaaiadmin -# DB_PASSWORD=cOIYBbjeRpb5rZigZBYX -# DB_HOST=utopia-ai-hr-ats-portal-db.co658idowpql.us-east-2.rds.amazonaws.com -# DB_PORT=5432 -# DB_NAME=dev_hrms -# DB_SSLMODE=require - -EMAIL_URL=http://172.16.204.191:5000 -EMAIL_API_TOKEN=vn1a9sx6tI3L5LVXgblOiVpxn3gAiJXTVYvO5GICUNo -EMAIL_SYNC_FOLDER=inbox -EMAIL_SYNC_SINCE= -EMAIL_SYNC_CRON=* * * * * -JWT_SECRET_KEY=8B6lep0TuSrGp__2SFDCqKGyEluuUWV7SxvobhG5ECQYvN4o4P0OakRW0VWmiflZ6hgNK7RGdOVmi4H8LnSLwA -JWT_ALGORITHM=HS256 -JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 -JWT_REFRESH_TOKEN_EXPIRE_DAYS=7 - -TEAMS_MAIL_API_URL=http://ec2-13-222-174-68.compute-1.amazonaws.com:8000/mail/send -TEAMS_API_TOKEN=wt139Dg1bm0lXoYszzwCcMmkjQrkuP -RESET_CODE_TTL_SECONDS=60 -RESET_CODE_RESEND_SECONDS=30 -RESET_CODE_MAX_ATTEMPTS=5 -JWT_RESET_TOKEN_EXPIRE_MINUTES=10 - -# Vite / email links. Docker SPA publishes on FRONTEND_PORT (5173). -FRONTEND_URL=http://127.0.0.1:5173 -CONFIRM_EMAIL_PATH=/auth/confirm-email -CONFIRM_TOKEN_TTL_SECONDS=86400 -CONFIRM_TOKEN_RESEND_SECONDS=60 - -BUFFER_API=1aF1d6NQ3qTsjtfA_mdNwqfhK6myTqXK0vwSySiPRrK -BUFFER_API_URL=https://api.buffer.com -BUFFER_CHANNEL_ID=6a73328399afb4434907444f -CLIENT_ID=6a7331dc2d90e07071891bfc - -# OpenAI API Key -OPENAI_API_KEY=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 -OPENAI_BASE_URL=https://api.openai.com/v1 -OPENAI_MAX_OUTPUT_TOKENS=32768 -OPENAI_MODEL=gpt-5.4-mini -OPENAI_TIMEOUT=60 -OPENAI_MAX_RETRIES=3 -OPENAI_CONNECT_RETRIES=3 -OPENAI_TEMPERATURE=0.3 - -REDIS_URL=redis://redis:6379/0 -TASKIQ_QUEUE_NAME=inbox -TASKIQ_MAX_RETRIES=3 -TASKIQ_RETRY_DELAY=5 -TASKIQ_MAX_DELAY=120 -TASKIQ_DLQ_STREAM=taskiq:dlq -TASKIQ_IDLE_TIMEOUT_MS=600000 -APP_VERSION=dev - - -# Google Sheet -SPREADSHEET_NAME=Product Hiring -SPREADSHEET_ID=1yjRueJjA1NbW8rS-KsSCJxxnkqh6cPiJjwcmXbTLusk -SPREADSHEET_URL=https://docs.google.com/spreadsheets/d/1yjRueJjA1NbW8rS-KsSCJxxnkqh6cPiJjwcmXbTLusk/edit - -# Google Cloud project -GOOGLE_CLOUD_PROJECT=hrms-ats-portal -GOOGLE_ACCOUNT=ahmed.mujtaba@utopiabrands.com - -# OAuth client (Desktop) -GOOGLE_CLIENT_ID=679334897177-ufal3rogbg8cgm3qcren6pv20phqd7nl.apps.googleusercontent.com -GOOGLE_CLIENT_SECRET=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 -GOOGLE_OAUTH_CLIENT_ID_FILE=credentials/client_secret.json - -# Application Default Credentials (used by google-auth) -GOOGLE_APPLICATION_CREDENTIALS=credentials/application_default_credentials.json -GOOGLE_REFRESH_TOKEN=1//038IfgCu3D42fCgYIARAAGAMSNwF-L9IrYAZ_DJUqwC9ETwLtH23D46j61gWMwFQjRWPklFZIiLmv7Q3-TOgcNxTrjO30jgkeYOo -GOOGLE_CREDENTIALS_TYPE=authorized_user - - - -BACKEND_URL=http://backend-api:8000 -DB_AUTOGENERATE=false - -# --------------------------------------------------------------------------- - -DB_AUTO_MIGRATE=false - -# Compose host ports (docker compose --env-file ./backend/.env …). -FRONTEND_PORT=5173 -BACKEND_PORT=8000 -ATS_PORT=8100 -REDIS_PORT=6379 -POSTGRES_PORT=5433 - -UVICORN_WORKERS=2 - -# Empty = same-origin; frontend nginx proxies API paths to backend-api. -VITE_API_BASE= From 0a6dd688fbefed8591f9203b8fce4b5b861b985e Mon Sep 17 00:00:00 2001 From: "ahmed.mujtaba" Date: Mon, 24 Aug 2026 21:25:23 +0500 Subject: [PATCH 4/6] Stop tracking .env files so secrets are never pushed. Co-authored-by: Cursor --- .gitignore | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 9acc410..8720553 100644 --- a/.gitignore +++ b/.gitignore @@ -34,13 +34,13 @@ __pycache__/ venv/ env/ -# Environment / secrets — app secrets only in backend/.env (never commit it). -# Root .env is a Compose pointer (COMPOSE_ENV_FILES) with no secrets; keep it. -backend/.env +# Environment / secrets — NEVER commit real .env files +.env +**/.env .env.* -!.env +**/.env.* !.env.example -!backend/.env.example +!**/.env.example !frontend/.env.development !frontend/.env.production @@ -66,4 +66,3 @@ Utopia-ai-hr-ats-portal 1.pem # Local-only Compose overrides (never deployed) docker.local.env tests/** -**/.env** \ No newline at end of file From f8685c04fedc314e1d60f66bfc489d004473e89a Mon Sep 17 00:00:00 2001 From: "ahmed.mujtaba" Date: Mon, 24 Aug 2026 21:28:16 +0500 Subject: [PATCH 5/6] Add root .env.example Compose pointer (no secrets). Co-authored-by: Cursor --- .env.example | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4e761bb --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +# Copy to `.env` at the repo root (gitignored) if you want plain +# `docker compose up -d --build` to interpolate ${FRONTEND_PORT} etc. +# from backend/.env. Secrets stay in backend/.env only — never commit .env. +COMPOSE_ENV_FILES=./backend/.env From d9992e46d10c02e7e398d75bfdf3ba6cf51210a5 Mon Sep 17 00:00:00 2001 From: "ahmed.mujtaba" Date: Tue, 25 Aug 2026 12:54:04 +0500 Subject: [PATCH 6/6] correct the error --- .gitignore | 4 +++- frontend/src/lib/charts.js | 12 +++++++++++- frontend/src/ui/Chart.jsx | 5 +++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 274ae0d..d189398 100644 --- a/.gitignore +++ b/.gitignore @@ -72,4 +72,6 @@ tests/** # Root-anchored: backend/candidate_forms/ is the forms domain package and IS tracked. /candidate_forms/ frontend/dist/** */ -docker.local.frontend/dist/** */ \ No newline at end of file +docker.local.frontend/dist/** */ +frontend/dist/index.html +frontend/dist/index.html diff --git a/frontend/src/lib/charts.js b/frontend/src/lib/charts.js index f86617a..08f73d8 100644 --- a/frontend/src/lib/charts.js +++ b/frontend/src/lib/charts.js @@ -48,7 +48,17 @@ function css(name) { return getComputedStyle(document.documentElement).getProper const dpr = window.devicePixelRatio || 1; const rect = canvas.getBoundingClientRect(); const w = rect.width || canvas.clientWidth || 600; - const h = parseInt(canvas.getAttribute('height')) || 260; + // The LOGICAL height, remembered on first setup. Reading the `height` + // attribute here instead would read back the DEVICE-pixel value written + // below (h * dpr): with dpr > 1 every redraw multiplied the canvas by dpr, + // and the ResizeObserver on the auto-height .chart-wrap fed each growth + // straight back in — canvases reached millions of px tall and the chart + // became an invisible speck at the top of a giant blank canvas. + let h = Number(canvas.dataset.baseHeight); + if (!h) { + h = parseInt(canvas.getAttribute('height')) || 260; + canvas.dataset.baseHeight = String(h); + } canvas.width = w * dpr; canvas.height = h * dpr; canvas.style.height = h + 'px'; const ctx = canvas.getContext('2d'); diff --git a/frontend/src/ui/Chart.jsx b/frontend/src/ui/Chart.jsx index 2d6d55f..e96f608 100644 --- a/frontend/src/ui/Chart.jsx +++ b/frontend/src/ui/Chart.jsx @@ -29,6 +29,11 @@ export default function Chart({ type, data, options, height = 260, className = ' const canvas = ref.current if (!canvas || typeof Charts[type] !== 'function') return undefined + // setup() caches the logical height on first draw (dataset.baseHeight) so a + // redraw never reads back the device-pixel height it wrote. Clear it here so + // a changed `height` prop is picked up rather than the stale cached value. + delete canvas.dataset.baseHeight + const draw = () => { if (canvas.isConnected && canvas.getBoundingClientRect().width > 0) { Charts[type](canvas, data, options)