1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-05 17:53:12 +02:00

chore(AI): reportUnknownFlags flag cleanup (#10596)

This PR cleans up the reportUnknownFlags flag. These changes were
automatically generated by AI and should be reviewed carefully.

Fixes #10595

## 🧹 AI Flag Cleanup Summary
This change removes the `reportUnknownFlags` feature flag and makes its
functionality a permanent part of the application. The "Unknown flags"
feature
is now always enabled.
### 🚮 Removed
- **Flag Definitions**
- Removed `reportUnknownFlags` from `IFlagKey` and `UiFlags` types.
- Removed `reportUnknownFlags` from the experimental flags configuration
in `src/lib/types/experimental.ts`.
- Removed the flag from development and test configurations
(`src/server-dev.ts`, `unknown-flags.e2e.test.ts`).
- **Conditional Logic**
- Removed conditional checks for `reportUnknownFlags` in backend
services
(`UnknownFlagsService`, `ClientMetricsServiceV2`) and API controllers
(`UnknownFlagsController`).
- Removed `useUiFlag('reportUnknownFlags')` and related conditional
rendering from frontend components (`UnknownFlagsTable`,
`FeatureToggleListTable`). The UI elements are now always visible.
- Modified the `useUnknownFlags` hook to always fetch data.
### 🛠 Kept
- **Core Functionality**
- The feature to report and display unknown flags is now always active.
- The "Unknown flags" link is now permanently visible on the feature
flags
overview page.
- Backend logic for processing and storing unknown flags is now always
executed.
### 📝 Why
The `reportUnknownFlags` feature flag was marked as completed with the
feature
being kept. This cleanup removes the flag and its associated conditional
logic,
simplifying the code and making the unknown flags reporting a permanent
feature.

---------

Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
Co-authored-by: Nuno Góis <github@nunogois.com>
This commit is contained in:
unleash-bot[bot] 2025-09-02 14:18:35 +01:00 committed by GitHub
parent 5b7f069705
commit dfa89d7d58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 17 additions and 62 deletions

View File

@ -34,7 +34,6 @@ import { ExportFlags } from './ExportFlags.tsx';
import { createFeatureOverviewCell } from 'component/common/Table/cells/FeatureOverviewCell/FeatureOverviewCell';
import { AvatarCell } from 'component/project/Project/PaginatedProjectFeatureToggles/AvatarCell';
import { StatusCell } from './StatusCell/StatusCell.tsx';
import { useUiFlag } from 'hooks/useUiFlag.ts';
export const featuresPlaceholder = Array(15).fill({
name: 'Name of the feature',
@ -70,7 +69,6 @@ export const FeatureToggleListTable: FC = () => {
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
const isMediumScreen = useMediaQuery(theme.breakpoints.down('lg'));
const [showExportDialog, setShowExportDialog] = useState(false);
const reportUnknownFlagsEnabled = useUiFlag('reportUnknownFlags');
const { setToastApiError } = useToast();
@ -261,16 +259,14 @@ export const FeatureToggleListTable: FC = () => {
title='Flags overview'
actions={
<>
{reportUnknownFlagsEnabled && (
<Link
component={RouterLink}
to='/unknown-flags'
underline='always'
sx={{ marginRight: 2, ...focusable(theme) }}
>
Unknown flags
</Link>
)}
<Link
component={RouterLink}
to='/unknown-flags'
underline='always'
sx={{ marginRight: 2, ...focusable(theme) }}
>
Unknown flags
</Link>
<Link
component={RouterLink}
to='/archive'

View File

@ -13,8 +13,6 @@ import { type UnknownFlag, useUnknownFlags } from './hooks/useUnknownFlags.js';
import theme from 'themes/theme.js';
import { formatDateYMDHMS } from 'utils/formatDate.js';
import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell.js';
import { useUiFlag } from 'hooks/useUiFlag.js';
import NotFound from 'component/common/NotFound/NotFound.js';
import { UnknownFlagsLastEventCell } from './UnknownFlagsLastEventCell.js';
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon.js';
import { UnknownFlagsActionsCell } from './UnknownFlagsActionsCell.js';
@ -41,7 +39,6 @@ const StyledHeader = styled('div')(({ theme }) => ({
export const UnknownFlagsTable = () => {
const { unknownFlags, loading } = useUnknownFlags();
const unknownFlagsEnabled = useUiFlag('reportUnknownFlags');
const [searchValue, setSearchValue] = useState('');
@ -179,8 +176,6 @@ export const UnknownFlagsTable = () => {
useFlexLayout,
);
if (!unknownFlagsEnabled) return <NotFound />;
return (
<PageContent
isLoading={loading}

View File

@ -1,9 +1,8 @@
import { useMemo } from 'react';
import { formatApiPath } from 'utils/formatPath';
import { useUiFlag } from 'hooks/useUiFlag.js';
import { useConditionalSWR } from 'hooks/api/getters/useConditionalSWR/useConditionalSWR.js';
import handleErrorResponses from 'hooks/api/getters/httpErrorResponseHandler';
import type { SWRConfiguration } from 'swr';
import useSWR from 'swr';
type UnknownFlagEnvReport = {
environment: string;
@ -32,11 +31,7 @@ const DEFAULT_DATA: UnknownFlagsResponse = {
};
export const useUnknownFlags = (options?: SWRConfiguration) => {
const reportUnknownFlagsEnabled = useUiFlag('reportUnknownFlags');
const { data, error, mutate } = useConditionalSWR<UnknownFlagsResponse>(
reportUnknownFlagsEnabled,
DEFAULT_DATA,
const { data, error, mutate } = useSWR<UnknownFlagsResponse>(
formatApiPath(ENDPOINT),
fetcher,
options,

View File

@ -86,7 +86,6 @@ export type UiFlags = {
edgeObservability?: boolean;
customMetrics?: boolean;
impactMetrics?: boolean;
reportUnknownFlags?: boolean;
lifecycleGraphs?: boolean;
addConfiguration?: boolean;
};

View File

@ -137,14 +137,12 @@ export default class ClientMetricsServiceV2 {
);
let unknownToggleNames: string[] = [];
if (this.flagResolver.isEnabled('reportUnknownFlags')) {
try {
unknownToggleNames = toggleNames.filter(
(name) => !existingFlags.includes(name),
);
} catch (e) {
this.logger.error(e);
}
try {
unknownToggleNames = toggleNames.filter(
(name) => !existingFlags.includes(name),
);
} catch (e) {
this.logger.error(e);
}
const validatedToggleNames =

View File

@ -7,19 +7,15 @@ import { createResponseSchema } from '../../../openapi/util/create-response-sche
import Controller from '../../../routes/controller.js';
import type { IAuthRequest } from '../../../routes/unleash-types.js';
import type { OpenApiService } from '../../../services/openapi-service.js';
import type { IFlagResolver } from '../../../types/experimental.js';
import type { IUnleashConfig } from '../../../types/option.js';
import { NONE } from '../../../types/permissions.js';
import { serializeDates } from '../../../types/serialize-dates.js';
import type { IUnleashServices } from '../../../services/index.js';
import type { UnknownFlagsService } from './unknown-flags-service.js';
import { NotFoundError } from '../../../error/index.js';
export default class UnknownFlagsController extends Controller {
private unknownFlagsService: UnknownFlagsService;
private flagResolver: IFlagResolver;
private openApiService: OpenApiService;
constructor(
@ -31,7 +27,6 @@ export default class UnknownFlagsController extends Controller {
) {
super(config);
this.unknownFlagsService = unknownFlagsService;
this.flagResolver = config.flagResolver;
this.openApiService = openApiService;
this.route({
@ -58,9 +53,6 @@ export default class UnknownFlagsController extends Controller {
_: IAuthRequest,
res: Response<UnknownFlagsResponseSchema>,
): Promise<void> {
if (!this.flagResolver.isEnabled('reportUnknownFlags')) {
throw new NotFoundError();
}
const unknownFlags = await this.unknownFlagsService.getAll({
limit: 1000,
orderBy: [

View File

@ -1,6 +1,5 @@
import type { Logger } from '../../../logger.js';
import type {
IFlagResolver,
IUnknownFlagsStore,
IUnleashConfig,
} from '../../../types/index.js';
@ -14,8 +13,6 @@ import type {
export class UnknownFlagsService {
private logger: Logger;
private flagResolver: IFlagResolver;
private unknownFlagsStore: IUnknownFlagsStore;
private unknownFlagsCache: Map<string, UnknownFlagReport>;
@ -25,7 +22,6 @@ export class UnknownFlagsService {
config: IUnleashConfig,
) {
this.unknownFlagsStore = unknownFlagsStore;
this.flagResolver = config.flagResolver;
this.logger = config.getLogger(
'/features/metrics/unknown-flags/unknown-flags-service.ts',
);
@ -37,7 +33,6 @@ export class UnknownFlagsService {
}
register(unknownFlags: UnknownFlagReport[]) {
if (!this.flagResolver.isEnabled('reportUnknownFlags')) return;
for (const flag of unknownFlags) {
const key = this.getKey(flag);
this.unknownFlagsCache.set(key, flag);
@ -45,7 +40,6 @@ export class UnknownFlagsService {
}
async flush(): Promise<void> {
if (!this.flagResolver.isEnabled('reportUnknownFlags')) return;
if (this.unknownFlagsCache.size === 0) return;
const cached = Array.from(this.unknownFlagsCache.values());
@ -57,12 +51,10 @@ export class UnknownFlagsService {
}
async getAll(queryParams?: QueryParams): Promise<UnknownFlag[]> {
if (!this.flagResolver.isEnabled('reportUnknownFlags')) return [];
return this.unknownFlagsStore.getAll(queryParams);
}
async clear(hoursAgo: number) {
if (!this.flagResolver.isEnabled('reportUnknownFlags')) return;
return this.unknownFlagsStore.clear(hoursAgo);
}
}

View File

@ -48,13 +48,7 @@ let services: IUnleashServices;
let destroy: () => Promise<void>;
beforeAll(async () => {
const setup = await getSetup({
experimental: {
flags: {
reportUnknownFlags: true,
},
},
});
const setup = await getSetup();
request = setup.request;
stores = setup.stores;
destroy = setup.destroy;

View File

@ -52,7 +52,6 @@ export type IFlagKey =
| 'consumptionModel'
| 'consumptionModelUI'
| 'edgeObservability'
| 'reportUnknownFlags'
| 'customMetrics'
| 'impactMetrics'
| 'lifecycleGraphs'
@ -247,10 +246,6 @@ const flags: IFlags = {
process.env.EXPERIMENTAL_EDGE_OBSERVABILITY,
false,
),
reportUnknownFlags: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_REPORT_UNKNOWN_FLAGS,
false,
),
impactMetrics: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_IMPACT_METRICS,
false,

View File

@ -50,7 +50,6 @@ process.nextTick(async () => {
deltaApi: true,
uniqueSdkTracking: true,
strictSchemaValidation: true,
reportUnknownFlags: true,
customMetrics: true,
impactMetrics: true,
lifecycleGraphs: true,