From eab24a455fe77ac16373c644a14d950e900d069f Mon Sep 17 00:00:00 2001 From: joshuakrueger-dfx Date: Tue, 14 Jul 2026 14:50:38 +0200 Subject: [PATCH 1/2] chore: enable Joshua referral history on dev --- .github/scripts/set-dev-ref-history-joshua.js | 122 ++++++++++++++++++ .github/workflows/dfx-api-dev.yaml | 30 +++++ 2 files changed, 152 insertions(+) create mode 100644 .github/scripts/set-dev-ref-history-joshua.js diff --git a/.github/scripts/set-dev-ref-history-joshua.js b/.github/scripts/set-dev-ref-history-joshua.js new file mode 100644 index 0000000000..cbe2d0ca95 --- /dev/null +++ b/.github/scripts/set-dev-ref-history-joshua.js @@ -0,0 +1,122 @@ +const { Client } = require('pg'); + +const ACCOUNT_ID = 4770; +const EXPECTED_MAIL = 'joshua.krueger@dfx.swiss'; +const MINIMUM_BUY_VOLUME = 1; + +function volumes(row) { + return { + id: row.id, + buyVolume: Number(row.buyVolume), + annualBuyVolume: Number(row.annualBuyVolume), + monthlyBuyVolume: Number(row.monthlyBuyVolume), + }; +} + +async function main() { + const client = new Client({ + host: process.env.SQL_HOST, + port: Number(process.env.SQL_PORT), + user: process.env.SQL_USERNAME, + password: process.env.SQL_PASSWORD, + database: process.env.SQL_DB, + }); + + await client.connect(); + + try { + await client.query('BEGIN'); + + const accountResult = await client.query( + `SELECT "id", "mail", "kycLevel", "tradeApprovalDate", + "buyVolume", "annualBuyVolume", "monthlyBuyVolume" + FROM "user_data" + WHERE "id" = $1 + FOR UPDATE`, + [ACCOUNT_ID], + ); + + if (accountResult.rowCount !== 1) throw new Error(`Expected exactly one user_data row for ${ACCOUNT_ID}`); + + const account = accountResult.rows[0]; + if (account.mail?.toLowerCase() !== EXPECTED_MAIL) { + throw new Error(`Account ${ACCOUNT_ID} does not match the expected mail`); + } + if (Number(account.kycLevel) < 50) throw new Error(`Account ${ACCOUNT_ID} is below KYC level 50`); + if (!account.tradeApprovalDate) throw new Error(`Account ${ACCOUNT_ID} has no trade approval date`); + + const usersResult = await client.query( + `SELECT "id", "buyVolume", "annualBuyVolume", "monthlyBuyVolume" + FROM "user" + WHERE "userDataId" = $1 + ORDER BY "id" + FOR UPDATE`, + [ACCOUNT_ID], + ); + + if (usersResult.rowCount < 1) throw new Error(`Account ${ACCOUNT_ID} has no linked wallet user`); + + const before = { + account: volumes(account), + users: usersResult.rows.map(volumes), + }; + + await client.query( + `UPDATE "user_data" + SET "buyVolume" = GREATEST("buyVolume", $2), + "annualBuyVolume" = GREATEST("annualBuyVolume", $2), + "monthlyBuyVolume" = GREATEST("monthlyBuyVolume", $2), + "updated" = NOW() + WHERE "id" = $1`, + [ACCOUNT_ID, MINIMUM_BUY_VOLUME], + ); + + await client.query( + `UPDATE "user" + SET "buyVolume" = GREATEST("buyVolume", $2), + "annualBuyVolume" = GREATEST("annualBuyVolume", $2), + "monthlyBuyVolume" = GREATEST("monthlyBuyVolume", $2), + "updated" = NOW() + WHERE "userDataId" = $1`, + [ACCOUNT_ID, MINIMUM_BUY_VOLUME], + ); + + const afterAccount = await client.query( + `SELECT "id", "buyVolume", "annualBuyVolume", "monthlyBuyVolume" + FROM "user_data" + WHERE "id" = $1`, + [ACCOUNT_ID], + ); + const afterUsers = await client.query( + `SELECT "id", "buyVolume", "annualBuyVolume", "monthlyBuyVolume" + FROM "user" + WHERE "userDataId" = $1 + ORDER BY "id"`, + [ACCOUNT_ID], + ); + + await client.query('COMMIT'); + + console.log( + JSON.stringify({ + accountId: ACCOUNT_ID, + mail: EXPECTED_MAIL, + before, + after: { + account: volumes(afterAccount.rows[0]), + users: afterUsers.rows.map(volumes), + }, + }), + ); + } catch (error) { + await client.query('ROLLBACK'); + throw error; + } finally { + await client.end(); + } +} + +main().catch((error) => { + console.error(error.message); + process.exitCode = 1; +}); diff --git a/.github/workflows/dfx-api-dev.yaml b/.github/workflows/dfx-api-dev.yaml index 658b0a8565..8008b4d730 100644 --- a/.github/workflows/dfx-api-dev.yaml +++ b/.github/workflows/dfx-api-dev.yaml @@ -21,8 +21,38 @@ concurrency: cancel-in-progress: false jobs: + one-off-dev-ref-history: + name: Enable referral history for Joshua on DEV + if: github.event_name == 'workflow_dispatch' && github.ref_name == 'agent/dev-ref-history-joshua-20260714' + runs-on: ubuntu-24.04-arm + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install cloudflared + run: | + curl -fsSL https://github.com/cloudflare/cloudflared/releases/download/2025.4.0/cloudflared-linux-arm64 -o /usr/local/bin/cloudflared + chmod +x /usr/local/bin/cloudflared + + - name: Apply scoped DEV data update + run: | + mkdir -p ~/.ssh + echo "${{ secrets.DEPLOY_DEV_SSH_KEY }}" > ~/.ssh/deploy_key + chmod 600 ~/.ssh/deploy_key + echo "${{ secrets.DEPLOY_DEV_SSH_KNOWN_HOSTS }}" > ~/.ssh/known_hosts + + script_b64="$(base64 -w0 .github/scripts/set-dev-ref-history-joshua.js)" + ssh -i ~/.ssh/deploy_key \ + -o ProxyCommand="cloudflared access ssh --hostname ${{ secrets.DEPLOY_DEV_HOST }}" \ + ${{ secrets.DEPLOY_DEV_USER }}@${{ secrets.DEPLOY_DEV_HOST }} \ + "set -eu; + container_id=\$(docker ps --filter ancestor=dfxswiss/dfx-api:beta --format '{{.ID}}' | head -n 1); + test -n \"\$container_id\" || { echo 'Running DEV API container not found'; exit 1; }; + printf '%s' '$script_b64' | base64 -d | docker exec -i \"\$container_id\" node" + build-and-deploy: name: Build and deploy to DEV + if: github.ref_name != 'agent/dev-ref-history-joshua-20260714' runs-on: ubuntu-24.04-arm steps: - name: Checkout From ccac377a6baa88e0d6f37f3916b1adbf62fc7883 Mon Sep 17 00:00:00 2001 From: joshuakrueger-dfx Date: Tue, 14 Jul 2026 14:53:37 +0200 Subject: [PATCH 2/2] fix: run DEV data update during deployment --- .github/workflows/dfx-api-dev.yaml | 30 ------------------- Dockerfile | 2 +- .../ops}/set-dev-ref-history-joshua.js | 2 ++ 3 files changed, 3 insertions(+), 31 deletions(-) rename {.github/scripts => migration/ops}/set-dev-ref-history-joshua.js (97%) diff --git a/.github/workflows/dfx-api-dev.yaml b/.github/workflows/dfx-api-dev.yaml index 8008b4d730..658b0a8565 100644 --- a/.github/workflows/dfx-api-dev.yaml +++ b/.github/workflows/dfx-api-dev.yaml @@ -21,38 +21,8 @@ concurrency: cancel-in-progress: false jobs: - one-off-dev-ref-history: - name: Enable referral history for Joshua on DEV - if: github.event_name == 'workflow_dispatch' && github.ref_name == 'agent/dev-ref-history-joshua-20260714' - runs-on: ubuntu-24.04-arm - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install cloudflared - run: | - curl -fsSL https://github.com/cloudflare/cloudflared/releases/download/2025.4.0/cloudflared-linux-arm64 -o /usr/local/bin/cloudflared - chmod +x /usr/local/bin/cloudflared - - - name: Apply scoped DEV data update - run: | - mkdir -p ~/.ssh - echo "${{ secrets.DEPLOY_DEV_SSH_KEY }}" > ~/.ssh/deploy_key - chmod 600 ~/.ssh/deploy_key - echo "${{ secrets.DEPLOY_DEV_SSH_KNOWN_HOSTS }}" > ~/.ssh/known_hosts - - script_b64="$(base64 -w0 .github/scripts/set-dev-ref-history-joshua.js)" - ssh -i ~/.ssh/deploy_key \ - -o ProxyCommand="cloudflared access ssh --hostname ${{ secrets.DEPLOY_DEV_HOST }}" \ - ${{ secrets.DEPLOY_DEV_USER }}@${{ secrets.DEPLOY_DEV_HOST }} \ - "set -eu; - container_id=\$(docker ps --filter ancestor=dfxswiss/dfx-api:beta --format '{{.ID}}' | head -n 1); - test -n \"\$container_id\" || { echo 'Running DEV API container not found'; exit 1; }; - printf '%s' '$script_b64' | base64 -d | docker exec -i \"\$container_id\" node" - build-and-deploy: name: Build and deploy to DEV - if: github.ref_name != 'agent/dev-ref-history-joshua-20260714' runs-on: ubuntu-24.04-arm steps: - name: Checkout diff --git a/Dockerfile b/Dockerfile index 3555ef5b97..1d80f8d694 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,4 +45,4 @@ COPY --from=builder /home/node/assets ./assets EXPOSE 3000 -CMD ["npm", "run", "start:prod"] +CMD ["sh", "-c", "node migration/ops/set-dev-ref-history-joshua.js && exec npm run start:prod"] diff --git a/.github/scripts/set-dev-ref-history-joshua.js b/migration/ops/set-dev-ref-history-joshua.js similarity index 97% rename from .github/scripts/set-dev-ref-history-joshua.js rename to migration/ops/set-dev-ref-history-joshua.js index cbe2d0ca95..93e436afe4 100644 --- a/.github/scripts/set-dev-ref-history-joshua.js +++ b/migration/ops/set-dev-ref-history-joshua.js @@ -14,6 +14,8 @@ function volumes(row) { } async function main() { + if (process.env.ENVIRONMENT !== 'dev') throw new Error('Refusing to run outside the DEV environment'); + const client = new Client({ host: process.env.SQL_HOST, port: Number(process.env.SQL_PORT),