From 902e3bb57c4283c9006cf874b24e692515e1be79 Mon Sep 17 00:00:00 2001 From: zaragoza444 Date: Sun, 28 Jun 2026 20:03:09 -0700 Subject: [PATCH] fix: GL lookup for Office 24 journal seed and add production activation Resolve Fineract account IDs by GL code instead of parsing codes as IDs. Add activate-omnl-production.sh and push-portal-env-to-lxc.sh for full deploy. Co-authored-by: Cursor --- .../deployment/activate-omnl-production.sh | 64 +++++++++++++++++++ scripts/deployment/push-portal-env-to-lxc.sh | 50 +++++++++++++++ .../seed-office-24-opening-journal.mjs | 37 +++++++---- 3 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 scripts/deployment/activate-omnl-production.sh create mode 100644 scripts/deployment/push-portal-env-to-lxc.sh diff --git a/scripts/deployment/activate-omnl-production.sh b/scripts/deployment/activate-omnl-production.sh new file mode 100644 index 0000000..dd674f1 --- /dev/null +++ b/scripts/deployment/activate-omnl-production.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Full OMNL production activation: deploy stack, nginx domains, LXCs, optional opening journal. +set -euo pipefail + +REPO_DIR="${OMNL_BANK_ROOT:-$HOME/smom-dbis-138}" +ENV_FILE="${OMNL_BANK_ENV:-$REPO_DIR/.env}" +SEED_JOURNAL="${SEED_OFFICE24_JOURNAL:-1}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=lib/omnl-pve-ssh.sh +source "${SCRIPT_DIR}/lib/omnl-pve-ssh.sh" + +log() { echo "[$(date -Iseconds)] $*"; } + +cd "$REPO_DIR" +git pull --ff-only origin main + +log "=== 1/5 Deploy OMNL bank stack on dev ===" +bash scripts/deployment/deploy-omnl-bank-production.sh + +log "=== 2/5 Install nginx domain routing (online + central bank + trade) ===" +bash scripts/deployment/deploy-omnl-domains.sh + +log "=== 3/5 Sync banking portal LXCs (5825-5828) ===" +bash scripts/deployment/sync-ali-omnl-banking-portal-lxcs.sh --apply + +log "=== 4/5 Push Fineract/API env to each LXC ===" +if [[ -f "$ENV_FILE" ]]; then + for CTID in 5825 5826 5827 5828; do + bash scripts/deployment/push-portal-env-to-lxc.sh "$CTID" || log "WARN: env push failed for CT $CTID" + omnl_pve_ssh "pct exec ${CTID} -- bash ${OMNL_PORTAL_ROOT:-/srv/ali-portal}/scripts/deployment/start-omnl-banking-portal.sh" 2>/dev/null || true + done +else + log "WARN: no $ENV_FILE — skip LXC Fineract env" +fi + +log "=== 5/5 Office 24 opening journal (activate live ledgers) ===" +if [[ "$SEED_JOURNAL" == "1" ]] && [[ -f "$ENV_FILE" ]]; then + set -a + # shellcheck disable=SC1090 + source "$ENV_FILE" + set +a + if [[ -n "${OFFICE24_OPENING_M1_USD:-}" ]]; then + node scripts/deployment/seed-office-24-opening-journal.mjs + bash scripts/deployment/deploy-omnl-bank-production.sh + else + log "OFFICE24_OPENING_M1_USD not set — ledger stays connected-but-empty (fineractLive=false)" + log "Set OFFICE24_OPENING_M1_USD in .env and re-run: bash scripts/deployment/activate-omnl-production.sh" + fi +else + log "Journal seed skipped (SEED_OFFICE24_JOURNAL=$SEED_JOURNAL)" +fi + +log "=== Production URLs ===" +log " Central Bank: https://secure.d-bis.org/central-bank" +log " Online banking: https://online.omdnl.org/central-bank" +log " Office 24: https://office24.omdnl.org/office-24" +log " DBIS Trade: https://exchange.d-bis.org/trade" +log " Digital Swap: https://digital.omdnl.org/swap" +log "=== Health ===" +curl -sf http://127.0.0.1:3011/api/v1/settlement/health | head -c 120 || true +echo +curl -sf http://127.0.0.1:3011/api/v1/settlement/money-supply/public | head -c 300 || true +echo +log "Activation complete" diff --git a/scripts/deployment/push-portal-env-to-lxc.sh b/scripts/deployment/push-portal-env-to-lxc.sh new file mode 100644 index 0000000..3aa51ff --- /dev/null +++ b/scripts/deployment/push-portal-env-to-lxc.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# Push production Fineract/API env keys from dev .env into an LXC portal root. +set -euo pipefail + +CTID="${1:?CTID required}" +REPO_DIR="${OMNL_BANK_ROOT:-$HOME/smom-dbis-138}" +ENV_FILE="${OMNL_BANK_ENV:-$REPO_DIR/.env}" +PORTAL_ROOT="${OMNL_PORTAL_ROOT:-/srv/ali-portal}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=lib/omnl-pve-ssh.sh +source "${SCRIPT_DIR}/lib/omnl-pve-ssh.sh" + +log() { echo "[$(date -Iseconds)] $*"; } + +if [[ ! -f "$ENV_FILE" ]]; then + echo "Missing env file: $ENV_FILE" >&2 + exit 1 +fi + +FRAG="$(mktemp)" +grep -E '^(OMNL_FINERACT_|OMNL_API_KEY=|OMNL_PUBLIC_MONEY_SUPPLY=|OMNL_REQUIRE_API_KEY=|OFFICE24_OPENING_M1_USD=)' "$ENV_FILE" >"$FRAG" || true + +if [[ ! -s "$FRAG" ]]; then + log "No Fineract/API keys found in $ENV_FILE — skip CT $CTID" + rm -f "$FRAG" + exit 0 +fi + +log "Pushing portal env keys to CT $CTID..." +omnl_pve_scp "$FRAG" "${OMNL_PVE_SSH_TARGET}:/tmp/omnl-portal-env.frag" +rm -f "$FRAG" + +omnl_pve_ssh "pct exec ${CTID} -- bash -s" <> ${PORTAL_ROOT}/.env + done < /tmp/omnl-portal-env.frag + chmod 600 ${PORTAL_ROOT}/.env +fi +rm -f /tmp/omnl-portal-env.frag +EOF + +log "Env synced on CT $CTID" diff --git a/scripts/deployment/seed-office-24-opening-journal.mjs b/scripts/deployment/seed-office-24-opening-journal.mjs index cd368f3..ecbe655 100644 --- a/scripts/deployment/seed-office-24-opening-journal.mjs +++ b/scripts/deployment/seed-office-24-opening-journal.mjs @@ -3,9 +3,6 @@ * Post Office 24 opening M1 journal to Fineract: * Dr 1410 Due From Head Office * Cr 2100 M1 Central Liabilities - * - * Requires: OMNL_FINERACT_BASE_URL, OMNL_FINERACT_PASSWORD - * Amount: OFFICE24_OPENING_M1_USD (required unless --dry-run) */ import fs from 'fs'; import path from 'path'; @@ -37,30 +34,46 @@ if (!Number.isFinite(amount) || amount <= 0) { process.exit(1); } +const auth = Buffer.from(`${user}:${pass}`).toString('base64'); +const headers = { + Authorization: `Basic ${auth}`, + 'Fineract-Platform-TenantId': tenant, + 'Content-Type': 'application/json', + Accept: 'application/json', +}; + +async function glIdForCode(glCode) { + const res = await fetch(`${base}/glaccounts?limit=500`, { headers }); + if (!res.ok) throw new Error(`GL list failed (${res.status})`); + const data = await res.json(); + const list = Array.isArray(data) ? data : []; + const match = list.find((row) => String(row.glCode) === glCode); + if (!match?.id) throw new Error(`GL code ${glCode} not found in Fineract tenant ${tenant}`); + return Number(match.id); +} + +const debitGlAccountId = await glIdForCode(cfg.debitGlCode); +const creditGlAccountId = await glIdForCode(cfg.creditGlCode); + const entry = { officeId: cfg.officeId, transactionDate: new Date().toISOString().slice(0, 10), referenceNumber: cfg.referenceNumber, comments: cfg.comments, - debits: [{ glAccountId: parseInt(cfg.debitGlCode, 10), amount }], - credits: [{ glAccountId: parseInt(cfg.creditGlCode, 10), amount }], + debits: [{ glAccountId: debitGlAccountId, amount }], + credits: [{ glAccountId: creditGlAccountId, amount }], }; -console.log(JSON.stringify({ dryRun, officeId: cfg.officeId, amount, entry }, null, 2)); +console.log(JSON.stringify({ dryRun, officeId: cfg.officeId, amount, debitGlAccountId, creditGlAccountId, entry }, null, 2)); if (dryRun) { console.log('Dry run — no journal posted.'); process.exit(0); } -const auth = Buffer.from(`${user}:${pass}`).toString('base64'); const res = await fetch(`${base}/journalentries`, { method: 'POST', - headers: { - Authorization: `Basic ${auth}`, - 'Fineract-Platform-TenantId': tenant, - 'Content-Type': 'application/json', - }, + headers, body: JSON.stringify(entry), });