Files
worldmonitor/docs/Docs_To_Review/RELEASE_PACKAGING.md
Elie Habib 07d0803014 Add WTO trade policy intelligence service with tariffs, flows, and barriers (#364)
* feat: add WTO trade policy service with 4 RPC endpoints and TradePolicyPanel

Adds a new `trade` RPC domain backed by the WTO API (apiportal.wto.org) for
trade policy intelligence: quantitative restrictions, tariff timeseries,
bilateral trade flows, and SPS/TBT barrier notifications.

New files: 6 protos, generated server/client, 4 server handlers + shared WTO
fetch utility, client service with circuit breakers, TradePolicyPanel (4 tabs),
and full API key infrastructure (Rust keychain, sidecar, runtime config).

Panel registered for FULL and FINANCE variants with data loader integration,
command palette entry, status panel tracking, data freshness monitoring, and
i18n across all 17 locale files.

https://claude.ai/code/session_01HZXyoQp6xK3TX8obDzv6Ye

* chore: update package-lock.json

https://claude.ai/code/session_01HZXyoQp6xK3TX8obDzv6Ye

* fix: move tab click listener to constructor to prevent leak

The delegated click handler was added inside render(), which runs
on every data update (4× per load cycle). Since the listener targets
this.content (a persistent container), each call stacked a duplicate
handler. Moving it to the constructor binds it exactly once.

https://claude.ai/code/session_01HZXyoQp6xK3TX8obDzv6Ye

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-25 10:50:12 +00:00

6.5 KiB

Desktop Release Packaging Guide (Local, Reproducible)

This guide provides reproducible local packaging steps for both desktop variants:

  • fullWorld Monitor
  • techTech Monitor

Variant identity is controlled by Tauri config:

  • full: src-tauri/tauri.conf.json
  • tech: src-tauri/tauri.tech.conf.json

Prerequisites

  • Node.js + npm
  • Rust toolchain
  • OS-native Tauri build prerequisites:
    • macOS: Xcode command-line tools
    • Windows: Visual Studio Build Tools + NSIS + WiX

Install dependencies (this also installs the pinned Tauri CLI used by desktop scripts):

npm ci

All desktop scripts call the local tauri binary from node_modules/.bin; no runtime npx package download is required after npm ci. If the local CLI is missing, scripts/desktop-package.mjs now fails fast with an explicit npm ci remediation message.

Network preflight and remediation

Before running desktop packaging in CI or managed networks, verify connectivity and proxy config:

npm ping
curl -I https://index.crates.io/
env | grep -E '^(HTTP_PROXY|HTTPS_PROXY|NO_PROXY)='

If these fail, use one of the supported remediations:

  • Internal npm mirror/proxy.
  • Internal Cargo sparse index/registry mirror.
  • Pre-vendored Rust crates (src-tauri/vendor/) + Cargo offline mode.
  • CI artifact/caching strategy that restores required package inputs before build.

See docs/TAURI_VALIDATION_REPORT.md for failure classification labels and troubleshooting flow.

Packaging commands

To view script usage/help:

npm run desktop:package -- --help

macOS (.app + .dmg)

npm run desktop:package:macos:full
npm run desktop:package:macos:tech
# or generic runner
npm run desktop:package -- --os macos --variant full

Windows (.exe + .msi)

npm run desktop:package:windows:full
npm run desktop:package:windows:tech
# or generic runner
npm run desktop:package -- --os windows --variant tech

Bundler targets are pinned in both Tauri configs and enforced by packaging scripts:

  • macOS: app,dmg
  • Windows: nsis,msi

Rust dependency modes (online vs restricted network)

From src-tauri/, the project supports two packaging paths:

1) Standard online build (default)

Use normal Cargo behavior (crates.io):

cd src-tauri
cargo generate-lockfile
cargo tauri build --config tauri.conf.json

2) Restricted-network build (pre-vendored or internal mirror)

An optional vendored source is defined in src-tauri/.cargo/config.toml. To use it, first prepare vendored crates on a machine that has registry access:

# from repository root
cargo vendor --manifest-path src-tauri/Cargo.toml src-tauri/vendor

