Files
proxmox/scripts/omnl/verify-ack-before-credit.sh
defiQUG 7ac74f432b chore: sync docs, config schemas, scripts, and meta task alignment
- Institutional / JVMTM / reserve-provenance / GRU transport + standards JSON
- Validation and verify scripts (Blockscout labels, x402, GRU preflight, P1 local path)
- Wormhole wiring in AGENTS, MCP_SETUP, MASTER_INDEX, 04-configuration README
- Meta docs, integration gaps, live verification log, architecture updates
- CI validate-config workflow updates

Operator/LAN items, submodule working trees, and public token-aggregation edge
routes remain follow-up (see TODOS_CONSOLIDATED P1).

Made-with: Cursor
2026-03-31 22:31:39 -07:00

66 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Prove ACK instant is before journal credit (regulatory ordering: ack before credit).
# Usage: verify-ack-before-credit.sh <ack.json> <journalEntryId>
# ack.json: include "timestamp" or "ack_timestamp" as full ISO-8601 (UTC recommended).
# Fineract often returns transactionDate as YYYY-MM-DD only; we treat credit as end of that UTC day
# (conservative: ACK must be strictly before 23:59:59.999Z on that date unless you extend this script).
#
# Exit: 0 pass, 1 fail ordering, 2 usage/API/parse error.
set -eo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=scripts/lib/load-project-env.sh
set +u
source "${REPO_ROOT}/scripts/lib/load-project-env.sh"
set -euo pipefail
ACK_FILE="${1:-}"
JE_ID="${2:-}"
if [[ -z "$ACK_FILE" || -z "$JE_ID" || ! -f "$ACK_FILE" ]]; then
echo "Usage: $0 <ack.json> <journalEntryId>" >&2
exit 2
fi
BASE_URL="${OMNL_FINERACT_BASE_URL:-}"
PASS="${OMNL_FINERACT_PASSWORD:-}"
USER="${OMNL_FINERACT_USER:-app.omnl}"
TENANT="${OMNL_FINERACT_TENANT:-omnl}"
if [[ -z "$BASE_URL" || -z "$PASS" ]]; then
echo "error: OMNL_FINERACT_BASE_URL and OMNL_FINERACT_PASSWORD required" >&2
exit 2
fi
ACK_TS="$(jq -r '.timestamp // .ack_timestamp // empty' "$ACK_FILE")"
[[ -z "$ACK_TS" ]] && echo "error: ack file missing timestamp / ack_timestamp" >&2 && exit 2
JE_JSON="$(curl -sS -H "Fineract-Platform-TenantId: ${TENANT}" -u "${USER}:${PASS}" "${BASE_URL}/journalentries/${JE_ID}")"
CREDIT_DATE="$(echo "$JE_JSON" | jq -r '.transactionDate // empty')"
[[ -z "$CREDIT_DATE" ]] && echo "error: journalentries/${JE_ID} missing transactionDate" >&2 && exit 2
ACK_TS="$ACK_TS" CREDIT_DATE="$CREDIT_DATE" python3 <<'PY'
import os, sys
from datetime import datetime, timezone
ack_s = os.environ["ACK_TS"].strip().replace("Z", "+00:00")
try:
ack = datetime.fromisoformat(ack_s)
except ValueError:
print("error: cannot parse ACK timestamp as ISO-8601", file=sys.stderr)
sys.exit(2)
if ack.tzinfo is None:
ack = ack.replace(tzinfo=timezone.utc)
d = os.environ["CREDIT_DATE"].strip()[:10]
try:
y, m, day = (int(d[0:4]), int(d[5:7]), int(d[8:10]))
credit_end = datetime(y, m, day, 23, 59, 59, 999000, tzinfo=timezone.utc)
except Exception:
print("error: bad transactionDate", file=sys.stderr)
sys.exit(2)
if ack < credit_end:
print(f"OK: ack {ack.isoformat()} is before credit value-date end {credit_end.isoformat()}")
sys.exit(0)
print(f"FAIL: ack {ack.isoformat()} is not before credit window end {credit_end.isoformat()}", file=sys.stderr)
sys.exit(1)
PY