Skip to content

feat(frontend): migration to configuration files - #693

Closed
bosbaber wants to merge 3923 commits into
mainfrom
stephan/wal-1205
Closed

bosbaber wants to merge 3923 commits into
mainfrom
stephan/wal-1205

Conversation

@bosbaber

@bosbaber bosbaber commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

No description provided.

semantic-release-bot and others added 30 commits May 12, 2026 15:26
This pull request updates the deployment workflow to enable and
streamline production deployments alongside sandbox deployments. The
changes consolidate environment handling, generalize secrets management,
and update documentation and logic to support both sandbox and
production environments for the deploy process and Linear release
registration.

Key changes include:

**Production Deployment Enablement and Environment Handling:**
* The workflow now supports deploying to both `sandbox` and `production`
environments, removing the previous guard that blocked production
deployments and updating the guard job to fail only on unknown
environments.
[[1]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3L78-R81)
[[2]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3L90-R92)
* Environment-specific secrets (`GCR_PROJECT`, `GSA_EMAIL`,
`GCR_WORKLOAD_IDENTITY_PROVIDER`) are now selected dynamically based on
the deployment target, allowing a flat workflow without per-environment
job duplication.
* The health check step is updated to include the production health
endpoint, enabling rollout verification for both environments.

**Linear Release Registration Improvements:**
* The Linear release registration step now works for both environments,
using environment-scoped secrets and continuous pipeline configuration.
The gating logic is updated to trigger for any environment where a PR
was created, not just sandbox.
[[1]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3L472-R485)
[[2]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3L491-R494)

**Documentation and Comments:**
* Workflow comments and documentation are updated throughout to reflect
support for both environments, clarify secret usage, and explain the
continuous pipeline approach for Linear.
[[1]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3L20-L22)
[[2]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3L32-R35)
[[3]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3L110-R114)

These changes collectively prepare the deployment workflow for
production use while maintaining clarity and safety for both
environments.
Added trivial text to the README to trigger new deploy
Normally this PR would not be a fix, but we are testing the versioning
code.

This pull request updates the deployment workflow to improve clarity and
reliability when handling no-op deployments (when the target environment
is already at the desired chart version). The main changes ensure that
all relevant jobs run consistently, even if no version bump is needed,
and improve communication in the workflow summary.

Workflow logic and communication improvements:

