If there are two concurrent requests to create or edit change requests,
two separate ones may be created in parallel. The UI does not currently
handle this scenario, and if additional changes are made, they might be
added to a random existing change request—resulting in a messy and
unpredictable state.
This PR adds a unique index to the `change_requests` table
```
on (created_by, project, environment)
WHERE state NOT IN ('Applied', 'Cancelled', 'Rejected', 'Scheduled').
```
In the extremely rare case where such conflicting data already exists in
a database, the migration will automatically cancel one of the
conflicting change requests.
- added `sideMenuCleanup` flag
- extracted `SecondaryNavigation`, `SecondaryNavigationList` and
`MobileNavigationSidebar` into separate files
- hidden recent projects and flags
- renamed 'Insights' to 'Analytics'
Unleash is being too reactive to events inside Unleash. We should not
update etag if feature is created or tag is added to feature.
This PR adds this condition and adds test for it.
Now we can receive custom metrics, return those for UI and have extra
prometheus endpoint for it.
---------
Co-authored-by: Christopher Kolstad <chriswk@getunleash.io>
Blocks deletion of context fields that are in use and updates the
"active usage" count to exclude use in archived flags.
- Before allowing you to delete a context field, checks if it is in use
by any strategies. If so, returns a 409 error.
- Updates what we count as "in use" to exclude flags that have been
archived.
BREAKING CHANGE: Context fields can no longer be deleted if they are in
use by active (non-archived) flags.
## About the changes
Our health implementation always returns GOOD if the server is up:
beb29f5b5b/src/lib/routes/health-check.ts (L46-L51)
Currently our documentation of the endpoint is misleading saying that it
will return BAD if unable to connect to PostgreSQL
Closes#9965
Vitest Pros:
* Automated failing test comments on github PRs
* A nice local UI with incremental testing when changing files (`yarn
test:ui`)
* Also nicely supported in all major IDEs, click to run test works (so
we won't miss what we had with jest).
* Works well with ESM
Vitest Cons:
* The ESBuild transformer vitest uses takes a little longer to transform
than our current SWC/jest setup, however, it is possible to setup SWC as
the transformer for vitest as well (though it only does one transform,
so we're paying ~7-10 seconds instead of ~ 2-3 seconds in transform
phase).
* Exposes how slow our tests are (tongue in cheek here)
https://linear.app/unleash/issue/2-3564/remove-filterexistingflagnames-feature-flag
We're removing the `filterExistingFlagNames` feature flag since we've
decided we want this to be the default behavior.
We don't need to rush to merge it, just in case we need to disable this
for any reason. However it should also be pretty easy to just revert if
needed.
Changes in tests are a bit tricky since they assumed the previous
behavior where we always registered metrics, even for non existing flag
names. `cachedFeatureNames` is also memoized with a TTL of 10s, so the
easiest way to overcome this was to override `cachedFeatureNames` to
return what we expected. As long as they return the same flag names that
we expect, we're able to register their metrics.
Let me know if you can think of a better approach.
Improves handling of constraints in use that have been deleted.
This change implments a few small changes on both the front and the back
end on how we deal with constraints that have been deleted.
The most important change is on the back end, in the
`/constraints/validate` endpoint. We used to throw here if the
constraint couldn't be found, but the only reason we wanted to look for
the constraint in the db was to check for legal values. Now, instead,
we'll allow you to pass a constraint field that doesn't exist in the
database. We'll still check the values against the operator for
validity, we just don't control legal values anymore (because there
aren't any).
On the front end, we improve the handling by showing the deleted context
filed in the dropdown, both when the selector dropdown is closed and
when it is open. However, if you change the context field, we remove the
deleted field from the list. This seems like a sensible tradeoff. Means
you can't select it if you've deselected it.
We're migrating to ESM, which will allow us to import the latest
versions of our dependencies.
Co-Authored-By: Christopher Kolstad <chriswk@getunleash.io>
Add `getProjectLinkTemplates` method to ProjectStore and corresponding
test. Ideally this should be in a read-model, but let's finish link
templates end to end
Adds support for link templates in projects, allowing reusable URL
patterns with placeholders. Includes validation, database changes,
updated API schemas, and tests.
https://linear.app/unleash/issue/2-3406/hold-unknown-flags-in-memory-and-show-them-in-the-ui-somehow
This PR introduces a suggestion for a “unknown flags” feature.
When clients report metrics for flags that don’t exist in Unleash (e.g.
due to typos), we now track a limited set of these unknown flag names
along with the appnames that reported them. The goal is to help users
identify and clean up incorrect flag usage across their apps.
We store up to 10 unknown flag + appName combinations, keeping only the
most recent reports. Data is collected in-memory and flushed
periodically to the DB, with deduplication and merging to ensure we
don’t exceed the cap even across pods.
We were especially careful to make this implementation defensive, as
unknown flags could be reported in very high volumes. Writes are
batched, deduplicated, and hard-capped to avoid DB pressure.
No UI has been added yet — this is backend-only for now and intended as
a step toward better visibility into client misconfigurations.
I would suggest starting with a simple banner that opens a dialog
showing the list of unknown flags and which apps reported them.
<img width="497" alt="image"
src="https://github.com/user-attachments/assets/b7348e0d-0163-4be4-a7f8-c072e8464331"
/>
Spotted this in local dev mode:
```
[2025-04-17T15:10:21.036] [DEBUG] openapi-service.ts - Invalid response: {
"schema": "#/components/schemas/environmentsProjectSchema",
"errors": [
{
"instancePath": "/environments/0",
"schemaPath": "#/additionalProperties",
"keyword": "additionalProperties",
"params": {
"additionalProperty": "requiredApprovals"
},
"message": "must NOT have additional properties"
}
]
}
```
Enabling strictSchemaValidation in dev mode should help prevent these
issues from going out to prod as developers would identify them while
testing locally
## About the changes
Currently, we're running against the older version of our UI. When
making changes to it we want to make sure we're testing the current code
**Details in comments**
---------
Co-authored-by: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com>
## About the changes
Initially at Unleash we started using `process.nextTick` inside
constructors to delay initialization of services.
Later we stared using a pattern where we instantiate services multiple
times.
The problem is the first pattern implies we have singleton services,
while the second pattern breaks the singleton.
There are reasons for both patterns, but we've decided that
`process.nextTick` inside constructors is not something we want to keep
as it creates side effects from creating objects. Instead this PR
proposes a more explicit approach.
Fixes#9775