Then enable offline mode using either method:

  • One-off CLI override (no file changes):
cd src-tauri
cargo generate-lockfile --offline --config 'source.crates-io.replace-with="vendored-sources"'
cargo tauri build --offline --config 'source.crates-io.replace-with="vendored-sources"' --config tauri.conf.json
  • Local override file (recommended for CI/repeatable offline jobs):
cp src-tauri/.cargo/config.local.toml.example src-tauri/.cargo/config.local.toml
cd src-tauri
cargo generate-lockfile --offline
cargo tauri build --offline --config tauri.conf.json

For CI or internal mirrors, publish src-tauri/vendor/ as an artifact and restore it before the restricted-network build. If your organization uses an internal crates mirror instead of vendoring, point source.crates-io.replace-with to that mirror in CI-specific Cargo config and run the same build commands.

Optional signing/notarization hooks

Unsigned packaging works by default.

If signing credentials are present in environment variables, Tauri will sign/notarize automatically during the same packaging commands.

macOS Apple Developer signing + notarization

Set before packaging (Developer ID signature):

export TAURI_BUNDLE_MACOS_SIGNING_IDENTITY="Developer ID Application: Your Company (TEAMID)"
export TAURI_BUNDLE_MACOS_PROVIDER_SHORT_NAME="TEAMID"
# optional alternate key accepted by Tauri tooling:
export APPLE_SIGNING_IDENTITY="Developer ID Application: Your Company (TEAMID)"

For notarization, choose one auth method:

# Apple ID + app-specific password
export APPLE_ID="you@example.com"
export APPLE_PASSWORD="app-specific-password"
export APPLE_TEAM_ID="TEAMID"

# OR App Store Connect API key
export APPLE_API_KEY="ABC123DEFG"
export APPLE_API_ISSUER="00000000-0000-0000-0000-000000000000"
export APPLE_API_KEY_PATH="$HOME/.keys/AuthKey_ABC123DEFG.p8"

Then run either standard or explicit sign script aliases:

npm run desktop:package:macos:full
# or
npm run desktop:package:macos:full:sign

Windows Authenticode signing

Set before packaging (PowerShell):

$env:TAURI_BUNDLE_WINDOWS_CERTIFICATE_THUMBPRINT="<CERT_THUMBPRINT>"
$env:TAURI_BUNDLE_WINDOWS_TIMESTAMP_URL="https://timestamp.digicert.com"
# optional: if using cert file + password instead of cert store
$env:TAURI_BUNDLE_WINDOWS_CERTIFICATE="C:\path\to\codesign.pfx"
$env:TAURI_BUNDLE_WINDOWS_CERTIFICATE_PASSWORD="<PFX_PASSWORD>"

Then run either standard or explicit sign script aliases:

npm run desktop:package:windows:full
# or
npm run desktop:package:windows:full:sign

Variant-aware outputs (names/icons)

  • Full variant: World Monitor / world-monitor
  • Tech variant: Tech Monitor / tech-monitor

Distinct names are configured in Tauri:

  • src-tauri/tauri.conf.jsonWorld Monitor / world-monitor
  • src-tauri/tauri.tech.conf.jsonTech Monitor / tech-monitor

If you want variant-specific icons, set bundle.icon separately in each config and point each variant to dedicated icon assets.

Output locations

Artifacts are produced under:

src-tauri/target/release/bundle/

Common subfolders:

  • app/ → macOS .app
  • dmg/ → macOS .dmg
  • nsis/ → Windows .exe installer
  • msi/ → Windows .msi installer

Release checklist (clean machine)

  1. Build required OS + variant package(s).
  2. Move artifacts to a clean machine (or fresh VM).
  3. Install/launch:
    • macOS: mount .dmg, drag app to Applications, launch.
    • Windows: run .exe or .msi, launch from Start menu.
  4. Validate startup:
    • App window opens without crash.
    • Map view renders.
    • Initial data loading path does not fatal-error.
  5. Validate variant identity:
    • Window title and product name match expected variant.
  6. If signing was enabled:
    • Verify code-signing metadata in OS dialogs/properties.
    • Verify notarization/Gatekeeper acceptance on macOS.