# 0.3.12

First release of the Welcome Package automation: a per-player onboarding flow that runs on the on-host management service, detects new players from the game Postgres database, inserts configured backpack items directly into the game database, and can send a separate welcome whisper through the existing MQ chat path. Includes a Visual + JSON editor in the desktop app, a SQLite-backed package ledger, and several follow-up fixes from internal review.

This is the first tagged release since v0.3.9. All 0.3.10 / 0.3.11 / 0.3.12 work ships together.

## Reinstall step

After updating the desktop app, open each server's Management Service card and click **Install / Update** so the refreshed on-host `dune-server-service` binary is pushed. The Welcome Package tab will not function until the host service is at v0.3.12.

## Added

- **Welcome Package tab** in the management view, with separate toggles for the welcome message (whisper) and the item package.
- **Package contents editor** for item rows. Each row inserts the configured `itemName` (Unreal FName / row name) and `quantity` into the player's backpack; durability defaults to `1.0`.
- **Optional raw JSON mode** on the package contents editor. Toggle the checkbox to swap the visual editor for a textarea you can paste / hand-edit, so a long package can be saved and restored without re-clicking every row. Switching back to the visual editor parses and validates first; an invalid textarea keeps you in JSON mode with an inline error so a typo cannot silently drop items.
- **Welcome whisper** support: configurable source player, message body, and a separate "Send test whisper" button that works even when the automated welcome message is disabled. Whispers publish on `chat.whispers` using the live-tested player-sourced shape.
- **Single transaction item grants**: all configured item rows are inserted into the player's backpack in one Postgres transaction. The package ledger is marked granted only after that transaction commits.
- **Full water-container grants**: known fillable containers such as `Literjon` and `Decajon` include embedded fillable stats for a full water container.
- **Recent welcome grants** table in the Welcome Package tab, backed by the daemon ledger. Failed rows show the error and a **Retry** button that clears the failed record so the next scan re-attempts the grant; granted rows are never cleared, so a retry can't duplicate a package.
- **Manual welcome scan** button in the Automated Tasks tab so a test pass does not have to wait for the next poll interval.
- **`scripts/rebuild-release.cmd`** helper for local release rebuilds: workspace tests, frontend build, musl service cross-compile, bundled binary copy, and Tauri NSIS in one shot.

## Fixed

- `welcome_package_items_json` (legacy alias) no longer clobbers `welcome_package_actions_json` when both are sent in the same `PATCH /api/config` request. The legacy field is only applied when the canonical field is absent.
- `welcome_package_version` mismatches now return `400 "currently fixed to v1 and cannot be changed"` instead of accepting the value and silently dropping it. Echoing the same `v1` value remains a no-op so the existing UI save flow still works.
- Removed the old MQ item-grant path, planned item ids, water-refill actions, and empty-backpack wait. Item packages now wait only for the player's backpack inventory row to exist.
- Dropped the inline 30-second `wait_for_item_quantity` poll inside `process_grant_item`. The direct DB transaction is the confirmation point, and missing backpacks do not create ledger rows until a later scan finds the backpack.
- Welcome automation no longer waits for the game DB `online_status` flag before running. Item grants are DB-backed, and welcome whispers are attempted from the configured chat identity without an online-grace gate.

## Changed

- Renamed the welcome automation toggles to "new players" in the UI so the wording matches the worker's actual scope.
- Split welcome message automation from welcome package grants so each can be enabled independently. Sending a manual test welcome whisper no longer overwrites unsaved tab state.
- The welcome whisper now runs on its own worker at a 60-second cadence instead of riding the 2-second package scan. A cheap local check skips accounts whose whisper is already confirmed before any Postgres chat lookup, so the fast item-grant loop no longer pays for a per-account chat query every tick.

## Notes

- Welcome Package timing on a fresh player: the service scans every 2 seconds while welcome automation is enabled. Once the service sees the account and its backpack inventory row exists, item insertion can happen on that scan.
- The package ledger is keyed by `(player_id, package_version, account_id)`. Recreating a character under the same FLS id creates a new `account_id`, so the welcome package can be granted again to the new character. Editing the item list while keeping the same `welcome_package_version` will not re-grant rows already marked granted for that account. The `welcome_package_version` field is currently pinned to `v1` server-side; "re-grant everyone" via a version bump is not yet wired up.
- This experiment only grants backpack items. Progression unlocks should stay out of direct DB writes until the game-owned tables and side effects are fully mapped.
