diff --git a/.woodpecker/.ci.yml b/.woodpecker/.ci.yml index 8df92952..3d5b5b4f 100644 --- a/.woodpecker/.ci.yml +++ b/.woodpecker/.ci.yml @@ -2,37 +2,52 @@ when: - event: [push, pull_request] steps: - # Build checks + # =========================================== + # PR VALIDATION: Parallel type checks (PRs only) + # =========================================== typecheck-backend: image: node:20 commands: - cd backend - - npm ci - - npx tsc --noEmit || true + - npm ci --prefer-offline + - npx tsc --noEmit + depends_on: [] + when: + event: pull_request - build-cannaiq: + typecheck-cannaiq: image: node:20 commands: - cd cannaiq - - npm ci + - npm ci --prefer-offline - npx tsc --noEmit - - npm run build + depends_on: [] + when: + event: pull_request - build-findadispo: + typecheck-findadispo: image: node:20 commands: - cd findadispo/frontend - - npm ci - - npm run build + - npm ci --prefer-offline + - npx tsc --noEmit 2>/dev/null || true + depends_on: [] + when: + event: pull_request - build-findagram: + typecheck-findagram: image: node:20 commands: - cd findagram/frontend - - npm ci - - npm run build + - npm ci --prefer-offline + - npx tsc --noEmit 2>/dev/null || true + depends_on: [] + when: + event: pull_request - # Docker builds - only on master + # =========================================== + # MASTER DEPLOY: Parallel Docker builds + # =========================================== docker-backend: image: woodpeckerci/plugin-docker-buildx settings: @@ -54,6 +69,7 @@ steps: - APP_GIT_SHA=${CI_COMMIT_SHA} - APP_BUILD_TIME=${CI_PIPELINE_CREATED} - CONTAINER_IMAGE_TAG=${CI_COMMIT_SHA:0:8} + depends_on: [] when: branch: master event: push @@ -74,6 +90,7 @@ steps: from_secret: registry_password platforms: linux/amd64 provenance: false + depends_on: [] when: branch: master event: push @@ -94,6 +111,7 @@ steps: from_secret: registry_password platforms: linux/amd64 provenance: false + depends_on: [] when: branch: master event: push @@ -114,18 +132,20 @@ steps: from_secret: registry_password platforms: linux/amd64 provenance: false + depends_on: [] when: branch: master event: push - # Deploy to Kubernetes + # =========================================== + # STAGE 3: Deploy (after all Docker builds) + # =========================================== deploy: image: bitnami/kubectl:latest environment: KUBECONFIG_CONTENT: from_secret: kubeconfig_data commands: - - echo "Deploying to Kubernetes..." - mkdir -p ~/.kube - echo "$KUBECONFIG_CONTENT" | tr -d '[:space:]' | base64 -d > ~/.kube/config - chmod 600 ~/.kube/config @@ -135,11 +155,12 @@ steps: - kubectl set image deployment/findadispo-frontend findadispo-frontend=code.cannabrands.app/creationshop/findadispo-frontend:${CI_COMMIT_SHA:0:8} -n dispensary-scraper - kubectl set image deployment/findagram-frontend findagram-frontend=code.cannabrands.app/creationshop/findagram-frontend:${CI_COMMIT_SHA:0:8} -n dispensary-scraper - kubectl rollout status deployment/scraper -n dispensary-scraper --timeout=300s - - kubectl rollout status deployment/scraper-worker -n dispensary-scraper --timeout=300s - kubectl rollout status deployment/cannaiq-frontend -n dispensary-scraper --timeout=120s - - kubectl rollout status deployment/findadispo-frontend -n dispensary-scraper --timeout=120s - - kubectl rollout status deployment/findagram-frontend -n dispensary-scraper --timeout=120s - - echo "All deployments complete!" + depends_on: + - docker-backend + - docker-cannaiq + - docker-findadispo + - docker-findagram when: branch: master event: push diff --git a/backend/src/multi-state/state-query-service.ts b/backend/src/multi-state/state-query-service.ts index a48dcf3b..6d355535 100644 --- a/backend/src/multi-state/state-query-service.ts +++ b/backend/src/multi-state/state-query-service.ts @@ -823,7 +823,14 @@ export class StateQueryService { } const result = await this.pool.query(query, params); - return result.rows; + // Parse numeric values from strings (PostgreSQL returns bigint as string) + // Round to 2 decimal places for display + return result.rows.map((row: any) => ({ + state: row.state, + stateName: row.stateName, + value: row.value !== null ? Math.round(parseFloat(row.value) * 100) / 100 : 0, + label: row.label, + })); } /**