mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-27 13:49:10 +02:00
feat: walking skeleton of the advanced playground (#3949)
This commit is contained in:
parent
cf69136789
commit
7b8b6bceaf
@ -53,6 +53,7 @@ export interface IFlags {
|
|||||||
disableBulkToggle?: boolean;
|
disableBulkToggle?: boolean;
|
||||||
segmentContextFieldUsage?: boolean;
|
segmentContextFieldUsage?: boolean;
|
||||||
disableNotifications?: boolean;
|
disableNotifications?: boolean;
|
||||||
|
advancedPlayground?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVersionInfo {
|
export interface IVersionInfo {
|
||||||
|
@ -67,6 +67,7 @@ exports[`should create default config 1`] = `
|
|||||||
"isEnabled": [Function],
|
"isEnabled": [Function],
|
||||||
},
|
},
|
||||||
"flags": {
|
"flags": {
|
||||||
|
"advancedPlayground": false,
|
||||||
"anonymiseEventLog": false,
|
"anonymiseEventLog": false,
|
||||||
"caseInsensitiveInOperators": false,
|
"caseInsensitiveInOperators": false,
|
||||||
"cleanClientApi": false,
|
"cleanClientApi": false,
|
||||||
@ -99,6 +100,7 @@ exports[`should create default config 1`] = `
|
|||||||
},
|
},
|
||||||
"flagResolver": FlagResolver {
|
"flagResolver": FlagResolver {
|
||||||
"experiments": {
|
"experiments": {
|
||||||
|
"advancedPlayground": false,
|
||||||
"anonymiseEventLog": false,
|
"anonymiseEventLog": false,
|
||||||
"caseInsensitiveInOperators": false,
|
"caseInsensitiveInOperators": false,
|
||||||
"cleanClientApi": false,
|
"cleanClientApi": false,
|
||||||
|
142
src/lib/features/playground/hardcodedReponse.ts
Normal file
142
src/lib/features/playground/hardcodedReponse.ts
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
const sharedDetails = {
|
||||||
|
isEnabled: true,
|
||||||
|
isEnabledInCurrentEnvironment: true,
|
||||||
|
strategies: {
|
||||||
|
result: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'flexibleRollout',
|
||||||
|
id: '9422b4bb-5f8a-4df5-863a-c2a4c4d83af7',
|
||||||
|
disabled: false,
|
||||||
|
parameters: {
|
||||||
|
groupId: 'test',
|
||||||
|
rollout: '100',
|
||||||
|
stickiness: 'default',
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
enabled: true,
|
||||||
|
evaluationStatus: 'complete',
|
||||||
|
},
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
inverted: false,
|
||||||
|
values: ['2', '4', '6', '8', '10'],
|
||||||
|
operator: 'IN',
|
||||||
|
contextName: 'userId',
|
||||||
|
caseInsensitive: false,
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
segments: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
variant: {
|
||||||
|
name: 'a',
|
||||||
|
payload: {
|
||||||
|
type: 'string',
|
||||||
|
value: 'a',
|
||||||
|
},
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
name: 'a',
|
||||||
|
weight: 334,
|
||||||
|
payload: {
|
||||||
|
type: 'string',
|
||||||
|
value: 'a',
|
||||||
|
},
|
||||||
|
overrides: [],
|
||||||
|
stickiness: 'default',
|
||||||
|
weightType: 'variable',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'b',
|
||||||
|
weight: 333,
|
||||||
|
payload: {
|
||||||
|
type: 'string',
|
||||||
|
value: 'b',
|
||||||
|
},
|
||||||
|
overrides: [],
|
||||||
|
stickiness: 'default',
|
||||||
|
weightType: 'variable',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'c',
|
||||||
|
weight: 333,
|
||||||
|
payload: {
|
||||||
|
type: 'string',
|
||||||
|
value: 'c',
|
||||||
|
},
|
||||||
|
overrides: [],
|
||||||
|
stickiness: 'default',
|
||||||
|
weightType: 'variable',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const sharedEnv = [
|
||||||
|
{
|
||||||
|
...sharedDetails,
|
||||||
|
context: {
|
||||||
|
appName: 'playground',
|
||||||
|
userId: '1',
|
||||||
|
channel: 'web',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...sharedDetails,
|
||||||
|
context: {
|
||||||
|
appName: 'playground',
|
||||||
|
userId: '2',
|
||||||
|
channel: 'web',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...sharedDetails,
|
||||||
|
context: {
|
||||||
|
appName: 'playground',
|
||||||
|
userId: '1',
|
||||||
|
channel: 'mobile',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...sharedDetails,
|
||||||
|
context: {
|
||||||
|
appName: 'playground',
|
||||||
|
userId: '2',
|
||||||
|
channel: 'mobile',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
export const fixedAdvancedPlaygroundResponse = {
|
||||||
|
input: {
|
||||||
|
environments: ['development', 'production'],
|
||||||
|
projects: ['default'],
|
||||||
|
context: {
|
||||||
|
appName: 'playground',
|
||||||
|
userId: '1,2',
|
||||||
|
channel: 'web,mobile',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
environments: {
|
||||||
|
development: sharedEnv,
|
||||||
|
production: sharedEnv,
|
||||||
|
},
|
||||||
|
|
||||||
|
projectId: 'default',
|
||||||
|
name: 'featureA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
environments: {
|
||||||
|
development: sharedEnv,
|
||||||
|
production: sharedEnv,
|
||||||
|
},
|
||||||
|
|
||||||
|
projectId: 'default',
|
||||||
|
name: 'featureB',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
@ -14,12 +14,16 @@ import {
|
|||||||
} from '../../openapi/spec/playground-response-schema';
|
} from '../../openapi/spec/playground-response-schema';
|
||||||
import { PlaygroundRequestSchema } from '../../openapi/spec/playground-request-schema';
|
import { PlaygroundRequestSchema } from '../../openapi/spec/playground-request-schema';
|
||||||
import { PlaygroundService } from './playground-service';
|
import { PlaygroundService } from './playground-service';
|
||||||
|
import { fixedAdvancedPlaygroundResponse } from './hardcodedReponse';
|
||||||
|
import { IFlagResolver } from '../../types';
|
||||||
|
|
||||||
export default class PlaygroundController extends Controller {
|
export default class PlaygroundController extends Controller {
|
||||||
private openApiService: OpenApiService;
|
private openApiService: OpenApiService;
|
||||||
|
|
||||||
private playgroundService: PlaygroundService;
|
private playgroundService: PlaygroundService;
|
||||||
|
|
||||||
|
private flagResolver: IFlagResolver;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
{
|
{
|
||||||
@ -30,6 +34,7 @@ export default class PlaygroundController extends Controller {
|
|||||||
super(config);
|
super(config);
|
||||||
this.openApiService = openApiService;
|
this.openApiService = openApiService;
|
||||||
this.playgroundService = playgroundService;
|
this.playgroundService = playgroundService;
|
||||||
|
this.flagResolver = config.flagResolver;
|
||||||
|
|
||||||
this.route({
|
this.route({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -49,6 +54,14 @@ export default class PlaygroundController extends Controller {
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.route({
|
||||||
|
method: 'post',
|
||||||
|
path: '/advanced',
|
||||||
|
handler: this.evaluateAdvancedContext,
|
||||||
|
permission: NONE,
|
||||||
|
middleware: [],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async evaluateContext(
|
async evaluateContext(
|
||||||
@ -58,7 +71,7 @@ export default class PlaygroundController extends Controller {
|
|||||||
const response = {
|
const response = {
|
||||||
input: req.body,
|
input: req.body,
|
||||||
features: await this.playgroundService.evaluateQuery(
|
features: await this.playgroundService.evaluateQuery(
|
||||||
req.body.projects,
|
req.body.projects || '*',
|
||||||
req.body.environment,
|
req.body.environment,
|
||||||
req.body.context,
|
req.body.context,
|
||||||
),
|
),
|
||||||
@ -71,4 +84,15 @@ export default class PlaygroundController extends Controller {
|
|||||||
response,
|
response,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async evaluateAdvancedContext(
|
||||||
|
req: Request<any, any, any>,
|
||||||
|
res: Response<any>,
|
||||||
|
): Promise<void> {
|
||||||
|
if (this.flagResolver.isEnabled('advancedPlayground')) {
|
||||||
|
res.json(fixedAdvancedPlaygroundResponse);
|
||||||
|
} else {
|
||||||
|
res.status(409).end();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@ export type IFlagKey =
|
|||||||
| 'variantMetrics'
|
| 'variantMetrics'
|
||||||
| 'disableBulkToggle'
|
| 'disableBulkToggle'
|
||||||
| 'segmentContextFieldUsage'
|
| 'segmentContextFieldUsage'
|
||||||
| 'disableNotifications';
|
| 'disableNotifications'
|
||||||
|
| 'advancedPlayground';
|
||||||
|
|
||||||
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
|
||||||
|
|
||||||
@ -108,6 +109,10 @@ const flags: IFlags = {
|
|||||||
process.env.DISABLE_NOTIFICATIONS,
|
process.env.DISABLE_NOTIFICATIONS,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
advancedPlayground: parseEnvVarBoolean(
|
||||||
|
process.env.ADVANCED_PLAYGROUND,
|
||||||
|
false,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultExperimentalOptions: IExperimentalOptions = {
|
export const defaultExperimentalOptions: IExperimentalOptions = {
|
||||||
|
@ -41,6 +41,7 @@ process.nextTick(async () => {
|
|||||||
variantMetrics: true,
|
variantMetrics: true,
|
||||||
strategyImprovements: true,
|
strategyImprovements: true,
|
||||||
segmentContextFieldUsage: true,
|
segmentContextFieldUsage: true,
|
||||||
|
advancedPlayground: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
authentication: {
|
authentication: {
|
||||||
|
Loading…
Reference in New Issue
Block a user