* When the current chart version matches the new version, the workflow
now adds a message to the GitHub step summary indicating that the appset
bump was skipped, making it clearer for reviewers and operators why no
bump occurred.
* The `wait_for_rollout` and `linear_release` jobs now run
unconditionally, regardless of whether a bump PR was created, ensuring
that environment verification and release registration always occur.
This improves reliability and avoids skipping important steps when
deployments are no-ops.
[[1]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3R467-L470)
[[2]](diffhunk://#diff-28802fbf11c83a2eee09623fb192785e7ca92a3f40602a517c011b947a1822d3L554)
This pull request makes a minor update to the `README.md` by removing
the "The end." line at the conclusion of the setup instructions.
## Changes proposed in this pull request

This pull request introduces a new way to configure the application's
base URL through an `APPLICATION_URL` environment variable, replacing
the previous hardcoded URLs for different environments. This change
improves flexibility and consistency in environment configuration,
especially for local development and deployments.

Configuration and environment management:

* Added support for the `APPLICATION_URL` environment variable, making
it required at startup (`cli.go`). The application will now fail to
start if this variable is not set.
* Refactored environment URL management: replaced hardcoded URLs
(`prodUrl`, `devUrl`, `localUrl`) with a single, mutable
`applicationURL` variable. Added `SetApplicationURL` and updated
`GetUrl` to return this value. Removed the old logic that returned URLs
based on environment. (`env.go`)
[[1]](diffhunk://#diff-655f5e833634a8579c679d59b124bffac00b13ca705ecee152ceb25bdf72b5c9L11-R19)
[[2]](diffhunk://#diff-655f5e833634a8579c679d59b124bffac00b13ca705ecee152ceb25bdf72b5c9L119-L130)

Deployment and configuration templates:

* Updated `helm/interledger-app/values.yaml` and related Helm chart
configuration to include `application_url`, and wired this value into
the backend config as `APPLICATION_URL`.
[[1]](diffhunk://#diff-100cce8429f01954c1af3be77db144265e78f8d7dcd8e08681dca63cf66a4a7dR142)
[[2]](diffhunk://#diff-100cce8429f01954c1af3be77db144265e78f8d7dcd8e08681dca63cf66a4a7dR803-R804)

Local development setup:

* Added `BACKEND_APPLICATION_URL` to `local/example.env` for easier
local configuration.
* Updated `local/wallet.yaml` to pass the `APPLICATION_URL` environment
variable to the backend service, defaulting to
`https://interledger.test` if not set.>

## Checklist

- [ ] Tests updated and in place
- [ ] No sensitive data linkage in logs, errors, etc
- [ ] DevOps team notified of any release-impacting changes (e.g.
environment variables, migrations, new services)
- [ ] Documentation and architecture updated
<img width="1280" height="720" alt="image"
src="https://github.com/user-attachments/assets/9c382b89-cc6b-4f04-8081-80447f110a5f"
/>


This pull request introduces end-to-end (E2E) test coverage and a
frontend enhancement for the Botanist admin portal, focusing on the
wallets management page. The changes add new E2E test steps and
scenarios for the admin portal UI, implement a client-side filter for
the wallets list, and improve testability and maintainability of the E2E
test suite.

**E2E Test Suite Enhancements:**

* Added new step definitions in `e2e/context.go` and corresponding
implementations in `e2e/botanist.go` to support navigation and
assertions for the Botanist admin portal, including menu visibility,
page title checks, and wallet filtering by email.
[[1]](diffhunk://#diff-94ad2a55bb9484585e3fef62396a16463d7854bd37527cd9de6efac1e45fefaeR47-R49)
[[2]](diffhunk://#diff-94ad2a55bb9484585e3fef62396a16463d7854bd37527cd9de6efac1e45fefaeR374-R404)
[[3]](diffhunk://#diff-9187eb711652f2bc92da46d3cc61a74c292b76e467b41a4a97d4b194edd66b3dR1-R220)
* Introduced two new feature files with scenarios for verifying the
admin portal navigation menu and the ability to filter wallets by common
fields such as email, including user signup and wallet visibility
checks.
[[1]](diffhunk://#diff-99ac06b10697086a126c1c63a34abba243ce1a4259736bf74d46af40db823c83R1-R24)
[[2]](diffhunk://#diff-39a6fda97182bc8462e7d318d465ffae25cc822335ff2afbc7b80493ec5fd053R1-R41)

**Frontend Improvements (Wallets Page):**

* Implemented a client-side filter input on the `/wallets` page,
allowing admins to filter the wallets list by wallet ID, name, email, or
phone number. The UI displays the number of filtered results and updates
the table accordingly.
[[1]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09R2)
[[2]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09L11-R13)
[[3]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09R27-R41)
[[4]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09R54-R71)
[[5]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09L75-R109)
[[6]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09L84-R121)
[[7]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09L111-R143)
* Improved table rendering logic for robustness by using optional
chaining (`wallet.users[0]?.email ?? ''`) to safely access user fields.

These changes collectively improve the admin experience for managing
wallets and ensure robust E2E test coverage for critical admin portal
functionality.
## Changes proposed in this pull request

Bumps the unit test threshold to be more aligned with the actual current
coverage.

## Checklist

- [x] Tests updated and in place
- [x] No sensitive data linkage in logs, errors, etc
- [x] DevOps team notified of any release-impacting changes (e.g.
environment variables, migrations, new services)
- [x] Documentation and architecture updated
This pull request implements server-side wallet search and updates the
Botanist admin wallets page to use it, replacing the previous
client-side filtering. The changes span backend, API, e2e tests, and
frontend code to enable searching wallets by name or ID (with
case-insensitive and partial match support), and update the test and UI
flows accordingly. Pagination and search now work together, and the user
experience is improved with more accurate result counts and page reloads
on search.

**Backend and API: Server-side search and pagination**

- Added a `search` field to the `PaginationRequest` proto and backend
pagination structs, enabling search queries to be passed from the
frontend to the backend. The backend now supports searching wallets by
name (case-insensitive, partial match) or by ID (exact match), and
combines search with pagination.
[[1]](diffhunk://#diff-55a6bd3f0bec9e97c3884a5d28ac973d638dbde276007f23d61ca849801ec89fR369)
[[2]](diffhunk://#diff-6177365039ef280357ac9837308a22e2b00a8d48f7b82a3ad1c6574531962204R3117)
[[3]](diffhunk://#diff-f4985d1a28df59841cc311421649e36775c93556b7d7d7f305282100e64c39f7R13)
[[4]](diffhunk://#diff-f4985d1a28df59841cc311421649e36775c93556b7d7d7f305282100e64c39f7R45)
[[5]](diffhunk://#diff-f1b594a13ce1778113a538d2791748f8c1be8aa2123072f90fd71a987848c084L246-R269)
- Updated the `ListWallets` RPC and DB logic to use the new search
parameter, and fixed pagination to correctly indicate if there is a next
page.
[[1]](diffhunk://#diff-2280ffd7696e018d248864af6e6e461219bb8e43a42715734e691cffd9f4ce6fR29-R33)
[[2]](diffhunk://#diff-2280ffd7696e018d248864af6e6e461219bb8e43a42715734e691cffd9f4ce6fL49-R60)

**Frontend: UI and search experience**

- Refactored the Botanist admin wallets page to use a server-side search
form instead of client-side filtering, submitting the search term to the
backend and displaying matching results. The table is now updated on
page reload, and pagination links preserve the search term.
[[1]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09L2-R30)
[[2]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09R45-R60)
[[3]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09L76-R69)
[[4]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09L109-R102)
[[5]](diffhunk://#diff-d0366c7bd23b9ddaf69c3e90b5977c7b3822e7351a81c33e1474db96ace23a09L144-R153)

**E2E tests: Adapted to new search flow**

- Updated e2e test steps and feature files to use "search by wallet
name" instead of the previous "filter by email", aligning with the new
backend search capability. The test implementation now triggers a form
submit and waits for the page reload.
[[1]](diffhunk://#diff-9187eb711652f2bc92da46d3cc61a74c292b76e467b41a4a97d4b194edd66b3dL164-R215)
[[2]](diffhunk://#diff-94ad2a55bb9484585e3fef62396a16463d7854bd37527cd9de6efac1e45fefaeL399-R400)
[[3]](diffhunk://#diff-39a6fda97182bc8462e7d318d465ffae25cc822335ff2afbc7b80493ec5fd053L22-R22)
[[4]](diffhunk://#diff-39a6fda97182bc8462e7d318d465ffae25cc822335ff2afbc7b80493ec5fd053L38-R38)

**Testing: Backend search coverage**

- Added unit tests to cover wallet search by name (exact and partial,
case-insensitive), by ID, and edge cases such as no matches and
pagination limits.
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@ory/client](https://redirect.github.com/ory/sdk) | [`1.22.22` →
`1.22.37`](https://renovatebot.com/diffs/npm/@ory%2fclient/1.22.22/1.22.37)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@ory%2fclient/1.22.37?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@ory%2fclient/1.22.22/1.22.37?slim=true)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/166) for more information.

---

### Release Notes

<details>
<summary>ory/sdk (@&#8203;ory/client)</summary>

###
[`v1.22.37`](https://redirect.github.com/ory/sdk/compare/1bd837100056f870ea191eeeb25461106c9739e8...6e316d789190471a40e30dc695d187291becedb7)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/1bd837100056f870ea191eeeb25461106c9739e8...6e316d789190471a40e30dc695d187291becedb7)

###
[`v1.22.36`](https://redirect.github.com/ory/sdk/compare/fcf8a9ee0913226212d6e4a8ce7d4b8483317fe6...1bd837100056f870ea191eeeb25461106c9739e8)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/fcf8a9ee0913226212d6e4a8ce7d4b8483317fe6...1bd837100056f870ea191eeeb25461106c9739e8)

###
[`v1.22.35`](https://redirect.github.com/ory/sdk/compare/209c6b041b2a998fe61045f8c6fe8461c56c26b5...fcf8a9ee0913226212d6e4a8ce7d4b8483317fe6)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/209c6b041b2a998fe61045f8c6fe8461c56c26b5...fcf8a9ee0913226212d6e4a8ce7d4b8483317fe6)

###
[`v1.22.34`](https://redirect.github.com/ory/sdk/compare/6ab6f96291894343ebf707599621b177617f63da...209c6b041b2a998fe61045f8c6fe8461c56c26b5)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/6ab6f96291894343ebf707599621b177617f63da...209c6b041b2a998fe61045f8c6fe8461c56c26b5)

###
[`v1.22.33`](https://redirect.github.com/ory/sdk/compare/92af7852a63330d7fd64b8479d1a0cac93bdb11b...6ab6f96291894343ebf707599621b177617f63da)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/92af7852a63330d7fd64b8479d1a0cac93bdb11b...6ab6f96291894343ebf707599621b177617f63da)

###
[`v1.22.32`](https://redirect.github.com/ory/sdk/compare/1d1c3f68dd95994db3ae88ad05a35f429befa399...92af7852a63330d7fd64b8479d1a0cac93bdb11b)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/1d1c3f68dd95994db3ae88ad05a35f429befa399...92af7852a63330d7fd64b8479d1a0cac93bdb11b)

###
[`v1.22.28`](https://redirect.github.com/ory/sdk/compare/a2ccb524034d2379f316d91f1bfed93f48b12a8f...1d1c3f68dd95994db3ae88ad05a35f429befa399)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/a2ccb524034d2379f316d91f1bfed93f48b12a8f...1d1c3f68dd95994db3ae88ad05a35f429befa399)

###
[`v1.22.27`](https://redirect.github.com/ory/sdk/compare/10f347d78ffc0ae673f23f84eefff01ccb7ef3c6...a2ccb524034d2379f316d91f1bfed93f48b12a8f)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/10f347d78ffc0ae673f23f84eefff01ccb7ef3c6...a2ccb524034d2379f316d91f1bfed93f48b12a8f)

###
[`v1.22.26`](https://redirect.github.com/ory/sdk/compare/374a63804a2f288c42e4e2aa367eaeb8d1332987...10f347d78ffc0ae673f23f84eefff01ccb7ef3c6)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/374a63804a2f288c42e4e2aa367eaeb8d1332987...10f347d78ffc0ae673f23f84eefff01ccb7ef3c6)

###
[`v1.22.25`](https://redirect.github.com/ory/sdk/compare/fc74e2c99407362168b910b14988eea1b0d35d7f...374a63804a2f288c42e4e2aa367eaeb8d1332987)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/fc74e2c99407362168b910b14988eea1b0d35d7f...374a63804a2f288c42e4e2aa367eaeb8d1332987)

###
[`v1.22.24`](https://redirect.github.com/ory/sdk/compare/137dab984d5d4eec1650787cabd937ca1703f6dc...fc74e2c99407362168b910b14988eea1b0d35d7f)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/137dab984d5d4eec1650787cabd937ca1703f6dc...fc74e2c99407362168b910b14988eea1b0d35d7f)

###
[`v1.22.23`](https://redirect.github.com/ory/sdk/compare/01b455b5a7085413df763f797a010f4f28660b00...137dab984d5d4eec1650787cabd937ca1703f6dc)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/01b455b5a7085413df763f797a010f4f28660b00...137dab984d5d4eec1650787cabd937ca1703f6dc)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/interledger/interledger-app).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xODIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE4Mi4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…s status (#485)

### Problem description

While a user's KYC is in `Pending` (or `InReview`) status, tapping
**Pay**, **Actions › Deposit**, or **Withdraw** redirected them to
`/personal-details` - the start of the KYC flow, effectively asking them
to redo verification that's already submitted and being processed.

## Changes proposed in this pull request
* When KYC is in Pending or InReview, the user should land on the home
screen with a clear message explaining that verification is in progress,
instead of being thrown back into the KYC form.
* Close the command palette on action click so the redirect's snackbar
isn't hidden behind the dialog backdrop.
This PR attempts to fix a bug introduced in my previous PR where
botanist wallet filtering was moved to now be performed on the backend.

I resolved the issue and added more e2e tests to prevent this regression
again.

<img width="1338" height="758" alt="image"
src="https://github.com/user-attachments/assets/9f0345b1-4d69-4e9a-a6d6-5f67b436fd80"
/>

<img width="1363" height="466" alt="image"
src="https://github.com/user-attachments/assets/f570cbb5-e352-4692-bb3f-be4de6440b8f"
/>

<img width="1340" height="402" alt="image"
src="https://github.com/user-attachments/assets/f521af7c-8999-4782-81c7-620eafae69b6"
/>

---

This pull request enhances the wallet filtering functionality in the
admin backend and its end-to-end (E2E) test coverage. The main focus is
on improving the user experience and reliability of wallet search by
supporting email-based filtering and strengthening test assertions to
catch regressions in the filter logic.

**Backend Improvements:**

* Added support for searching wallets by email address in the
`ListWallets` admin RPC. If the search term looks like an email, it is
resolved to a wallet ID before applying the filter, ensuring that email
searches correctly find the associated wallet.
* Introduced the `FindWalletIDByEmail` method in the user client
interface and implemented it in the client, mock, and ops layers. This
method resolves an email address to the corresponding wallet ID using
Kratos and the `user_wallets` table.
[[1]](diffhunk://#diff-b0ee740e1925e18a773d96a9eb06b32569c50448a4375ea489a74ce4b280dab5R17-R19)
[[2]](diffhunk://#diff-a7dbad0f5dd7e52026e09ea2c988e68eecd8bef9b4804c94d1fa72f1ab9242afR98-R101)
[[3]](diffhunk://#diff-ef972b2633223bc1c71e1c223cdab0c1af0898d60db0b96f780c1f81701d9f34R161-R164)
[[4]](diffhunk://#diff-69134863a37c05cccfbfd3a1bf2544a494cdcee09c860ef9cd73e35c03dd2fa9R169-R195)

**E2E Test Enhancements:**

* Added new test steps and helper methods to assert that the wallet list
correctly shows exactly one result when filtered, and that the
unfiltered list contains more than one result. This ensures the filter
is not silently ignored and helps catch regressions.
[[1]](diffhunk://#diff-9187eb711652f2bc92da46d3cc61a74c292b76e467b41a4a97d4b194edd66b3dR241-R290)
[[2]](diffhunk://#diff-94ad2a55bb9484585e3fef62396a16463d7854bd37527cd9de6efac1e45fefaeR405-R410)
* Updated the relevant feature file to include these new assertions,
improving the robustness of the filtering tests.

**Other:**

* Minor import adjustment to include the `strings` package where needed.
* Updated stub and mock user clients to implement the new
`FindWalletIDByEmail` method for test compatibility.
[[1]](diffhunk://#diff-889c0c424e228247dd28309b59e5ee8c907cf6074ba7048055848e0d43f591c8R45-R47)
[[2]](diffhunk://#diff-ef972b2633223bc1c71e1c223cdab0c1af0898d60db0b96f780c1f81701d9f34R161-R164)

These changes collectively improve both the backend's filtering
capabilities and the reliability of automated tests around wallet search
and filtering.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
UI functionality in the Admin portal allowing users to reset TOTP of a
wallet.

See images and linear issue for more details.

<img width="1324" height="792" alt="image"
src="https://github.com/user-attachments/assets/0227cc16-70e4-4296-af8c-95f4d279d00d"
/>

<img width="1358" height="824" alt="image"
src="https://github.com/user-attachments/assets/cf92879c-1e5b-422c-9697-77aac510c7a0"
/>

<img width="1184" height="780" alt="image"
src="https://github.com/user-attachments/assets/249170ba-dc1a-47c7-8adf-2a3a096ddedb"
/>

<img width="1048" height="863" alt="image"
src="https://github.com/user-attachments/assets/f497c871-c905-40ef-b3cd-1dfd90c78839"
/>

---

This pull request introduces a new admin feature that allows
administrators to reset a user's authenticator (TOTP) enrollment from
the wallet profile page in the admin portal. It includes backend,
frontend, email notification, and end-to-end test changes to support and
verify this workflow.

**Key changes include:**

### Admin Portal and E2E Test Enhancements

* Added a new scenario to the E2E test suite
(`101-botanist-wallets.feature`) that verifies an admin can reset a
wallet user's authenticator, including UI interactions, audit log
verification, and TOTP re-enrollment flow.
* Implemented new E2E step definitions and helpers to automate
navigation to the wallet profile, interact with the reset authenticator
button, handle confirmation modals, verify TOTP state, and check audit
logs.
[[1]](diffhunk://#diff-9187eb711652f2bc92da46d3cc61a74c292b76e467b41a4a97d4b194edd66b3dR291-R466)
[[2]](diffhunk://#diff-94ad2a55bb9484585e3fef62396a16463d7854bd37527cd9de6efac1e45fefaeR412-R435)
[[3]](diffhunk://#diff-6a7f19b8b33935109c7498ee139ab704aa0e1e6606aa9bccd6a187441b6bdf23R257-R296)
[[4]](diffhunk://#diff-94ad2a55bb9484585e3fef62396a16463d7854bd37527cd9de6efac1e45fefaeR162)

### Frontend (Admin Portal UI)

* Updated the wallet profile page (`wallet.$id.profile.tsx`) to display
the reset authenticator button when TOTP is enabled, show a confirmation
modal, handle reset actions, and update UI state accordingly.
[[1]](diffhunk://#diff-75344031f95b9cd5e56bbb139532f81dbfc85c30ce8f5f04b7c7a9d5008a3fb6L7-R10)
[[2]](diffhunk://#diff-75344031f95b9cd5e56bbb139532f81dbfc85c30ce8f5f04b7c7a9d5008a3fb6R23-R36)
[[3]](diffhunk://#diff-75344031f95b9cd5e56bbb139532f81dbfc85c30ce8f5f04b7c7a9d5008a3fb6L35-R57)
[[4]](diffhunk://#diff-75344031f95b9cd5e56bbb139532f81dbfc85c30ce8f5f04b7c7a9d5008a3fb6L64-R90)
[[5]](diffhunk://#diff-75344031f95b9cd5e56bbb139532f81dbfc85c30ce8f5f04b7c7a9d5008a3fb6R117-R129)

### Backend and Email Notification

* Extended the admin RPC service to send an authenticator reset email to
the user when their TOTP enrollment is reset by an admin.
* Added a new method `SendAuthenticatorResetEmail` to the email service
interface and implementations, including a new email template operation.
[[1]](diffhunk://#diff-0e54ba440b06fa317d6ecfde2596c292d2e6edb710c5538fe9c3250d786509d0R30)
[[2]](diffhunk://#diff-8abed5562644a73ceaaffa536b019e6c0a98437590c7d66d44e2662611996215R106-R109)
[[3]](diffhunk://#diff-852c355c7ede3dbd90827e1c580949af76bb39739c04dbe4fbe8ac50b33e46d2R76-R87)
[[4]](diffhunk://#diff-e2383f82bd2edd3199929397b0773be1f6e01ed18dfcd946c5b35248d3f3dea5R73-R76)
[[5]](diffhunk://#diff-d674ae0e13926862dadbbfe338ba873745ced3ab76a9d8f1a5ccdd239eed3cf1R532-R562)

### Minor Improvements

* Removed a redundant debug log from the TOTP deletion function.

These changes ensure that administrators can securely reset a user's
authenticator enrollment, notify users of the action, and that the
process is thoroughly tested end-to-end.
bosbaber and others added 14 commits July 6, 2026 15:42
TL;DR - Refactor so that the go `backend` will depend on configuration
files instead of environmental variables.

See the [Screen
recording](https://www.loom.com/share/88fc84bce97e492cb18d6a8da73b83cb)
explaining the changes.

This PR is a major and brave refactor to the way we have been doing
configurations. Our go backend code will now depend on the newly minted
`configa` library to ingest and validate configurations from `.yaml`
config files. Various checks will be performed on them before they are
passed on to the actual application.

One of the motivations of this change is to work towards removing very
tight coupling between application configuration and the helm charts.
This change will allow the helm application to become agnostic towards
configurations. At the moment only some application specific validation
rules still remain in the helm chart, but in the future this will go
away once we move towards automatead schema generation and validation.

A new `k8s` folder is also introduced to the project that demonstrates
how configurations are to be used for kubernetes deployments and how to
use the `configa` secret resolution scheme.

The outcome of this change should be that we can have:
- A yaml based configuration hierarchy
- Configuration type checking
- Secret resolution
- Simplified Helm charts
- Consistent configuration
This PR not only fixes a small issue with the CI pipeline, but it will
also trigger a new release that includes the configuration changes
merged with the previous PR.
This PR is a response to a bug we ran into while trying to deploy the
new helm chart to the dev1 environment. The deployment stalled because
the migration scripts failed. It could not access the appropriate
secrets.

This was because the migration scr runs using the pre-upgrade and
pre-install annotations on an argo level.

---

## Auto generated

This pull request updates the Helm chart for `interledger-app` to ensure
that the necessary RBAC resources (Role and RoleBinding) are created
before other dependent resources during installation or upgrade. This
prevents permission errors during migrations in environments where the
Role does not already exist. The most important changes are:

**Helm RBAC resource creation timing:**

* Added Helm hook annotations to both the `Role` and `RoleBinding`
templates so they are rendered as `pre-install` and `pre-upgrade` hooks
with a weight of -10, ensuring they are created before the migration
ConfigMap and Job run. This avoids permission errors during migrations.
[[1]](diffhunk://#diff-e8ed864f9eaa43bcdda8aa062c92b779902ec5ea0d8ca117a70cbd1f2200ffe2R33-R35)
[[2]](diffhunk://#diff-e8ed864f9eaa43bcdda8aa062c92b779902ec5ea0d8ca117a70cbd1f2200ffe2R51-R53)

**Documentation updates:**

* Updated comments in `rbac.backend.yaml` to explain the rationale for
using pre-install/pre-upgrade hooks and the absence of a
hook-delete-policy, clarifying that the Role and RoleBinding will
persist after hook completion.
Fixes another migration related issue discovered during deployment
attempt.

---

## Auto generated

This pull request updates the Helm chart for the backend RBAC resources
to improve upgrade reliability and avoid resource conflicts during
deployments. The main change is the addition of a `hook-delete-policy`
to ensure that Role and RoleBinding resources are properly cleaned up
before each hook run, preventing "already exists" errors on upgrades
while maintaining necessary permissions for running pods.

**Helm hook policy improvements:**

* Added `"helm.sh/hook-delete-policy": before-hook-creation` annotation
to both the backend `Role` and `RoleBinding` resources in
`rbac.backend.yaml`, ensuring that previous hook-created resources are
deleted before new ones are created during upgrades. This avoids
resource conflicts and ensures smooth upgrades.
[[1]](diffhunk://#diff-e8ed864f9eaa43bcdda8aa062c92b779902ec5ea0d8ca117a70cbd1f2200ffe2R40)
[[2]](diffhunk://#diff-e8ed864f9eaa43bcdda8aa062c92b779902ec5ea0d8ca117a70cbd1f2200ffe2R59)

**Documentation update:**

* Updated the explanatory comment in `rbac.backend.yaml` to clarify the
new behavior: the Role/RoleBinding are deleted only before the next hook
run (not after hook success), preventing "already exists" errors while
keeping the RBAC resources available for pods that need them.
## Changes proposed in this pull request

<img width="2320" height="1546" alt="image"
src="https://github.com/user-attachments/assets/a099a611-1259-4256-a3ec-c7cb5f037a9d"
/>


## Checklist

- [ ] Tests updated and in place
- [ ] No sensitive data linkage in logs, errors, etc
- [ ] DevOps team notified of any release-impacting changes (e.g.
environment variables, migrations, new services)
- [ ] Documentation and architecture updated
)

## Changes proposed in this pull request

- <!-- Describe the changes introduced by this PR -->

## Checklist

- [ ] Tests updated and in place
- [ ] No sensitive data linkage in logs, errors, etc
- [ ] DevOps team notified of any release-impacting changes (e.g.
environment variables, migrations, new services)
- [ ] Documentation and architecture updated
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@ory/client](https://redirect.github.com/ory/sdk) | [`1.22.37` →
`1.22.61`](https://renovatebot.com/diffs/npm/@ory%2fclient/1.22.37/1.22.61)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@ory%2fclient/1.22.61?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@ory%2fclient/1.22.37/1.22.61?slim=true)
|

---

### Release Notes

<details>
<summary>ory/sdk (@&#8203;ory/client)</summary>

###
[`v1.22.61`](https://redirect.github.com/ory/sdk/compare/93f409bac3b5539a668cae11324242abb2858817...831c0c4dc4b58394c6de9abb5cb54961f2746a9d)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/93f409bac3b5539a668cae11324242abb2858817...831c0c4dc4b58394c6de9abb5cb54961f2746a9d)

###
[`v1.22.60`](https://redirect.github.com/ory/sdk/compare/d14dcac0810c25ee728b8aa12bf2d21541fd68bd...93f409bac3b5539a668cae11324242abb2858817)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/d14dcac0810c25ee728b8aa12bf2d21541fd68bd...93f409bac3b5539a668cae11324242abb2858817)

###
[`v1.22.59`](https://redirect.github.com/ory/sdk/compare/3da8da57ed0b3e1dc627f0997fee7ab486cddb5b...d14dcac0810c25ee728b8aa12bf2d21541fd68bd)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/3da8da57ed0b3e1dc627f0997fee7ab486cddb5b...d14dcac0810c25ee728b8aa12bf2d21541fd68bd)

###
[`v1.22.58`](https://redirect.github.com/ory/sdk/compare/01349619983030c5f931bbd66f7d489d5587b94e...3da8da57ed0b3e1dc627f0997fee7ab486cddb5b)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/01349619983030c5f931bbd66f7d489d5587b94e...3da8da57ed0b3e1dc627f0997fee7ab486cddb5b)

###
[`v1.22.57`](https://redirect.github.com/ory/sdk/compare/67fb3e07a7c705e48535c17a1c58b345c9c855c4...01349619983030c5f931bbd66f7d489d5587b94e)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/67fb3e07a7c705e48535c17a1c58b345c9c855c4...01349619983030c5f931bbd66f7d489d5587b94e)

###
[`v1.22.56`](https://redirect.github.com/ory/sdk/compare/6e316d789190471a40e30dc695d187291becedb7...67fb3e07a7c705e48535c17a1c58b345c9c855c4)

[Compare
Source](https://redirect.github.com/ory/sdk/compare/6e316d789190471a40e30dc695d187291becedb7...67fb3e07a7c705e48535c17a1c58b345c9c855c4)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/interledger/interledger-app).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI0Mi4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Changes proposed in this pull request

Change mail formatting 

## Checklist

- [x] Tests updated and in place
- [x] No sensitive data linkage in logs, errors, etc
- [x] DevOps team notified of any release-impacting changes (e.g.
environment variables, migrations, new services)
- [ ] Documentation and architecture updated
@linear

linear Bot commented Jul 8, 2026 •

Copy link
Copy Markdown
WAL-1205 Migrate protea and admin portals to configuration files

Plan: TypeScript configa for protea & botanist

Goal

Create a TypeScript library — the equivalent of the Go go/configa library — that both protea (frontend/wallet) and botanist (admin portal) use to load their server-side configuration.

After this work, the server side ("backend") of both React Router apps depends on a minimal set of environment variables and instead reads configuration from a YAML config file:

  • Local: the YAML file is bind-mounted into the container.
  • Kubernetes: the YAML is delivered via a ConfigMap and mounted as a volume.
  • Secrets: handled exactly like the Go configa library — {{ secret "name" "key" }} templates resolved at runtime by calling the Kubernetes API in-cluster.

The same YAML files and the same {{ secret … }} template syntax must work for both the Go services and the new TS services, so ops writes config once.

Branch context

This branch (stephan/wal-1205) is based on stephan/wal-1157, which has already migrated the Go backend to the YAML/configa scheme. That is a large, working reference implementation we build on — we are not pioneering the pattern, we are following it for the two TypeScript apps.

What stephan/wal-1157 already delivers (our reference — do not redo)

  • Backend Go config loader: go/backend/config/start.go + migration.go. Typed StartConfig struct with validate tags, CONFIG env var (comma-separated YAML files, later overlays win), {{ secret … }} resolution via configa.InClusterSecretClient, applyStartDefaults, and mode-based validation (prod/dev/local/test).
  • Helm RBAC (in the interledger-app chart): helm/interledger-app/templates/rbac.backend.yaml — renders a scoped Role (get on named secrets, no wildcards) + RoleBinding, driven by .Values.backend.secretAccess + .Values.backend.server.serviceAccount.name. This is the exact template to mirror for frontend/admin.
  • Helm config delivery: backend ConfigMap templates + deployment env CONFIG=/etc/backend/config.yaml, plus validation.backend.yaml.
  • Local docker-compose config pattern: local/config/backend.yaml (+ backend.migration.yaml), mounted read-only, with a config-override/ overlay. CONFIG=/etc/backend/config.yaml,/etc/backend/config-override.yaml (see local/wallet.yaml). make prep creates empty override files; config-override/ is gitignored.
  • kind harness (in k8s/): the k8s/Makefile already builds, loads, and deploys backend protea botanist and the full interledger-app chart via k8s/kind/values.interledger-app.yaml, with certs, ingressroutes, manifests/app-secrets.yaml, and scripts/validate.sh.

What is NOT yet done (this project)

  • No TypeScript configa library exists.
  • protea and botanist are still env-var based. In the kind values, the frontend: and admin: sections still use the old config: block with *_ref keys that render secretKeyRef env injection — not configa YAML. protea's app/env.server.ts still validates a long knownEnvKeys* list; botanist has no validation.
  • The two TS apps are still independent pnpm projects (built with per-app Docker context ./typescript/protea / ./typescript/botanist in both the kind Makefile and tooling/github-scripts/constants.js). No workspace, so no shared library is reachable at build time.

Scope

  • Everything lands in interledger-app. No interledger-app-deploy changes in this project — rollout there happens later, once we have confidence.
  • Confidence is proven two ways:
    1. Local docker-compose (the primary target — get this fully working first).
    2. kind, via the k8s/ harness (proves in-cluster secret resolution + RBAC).
  • The Helm chart owns the RBAC, mirroring rbac.backend.yaml.

Prerequisite (separate PR — NOT part of this project)

Upgrade protea and botanist to the current Node LTS (Node 24.x at time of writing).

Today the two apps diverge: protea's Dockerfile uses node:20-alpine, botanist's engines require >=22.19, and each app pins pnpm@8.5.0 independently. A single pnpm workspace needs one consistent Node + pnpm baseline. Do this first in its own PR:

  • Bump both Dockerfiles and engines to the current Node LTS.
  • Align the pnpm version across both apps.
  • Confirm both apps build, boot, and pass their existing checks on the new Node.

This PR is a hard prerequisite — the workspace and library work below assumes both apps are already on the same Node LTS and pnpm version.


Development approach (read first)

  1. Local docker-compose is the primary target. Get the entire flow working end-to-end in the local environment before touching kind or CI. The backend already runs this way locally — mirror its local/config/*.yaml + config-override/ + CONFIG mount pattern for protea/botanist.
  2. Reuse the existing backend patterns. The reference is already in the tree and working:
  3. Preserve live reload. Developers rely on live reload (Vite dev / react-router dev). The local setup uses target: dev and bind-mounts app/ into the container (see local/protea.yaml, local/botanist.yaml). This must keep working. Loading config from a bind-mounted YAML file must not break hot reload of app code. Verify live reload still functions after the change.
  4. Use the e2e tests to check your work — incrementally, not all at once. See Verification. Running the whole suite from the start takes too long; run the targeted subsets in order and always with concurrency.

Decisions (already agreed)

Decision Choice
Sharing mechanism pnpm workspace under typescript/ (expand Docker build context, bundle via Vite)
Secret handling Full parity — in-cluster Kubernetes API fetch, identical {{ secret … }} syntax
Validation Zod schemas
RBAC Helm chart owns it, mirroring rbac.backend.yaml

Work breakdown

1. pnpm workspace under typescript/

protea and botanist are independent pnpm projects today. Establish a workspace:

  • Add typescript/pnpm-workspace.yaml:

    packages:
      - "protea"
      - "botanist"
      - "packages/*"
  • Add a private typescript/package.json with a single packageManager (pnpm version from the prerequisite PR) and shared engines.

  • Generate a single typescript/pnpm-lock.yaml. (protea/botanist already live at typescript/protea / typescript/botanist — just workspace membership.)

2. Library — @interledger/configa at typescript/packages/configa

Faithful TypeScript port of go/configa, ESM, built with tsup (or tsc). Match the Go public surface and the behaviour the backend already relies on:

  • parseConfig(files: string[], opts?) — read the first file, deep-merge overlays in order (maps deep-merge; scalars/arrays overlay-wins; last file wins — port of merge.go). Detect {{.
  • resolve<T>(schema: ZodType<T>): Promise<T> — if templates present and no secret client → throw ErrNoSecretClient; resolve templates; yaml.parse; schema.parse(...) → typed + validated result.
  • Template resolver — regex match of {{ secret "name" "key" }} (whitespace-tolerant, byte-compatible with the YAML the Go services already consume). Walk all string leaves; per-resolve cache keyed by secret name (mirrors resolve.go). Only the secret function — not a full Go-template engine.
  • InClusterSecretClient — port of k8s.go: lazy-load SA token/CA/namespace from /var/run/secrets/kubernetes.io/serviceaccount/*, read KUBERNETES_SERVICE_HOST/PORT, GET /api/v1/namespaces/{ns}/secrets/{name} over CA-pinned TLS (Node undici dispatcher with the SA CA), base64-decode .data. Same sentinel errors: ErrNoSecretClient, ErrSecretNotFound, ErrSecretForbidden, ErrSecretFetchFailed.
  • SecretClient interface + a fake for tests.
  • Vitest suite porting the cases from configa_test.go / k8s_test.go.

Dependencies: yaml, zod (peer), undici (or Node global fetch with a custom dispatcher).

3. Wire the library into protea & botanist

  • Add "@interledger/configa": "workspace:*" to both apps.
  • Add the package to ssr.noExternal in both Vite configs so it is bundled into the server output (the runner image copies only the app's own artifacts).
  • protea: replace app/env.server.ts with a Zod ConfigSchema (the TS analogue of the backend's StartConfig) loaded once at server startup from CONFIG via InClusterSecretClient. Reduce env vars to the bootstrap set: CONFIG, NODE_ENV, INTERLEDGER_APP_VERSION, KUBERNETES_SERVICE_*.
  • botanist: introduce the same startup path (it has no validation today).

4. Local docker-compose (do this before kind/CI)

Mirror the backend's local pattern exactly:

  • Author local/config/protea.yaml and local/config/botanist.yaml (base config; non-secret values in plaintext, no {{ secret }} needed locally).
  • Add config-override/protea.yaml / config-override/botanist.yaml to make prep (empty override files; config-override/ is gitignored) so devs can override locally like they do for the backend.
  • In local/protea.yaml / local/botanist.yaml: mount the config read-only, set CONFIG=/etc/<app>/config.yaml,/etc/<app>/config-override.yaml, and shrink the environment: blocks to the bootstrap set.
  • No secret client needed locally — no {{ secret }} templates survive, so configa skips all Kubernetes calls (same as the backend's local path).
  • Keep target: dev and the app/ bind-mount so live reload keeps working. Verify hot reload after the change.
  • Start the stack with make all-nowatch in local/ and verify both apps boot and serve.

5. Docker & CI build context

  • Change the TS build context from ./typescript/protea / ./typescript/botanist to ./typescript in both:
  • Rewrite both Dockerfiles for workspace installs: copy pnpm-workspace.yaml + lockfile + packages/ + the target app, pnpm install --frozen-lockfile --filter <app>..., then pnpm --filter <app> build. Runner stage copies the built app only (library bundled in via ssr.noExternal).
  • Verify each image builds and boots.

6. Helm chart: config delivery + RBAC (chart-owned)

  • ConfigMap + volume: add configMap.frontend.yaml / configMap.admin.yaml templates rendering the app YAML from values; mount as a volume; set CONFIG to the mounted path(s) on the frontend/admin deployments (mirror how the backend deployment does it).
  • RBAC: add rbac.frontend.yaml / rbac.admin.yaml mirroring rbac.backend.yaml, driven by .Values.frontend.secretAccess / .Values.admin.secretAccess + the frontend/admin SA name. The frontend SA is "" today, so this assigns it a real SA.
  • helm-unittest: add tests under helm/interledger-app/tests/ for the new ConfigMaps, Roles, and RoleBindings — the existing backend.*_test.yaml / mock *serviceaccount_test.yaml files are the template.

7. kind end-to-end testing (extend k8s/)

The harness already builds/loads/deploys protea & botanist and the interledger-app chart. The remaining work is to switch their configuration from env vars to configa YAML:

  • Values migration: in k8s/kind/values.interledger-app.yaml, convert the frontend: and admin: config: blocks (currently *_ref env-injection style) to configa YAML with {{ secret … }} templates, plus serviceAccount.create: true + secretAccess: [...] — exactly like the backend: section already does.
  • Secrets: add the frontend/admin secret keys to k8s/manifests/app-secrets.yaml so the templates resolve.
  • Build context: update build-app for the new ./typescript context (see step 5).
  • Validate: extend k8s/scripts/validate.sh to hit protea/botanist health endpoints (/healthz) and confirm pods are 1/1 Running with secrets resolved (no CrashLoop). This is the kind acceptance gate.

Verification with e2e tests

The e2e suite is a Go/godog BDD suite. Scenarios are tagged (-tags) and run concurrently (-concurrency).

Do NOT run the whole suite from the start — it takes too long. Run these targeted subsets in this order, only moving on once the previous is green:

  1. Signup
  2. P2P payments
  3. Deposit

Always use --concurrency=5.

Bring up the full local stack first (make all-nowatch in local/), then from e2e/:

# 1. Signup
go test -v -timeout 10m -args -tags signup --concurrency=5

# 2. P2P payments (only after signup passes)
go test -v -timeout 10m -args -tags p2p --concurrency=5

# 3. Deposit (only after p2p passes)
go test -v -timeout 10m -args -tags deposit --concurrency=5

Notes:

  • Tags live in e2e/features/*.feature (@signup, @p2p, @deposit).
  • Keep -timeout 10m — some flows (multiple KYC steps) exceed 5 minutes.
  • On failure, check screenshots under e2e/debug/<feature>__<scenario>/.
  • See e2e/AGENTS.md and e2e/README.md for environment gotchas (e.g. make reset for stale tel validation issues).

Suggested sequencing (each step independently reviewable)

  1. (Prerequisite PR) Upgrade protea & botanist to the current Node LTS + unify pnpm.
  2. pnpm workspace scaffold.
  3. @interledger/configa package + Vitest tests (nothing depends on it yet).
  4. Adopt in protea; get local docker-compose fully working (live reload preserved).
  5. Verify with e2e: signup → p2p → deposit (--concurrency=5), in order.
  6. protea Dockerfile + build-context changes (CI + kind Makefile); image builds & boots.
  7. Helm: ConfigMap + rbac.frontend.yaml for frontend; helm-unittest green.
  8. kind: migrate frontend values to configa; deploy + validate protea end-to-end (secret resolution proven).
  9. Repeat 3–7 for botanist (rbac.admin.yaml, admin values, botanist e2e tags @botanist/admin features).

Residual risks

  • Vite SSR externalization of undici / yaml — confirm they're bundled into, or present in, the runner image.
  • Live reload regression — the highest-risk day-to-day impact; explicitly verify dev hot-reload after the config change.
  • Config/secret split — be deliberate about which keys are non-secret (ConfigMap) vs secret ({{ secret … }}); the kind *_ref keys today are a guide to what's currently treated as secret.
  • kind image builds are slow — TS multi-stage builds add minutes; keep the split build-app / build-mock targets so mock-only runs stay fast.

Review in Linear

@bosbaber
bosbaber force-pushed the stephan/wal-1205 branch from ef008f4 to bd7a0c6 Compare July 8, 2026 07:07
@bosbaber
bosbaber force-pushed the stephan/wal-1205 branch from d9a0d2c to 85a169a Compare July 8, 2026 07:37
@bosbaber
bosbaber temporarily deployed to e2e-scaler-system July 8, 2026 07:37 — with GitHub Actions Inactive
@github-actions github-actions Bot added documentation Improvements or additions to documentation CI protea local botanist helm labels Jul 8, 2026
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

E2E Test Report

E2E markdown report is available as an artifact:

This branch had an error being deployed

1 failed and 1 inactive deployments
e2e-scaler-system — 85a169a7 Deployed Jul 8, 2026 by bosbaber via scale #3539
e2e-tester — 85a169a7 Deployed Jul 8, 2026 by bosbaber via e2e #1345
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

botanist CI documentation Improvements or additions to documentation helm local protea

Projects

None yet

Development

Successfully merging this pull request may close these issues.