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:
parent
5b7f069705
commit
dfa89d7d58
@ -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'
|
||||
|
@ -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}
|
||||
|
@ -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,
|
||||
|
@ -86,7 +86,6 @@ export type UiFlags = {
|
||||
edgeObservability?: boolean;
|
||||
customMetrics?: boolean;
|
||||
impactMetrics?: boolean;
|
||||
reportUnknownFlags?: boolean;
|
||||
lifecycleGraphs?: boolean;
|
||||
addConfiguration?: boolean;
|
||||
};
|
||||
|
@ -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 =
|
||||
|
@ -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: [
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -50,7 +50,6 @@ process.nextTick(async () => {
|
||||
deltaApi: true,
|
||||
uniqueSdkTracking: true,
|
||||
strictSchemaValidation: true,
|
||||
reportUnknownFlags: true,
|
||||
customMetrics: true,
|
||||
impactMetrics: true,
|
||||
lifecycleGraphs: true,
|
||||
|
Loading…
Reference in New Issue
Block a user