mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-31 00:16:47 +01:00
feat: project applications e2e PoC (#6189)
1. Adding store layer 2. Updating schemas 3. Refactoring project files that I touched into feature oriented architecture Next steps E2E tests.
This commit is contained in:
parent
b48d25a226
commit
5a75093cbc
@ -9,7 +9,7 @@ import ClientApplicationsStore from './client-applications-store';
|
||||
import ContextFieldStore from './context-field-store';
|
||||
import SettingStore from './setting-store';
|
||||
import UserStore from './user-store';
|
||||
import ProjectStore from './project-store';
|
||||
import ProjectStore from '../features/project/project-store';
|
||||
import TagStore from './tag-store';
|
||||
import TagTypeStore from '../features/tag-type/tag-type-store';
|
||||
import AddonStore from './addon-store';
|
||||
|
@ -3,7 +3,7 @@ import { Logger, LogProvider } from '../logger';
|
||||
import metricsHelper from '../util/metrics-helper';
|
||||
import { DB_TIME } from '../metric-events';
|
||||
import EventEmitter from 'events';
|
||||
import { IProjectStats } from '../services/project-service';
|
||||
import { IProjectStats } from '../features/project/project-service';
|
||||
import {
|
||||
ICreateEnabledDates,
|
||||
IProjectStatsStore,
|
||||
|
@ -5,7 +5,7 @@ import { ImportTogglesStore } from './import-toggles-store';
|
||||
import FeatureToggleStore from '../feature-toggle/feature-toggle-store';
|
||||
import TagStore from '../../db/tag-store';
|
||||
import TagTypeStore from '../tag-type/tag-type-store';
|
||||
import ProjectStore from '../../db/project-store';
|
||||
import ProjectStore from '../project/project-store';
|
||||
import FeatureTagStore from '../../db/feature-tag-store';
|
||||
import StrategyStore from '../../db/strategy-store';
|
||||
import ContextFieldStore from '../../db/context-field-store';
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
import FeatureStrategiesStore from './feature-toggle-strategies-store';
|
||||
import FeatureToggleStore from './feature-toggle-store';
|
||||
import FeatureToggleClientStore from '../client-feature-toggles/client-feature-toggle-store';
|
||||
import ProjectStore from '../../db/project-store';
|
||||
import ProjectStore from '../project/project-store';
|
||||
import { FeatureEnvironmentStore } from '../../db/feature-environment-store';
|
||||
import ContextFieldStore from '../../db/context-field-store';
|
||||
import GroupStore from '../../db/group-store';
|
||||
|
@ -11,7 +11,7 @@ import { IUnleashConfig } from '../../types';
|
||||
import { Db } from '../../db/db';
|
||||
import FeatureToggleStore from '../feature-toggle/feature-toggle-store';
|
||||
import UserStore from '../../db/user-store';
|
||||
import ProjectStore from '../../db/project-store';
|
||||
import ProjectStore from '../project/project-store';
|
||||
import EnvironmentStore from '../project-environments/environment-store';
|
||||
import StrategyStore from '../../db/strategy-store';
|
||||
import ContextFieldStore from '../../db/context-field-store';
|
||||
|
@ -11,7 +11,7 @@ import { IContextFieldStore } from '../../types/stores/context-field-store';
|
||||
import { IEnvironmentStore } from '../project-environments/environment-store-type';
|
||||
import { IFeatureToggleStore } from '../feature-toggle/types/feature-toggle-store-type';
|
||||
import { IGroupStore } from '../../types/stores/group-store';
|
||||
import { IProjectStore } from '../../types/stores/project-store';
|
||||
import { IProjectStore } from '../../features/project/project-store-type';
|
||||
import { IStrategyStore } from '../../types/stores/strategy-store';
|
||||
import { IUserStore } from '../../types/stores/user-store';
|
||||
import { ISegmentStore } from '../../types/stores/segment-store';
|
||||
@ -25,7 +25,7 @@ import {
|
||||
} from '../../types';
|
||||
import { CUSTOM_ROOT_ROLE_TYPE } from '../../util';
|
||||
import { type GetActiveUsers } from './getActiveUsers';
|
||||
import { ProjectModeCount } from '../../db/project-store';
|
||||
import { ProjectModeCount } from '../project/project-store';
|
||||
import { GetProductionChanges } from './getProductionChanges';
|
||||
|
||||
export type TimeRange = 'allTime' | '30d' | '7d';
|
||||
|
@ -7,7 +7,7 @@ import EnvironmentService from './environment-service';
|
||||
import EnvironmentStore from './environment-store';
|
||||
import FeatureStrategiesStore from '../feature-toggle/feature-toggle-strategies-store';
|
||||
import { FeatureEnvironmentStore } from '../../db/feature-environment-store';
|
||||
import ProjectStore from '../../db/project-store';
|
||||
import ProjectStore from '../project/project-store';
|
||||
import FakeFeatureEnvironmentStore from '../../../test/fixtures/fake-feature-environment-store';
|
||||
import FakeProjectStore from '../../../test/fixtures/fake-project-store';
|
||||
import FakeFeatureStrategiesStore from '../feature-toggle/fakes/fake-feature-strategies-store';
|
||||
|
@ -17,7 +17,7 @@ import { BadDataError, UNIQUE_CONSTRAINT_VIOLATION } from '../../error';
|
||||
import NameExistsError from '../../error/name-exists-error';
|
||||
import { sortOrderSchema } from '../../services/state-schema';
|
||||
import NotFoundError from '../../error/notfound-error';
|
||||
import { IProjectStore } from '../../types/stores/project-store';
|
||||
import { IProjectStore } from '../../features/project/project-store-type';
|
||||
import MinimumOneEnvironmentError from '../../error/minimum-one-environment-error';
|
||||
import { IFlagResolver } from '../../types/experimental';
|
||||
import { CreateFeatureStrategySchema } from '../../openapi';
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
} from '../../services';
|
||||
import FakeGroupStore from '../../../test/fixtures/fake-group-store';
|
||||
import FakeEventStore from '../../../test/fixtures/fake-event-store';
|
||||
import ProjectStore from '../../db/project-store';
|
||||
import ProjectStore from './project-store';
|
||||
import FeatureToggleStore from '../feature-toggle/feature-toggle-store';
|
||||
import { FeatureEnvironmentStore } from '../../db/feature-environment-store';
|
||||
import ProjectStatsStore from '../../db/project-stats-store';
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
import ProjectFeaturesController from '../feature-toggle/feature-toggle-controller';
|
||||
import EnvironmentsController from '../project-environments/environments';
|
||||
import ProjectHealthReport from '../../routes/admin-api/project/health-report';
|
||||
import ProjectService from '../../services/project-service';
|
||||
import ProjectService from './project-service';
|
||||
import VariantsController from '../../routes/admin-api/project/variants';
|
||||
import {
|
||||
createResponseSchema,
|
||||
@ -267,7 +267,7 @@ export default class ProjectController extends Controller {
|
||||
200,
|
||||
res,
|
||||
projectApplicationsSchema.$id,
|
||||
applications,
|
||||
serializeDates(applications),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { subDays } from 'date-fns';
|
||||
import { ValidationError } from 'joi';
|
||||
import { IUser } from '../types/user';
|
||||
import { AccessService, AccessWithRoles } from './access-service';
|
||||
import NameExistsError from '../error/name-exists-error';
|
||||
import InvalidOperationError from '../error/invalid-operation-error';
|
||||
import { nameType } from '../routes/util';
|
||||
import { projectSchema } from './project-schema';
|
||||
import NotFoundError from '../error/notfound-error';
|
||||
import { IUser } from '../../types/user';
|
||||
import { AccessService, AccessWithRoles } from '../../services/access-service';
|
||||
import NameExistsError from '../../error/name-exists-error';
|
||||
import InvalidOperationError from '../../error/invalid-operation-error';
|
||||
import { nameType } from '../../routes/util';
|
||||
import { projectSchema } from '../../services/project-schema';
|
||||
import NotFoundError from '../../error/notfound-error';
|
||||
import {
|
||||
DEFAULT_PROJECT,
|
||||
FeatureToggle,
|
||||
@ -42,34 +42,32 @@ import {
|
||||
IProjectUpdate,
|
||||
IProjectHealth,
|
||||
SYSTEM_USER,
|
||||
} from '../types';
|
||||
import {
|
||||
IProjectQuery,
|
||||
IProjectEnterpriseSettingsUpdate,
|
||||
IProjectApplication,
|
||||
IProjectStore,
|
||||
} from '../types/stores/project-store';
|
||||
} from '../../types';
|
||||
import {
|
||||
IProjectAccessModel,
|
||||
IRoleDescriptor,
|
||||
} from '../types/stores/access-store';
|
||||
import FeatureToggleService from '../features/feature-toggle/feature-toggle-service';
|
||||
import IncompatibleProjectError from '../error/incompatible-project-error';
|
||||
import ProjectWithoutOwnerError from '../error/project-without-owner-error';
|
||||
import { arraysHaveSameItems } from '../util';
|
||||
import { GroupService } from './group-service';
|
||||
import { IGroupRole } from '../types/group';
|
||||
import { FavoritesService } from './favorites-service';
|
||||
import { calculateAverageTimeToProd } from '../features/feature-toggle/time-to-production/time-to-production';
|
||||
import { IProjectStatsStore } from '../types/stores/project-stats-store-type';
|
||||
import { uniqueByKey } from '../util/unique';
|
||||
import { BadDataError, PermissionError } from '../error';
|
||||
} from '../../types/stores/access-store';
|
||||
import FeatureToggleService from '../feature-toggle/feature-toggle-service';
|
||||
import IncompatibleProjectError from '../../error/incompatible-project-error';
|
||||
import ProjectWithoutOwnerError from '../../error/project-without-owner-error';
|
||||
import { arraysHaveSameItems } from '../../util';
|
||||
import { GroupService } from '../../services/group-service';
|
||||
import { IGroupRole } from '../../types/group';
|
||||
import { FavoritesService } from '../../services/favorites-service';
|
||||
import { calculateAverageTimeToProd } from '../feature-toggle/time-to-production/time-to-production';
|
||||
import { IProjectStatsStore } from '../../types/stores/project-stats-store-type';
|
||||
import { uniqueByKey } from '../../util/unique';
|
||||
import { BadDataError, PermissionError } from '../../error';
|
||||
import { ProjectDoraMetricsSchema } from '../../openapi';
|
||||
import { checkFeatureNamingData } from '../feature-naming-pattern/feature-naming-validation';
|
||||
import { IPrivateProjectChecker } from '../private-project/privateProjectCheckerType';
|
||||
import EventService from '../events/event-service';
|
||||
import {
|
||||
ProjectDoraMetricsSchema,
|
||||
ProjectApplicationsSchema,
|
||||
} from '../openapi';
|
||||
import { checkFeatureNamingData } from '../features/feature-naming-pattern/feature-naming-validation';
|
||||
import { IPrivateProjectChecker } from '../features/private-project/privateProjectCheckerType';
|
||||
import EventService from '../features/events/event-service';
|
||||
IProjectEnterpriseSettingsUpdate,
|
||||
IProjectQuery,
|
||||
} from './project-store-type';
|
||||
|
||||
const getCreatedBy = (user: IUser) => user.email || user.username || 'unknown';
|
||||
|
||||
@ -903,10 +901,10 @@ export default class ProjectService {
|
||||
};
|
||||
}
|
||||
|
||||
async getApplications(
|
||||
projectId: string,
|
||||
): Promise<ProjectApplicationsSchema> {
|
||||
return [];
|
||||
async getApplications(projectId: string): Promise<IProjectApplication[]> {
|
||||
const applications =
|
||||
await this.projectStore.getApplicationsByProject(projectId);
|
||||
return applications;
|
||||
}
|
||||
|
||||
async changeRole(
|
@ -2,15 +2,16 @@ import {
|
||||
IEnvironmentProjectLink,
|
||||
IProjectMembersCount,
|
||||
ProjectModeCount,
|
||||
} from '../../db/project-store';
|
||||
} from './project-store';
|
||||
import {
|
||||
IEnvironment,
|
||||
IFeatureNaming,
|
||||
IProject,
|
||||
IProjectApplication,
|
||||
IProjectWithCount,
|
||||
ProjectMode,
|
||||
} from '../model';
|
||||
import { Store } from './store';
|
||||
} from '../../types/model';
|
||||
import { Store } from '../../types/stores/store';
|
||||
import { CreateFeatureStrategySchema } from '../../openapi';
|
||||
|
||||
export interface IProjectInsert {
|
||||
@ -121,4 +122,5 @@ export interface IProjectStore extends Store<IProject, string> {
|
||||
isFeatureLimitReached(id: string): Promise<boolean>;
|
||||
|
||||
getProjectModeCounts(): Promise<ProjectModeCount[]>;
|
||||
getApplicationsByProject(projectId: string): Promise<IProjectApplication[]>;
|
||||
}
|
@ -1,15 +1,17 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Logger, LogProvider } from '../logger';
|
||||
import { Logger, LogProvider } from '../../logger';
|
||||
|
||||
import NotFoundError from '../error/notfound-error';
|
||||
import NotFoundError from '../../error/notfound-error';
|
||||
import {
|
||||
IEnvironment,
|
||||
IFlagResolver,
|
||||
IProject,
|
||||
IProjectApplication,
|
||||
IProjectApplicationSdk,
|
||||
IProjectUpdate,
|
||||
IProjectWithCount,
|
||||
ProjectMode,
|
||||
} from '../types';
|
||||
} from '../../types';
|
||||
import {
|
||||
IProjectHealthUpdate,
|
||||
IProjectInsert,
|
||||
@ -18,14 +20,14 @@ import {
|
||||
IProjectEnterpriseSettingsUpdate,
|
||||
IProjectStore,
|
||||
ProjectEnvironment,
|
||||
} from '../types/stores/project-store';
|
||||
import { DEFAULT_ENV } from '../util';
|
||||
import metricsHelper from '../util/metrics-helper';
|
||||
import { DB_TIME } from '../metric-events';
|
||||
} from '../../features/project/project-store-type';
|
||||
import { DEFAULT_ENV } from '../../util';
|
||||
import metricsHelper from '../../util/metrics-helper';
|
||||
import { DB_TIME } from '../../metric-events';
|
||||
import EventEmitter from 'events';
|
||||
import { Db } from './db';
|
||||
import { Db } from '../../db/db';
|
||||
import Raw = Knex.Raw;
|
||||
import { CreateFeatureStrategySchema } from '../openapi';
|
||||
import { CreateFeatureStrategySchema } from '../../openapi';
|
||||
|
||||
const COLUMNS = [
|
||||
'id',
|
||||
@ -110,11 +112,12 @@ class ProjectStore implements IProjectStore {
|
||||
async isFeatureLimitReached(id: string): Promise<boolean> {
|
||||
const result = await this.db.raw(
|
||||
`SELECT EXISTS(SELECT 1
|
||||
FROM project_settings
|
||||
LEFT JOIN features ON project_settings.project = features.project
|
||||
WHERE project_settings.project = ? AND features.archived_at IS NULL
|
||||
GROUP BY project_settings.project
|
||||
HAVING project_settings.feature_limit <= COUNT(features.project)) AS present`,
|
||||
FROM project_settings
|
||||
LEFT JOIN features ON project_settings.project = features.project
|
||||
WHERE project_settings.project = ?
|
||||
AND features.archived_at IS NULL
|
||||
GROUP BY project_settings.project
|
||||
HAVING project_settings.feature_limit <= COUNT(features.project)) AS present`,
|
||||
[id],
|
||||
);
|
||||
const { present } = result.rows[0];
|
||||
@ -254,9 +257,10 @@ class ProjectStore implements IProjectStore {
|
||||
}
|
||||
|
||||
async updateHealth(healthUpdate: IProjectHealthUpdate): Promise<void> {
|
||||
await this.db(TABLE)
|
||||
.where({ id: healthUpdate.id })
|
||||
.update({ health: healthUpdate.health, updated_at: new Date() });
|
||||
await this.db(TABLE).where({ id: healthUpdate.id }).update({
|
||||
health: healthUpdate.health,
|
||||
updated_at: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
async create(
|
||||
@ -575,13 +579,45 @@ class ProjectStore implements IProjectStore {
|
||||
return Number(members.count);
|
||||
}
|
||||
|
||||
async getApplicationsByProject(
|
||||
projectId: string,
|
||||
): Promise<IProjectApplication[]> {
|
||||
const query = this.db
|
||||
.with('applications', (qb) => {
|
||||
qb.select('project', 'app_name', 'environment')
|
||||
.distinct()
|
||||
.from('client_metrics_env as cme')
|
||||
.leftJoin('features as f', 'cme.feature_name', 'f.name')
|
||||
.where('project', projectId);
|
||||
})
|
||||
.select(
|
||||
'a.app_name',
|
||||
'a.environment',
|
||||
'ci.instance_id',
|
||||
'ci.sdk_version',
|
||||
)
|
||||
.from('applications as a')
|
||||
.leftJoin('client_instances as ci', function () {
|
||||
this.on('ci.app_name', 'a.app_name').andOn(
|
||||
'ci.environment',
|
||||
'a.environment',
|
||||
);
|
||||
});
|
||||
const rows = await query;
|
||||
const applications = this.getAggregatedApplicationsData(rows);
|
||||
return applications;
|
||||
}
|
||||
|
||||
async getDefaultStrategy(
|
||||
projectId: string,
|
||||
environment: string,
|
||||
): Promise<CreateFeatureStrategySchema | null> {
|
||||
const rows = await this.db(PROJECT_ENVIRONMENTS)
|
||||
.select('default_strategy')
|
||||
.where({ project_id: projectId, environment_name: environment });
|
||||
.where({
|
||||
project_id: projectId,
|
||||
environment_name: environment,
|
||||
});
|
||||
|
||||
return rows.length > 0 ? rows[0].default_strategy : null;
|
||||
}
|
||||
@ -595,7 +631,10 @@ class ProjectStore implements IProjectStore {
|
||||
.update({
|
||||
default_strategy: strategy,
|
||||
})
|
||||
.where({ project_id: projectId, environment_name: environment })
|
||||
.where({
|
||||
project_id: projectId,
|
||||
environment_name: environment,
|
||||
})
|
||||
.returning('default_strategy');
|
||||
|
||||
return rows[0].default_strategy;
|
||||
@ -680,6 +719,43 @@ class ProjectStore implements IProjectStore {
|
||||
: row.default_strategy,
|
||||
};
|
||||
}
|
||||
|
||||
getAggregatedApplicationsData(rows): IProjectApplication[] {
|
||||
const entriesMap: Map<string, IProjectApplication> = new Map();
|
||||
const orderedEntries: IProjectApplication[] = [];
|
||||
|
||||
const getSdk = (sdkParts: string[]): IProjectApplicationSdk => {
|
||||
return {
|
||||
name: sdkParts[0],
|
||||
versions: [sdkParts[1]],
|
||||
};
|
||||
};
|
||||
|
||||
rows.forEach((row) => {
|
||||
let entry = entriesMap.get(row.app_name);
|
||||
const sdkParts = row.sdk_version.split(':');
|
||||
|
||||
if (!entry) {
|
||||
entry = {
|
||||
name: row.app_name,
|
||||
environments: [row.environment],
|
||||
instances: [row.instance_id],
|
||||
sdks: [getSdk(sdkParts)],
|
||||
};
|
||||
entriesMap.set(row.feature_name, entry);
|
||||
orderedEntries.push(entry);
|
||||
}
|
||||
|
||||
const sdk = entry.sdks.find((sdk) => sdk.name === sdkParts[0]);
|
||||
if (!sdk) {
|
||||
entry.sdks.push(getSdk(sdkParts));
|
||||
} else {
|
||||
sdk.versions.push(sdkParts[1]);
|
||||
}
|
||||
});
|
||||
|
||||
return orderedEntries;
|
||||
}
|
||||
}
|
||||
|
||||
export default ProjectStore;
|
@ -196,6 +196,7 @@ import { segmentStrategiesSchema } from './spec/segment-strategies-schema';
|
||||
import { featureDependenciesSchema } from './spec/feature-dependencies-schema';
|
||||
import { projectApplicationsSchema } from './spec/project-applications-schema';
|
||||
import { projectApplicationSchema } from './spec/project-application-schema';
|
||||
import { projectApplicationSdkSchema } from './spec/project-application-sdk-schema';
|
||||
|
||||
// Schemas must have an $id property on the form "#/components/schemas/mySchema".
|
||||
export type SchemaId = (typeof schemas)[keyof typeof schemas]['$id'];
|
||||
@ -326,6 +327,7 @@ export const schemas: UnleashSchemas = {
|
||||
playgroundStrategySchema,
|
||||
profileSchema,
|
||||
projectApplicationSchema,
|
||||
projectApplicationSdkSchema,
|
||||
projectApplicationsSchema,
|
||||
projectEnvironmentSchema,
|
||||
projectSchema,
|
||||
|
@ -1,34 +1,45 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
import { projectApplicationSdkSchema } from './project-application-sdk-schema';
|
||||
|
||||
export const projectApplicationSchema = {
|
||||
$id: '#/components/schemas/projectApplicationSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['appName', 'instanceId', 'sdkVersion', 'environment'],
|
||||
required: ['name', 'environments', 'instances', 'sdks'],
|
||||
description: 'A project application instance.',
|
||||
properties: {
|
||||
appName: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description:
|
||||
'Name of the application that is using the SDK. This is the same as the appName in the SDK configuration.',
|
||||
},
|
||||
instanceId: {
|
||||
type: 'string',
|
||||
environments: {
|
||||
description:
|
||||
'The unique identifier of the application instance. This is the same as the instanceId in the SDK configuration',
|
||||
'The environments that the application is using. This is the same as the environment in the SDK configuration.',
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
example: ['development', 'production'],
|
||||
},
|
||||
sdkVersion: {
|
||||
type: 'string',
|
||||
instances: {
|
||||
description:
|
||||
'The version of the SDK that is being used by the application',
|
||||
'The instances of the application that are using the SDK.',
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
example: ['prod-b4ca', 'prod-ac8a'],
|
||||
},
|
||||
environment: {
|
||||
type: 'string',
|
||||
description:
|
||||
'The environment that the application is running in. This is coming from token configured in the SDK configuration.',
|
||||
sdks: {
|
||||
type: 'array',
|
||||
description: 'The SDKs that the application is using.',
|
||||
items: {
|
||||
$ref: '#/components/schemas/projectApplicationSdkSchema',
|
||||
},
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
components: { projectApplicationSdkSchema },
|
||||
} as const;
|
||||
|
||||
export type ProjectApplicationSchema = FromSchema<
|
||||
|
31
src/lib/openapi/spec/project-application-sdk-schema.ts
Normal file
31
src/lib/openapi/spec/project-application-sdk-schema.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
|
||||
export const projectApplicationSdkSchema = {
|
||||
$id: '#/components/schemas/projectApplicationSdkSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['name', 'versions'],
|
||||
description: 'A project application instance SDK.',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
description:
|
||||
'Name of the SDK package that the application is using.',
|
||||
example: 'unleash-client-node',
|
||||
},
|
||||
versions: {
|
||||
description:
|
||||
'The versions of the SDK that the application is using.',
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
example: ['4.1.1'],
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
} as const;
|
||||
|
||||
export type ProjectApplicationSdkSchema = FromSchema<
|
||||
typeof projectApplicationSdkSchema
|
||||
>;
|
@ -4,10 +4,15 @@ import { ProjectApplicationsSchema } from './project-applications-schema';
|
||||
test('projectApplicationsSchema', () => {
|
||||
const data: ProjectApplicationsSchema = [
|
||||
{
|
||||
appName: 'my-weba-app',
|
||||
instanceId: 'app1:3:4',
|
||||
sdkVersion: '4.1.1',
|
||||
environment: 'production',
|
||||
name: 'my-weba-app',
|
||||
environments: ['development', 'production'],
|
||||
instances: ['instance-414122'],
|
||||
sdks: [
|
||||
{
|
||||
name: 'unleash-client-node',
|
||||
versions: ['4.1.1'],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
import { projectApplicationSchema } from './project-application-schema';
|
||||
import { projectApplicationSdkSchema } from './project-application-sdk-schema';
|
||||
|
||||
export const projectApplicationsSchema = {
|
||||
$id: '#/components/schemas/projectApplicationsSchema',
|
||||
@ -11,6 +12,7 @@ export const projectApplicationsSchema = {
|
||||
components: {
|
||||
schemas: {
|
||||
projectApplicationSchema,
|
||||
projectApplicationSdkSchema,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
@ -23,7 +23,7 @@ import {
|
||||
profileSchema,
|
||||
ProfileSchema,
|
||||
} from '../../../openapi/spec/profile-schema';
|
||||
import ProjectService from '../../../services/project-service';
|
||||
import ProjectService from '../../../features/project/project-service';
|
||||
|
||||
class UserController extends Controller {
|
||||
private accessService: AccessService;
|
||||
|
@ -4,7 +4,7 @@ import {
|
||||
IContextFieldDto,
|
||||
IContextFieldStore,
|
||||
} from '../types/stores/context-field-store';
|
||||
import { IProjectStore } from '../types/stores/project-store';
|
||||
import { IProjectStore } from '../features/project/project-store-type';
|
||||
import { IFeatureStrategiesStore, IUnleashStores } from '../types/stores';
|
||||
import { IUnleashConfig } from '../types/option';
|
||||
import { ContextFieldStrategiesSchema } from '../openapi/spec/context-field-strategies-schema';
|
||||
|
@ -3,7 +3,7 @@ import FeatureTypeService from './feature-type-service';
|
||||
import EventService from '../features/events/event-service';
|
||||
import HealthService from './health-service';
|
||||
|
||||
import ProjectService from './project-service';
|
||||
import ProjectService from '../features/project/project-service';
|
||||
import StateService from './state-service';
|
||||
import ClientInstanceService from '../features/metrics/instance/instance-service';
|
||||
import ClientMetricsServiceV2 from '../features/metrics/client-metrics/metrics-service-v2';
|
||||
|
@ -4,8 +4,8 @@ import { Logger } from '../logger';
|
||||
import type { IProject, IProjectHealthReport } from '../types/model';
|
||||
import type { IFeatureToggleStore } from '../features/feature-toggle/types/feature-toggle-store-type';
|
||||
import type { IFeatureTypeStore } from '../types/stores/feature-type-store';
|
||||
import type { IProjectStore } from '../types/stores/project-store';
|
||||
import ProjectService from './project-service';
|
||||
import type { IProjectStore } from '../features/project/project-store-type';
|
||||
import ProjectService from '../features/project/project-service';
|
||||
import {
|
||||
calculateHealthRating,
|
||||
calculateProjectHealth,
|
||||
|
@ -36,7 +36,7 @@ import {
|
||||
IFeatureTag,
|
||||
IFeatureTagStore,
|
||||
} from '../types/stores/feature-tag-store';
|
||||
import { IProjectStore } from '../types/stores/project-store';
|
||||
import { IProjectStore } from '../features/project/project-store-type';
|
||||
import {
|
||||
ITagType,
|
||||
ITagTypeStore,
|
||||
|
@ -3,9 +3,9 @@ import { LogProvider } from '../logger';
|
||||
import { IRole } from './stores/access-store';
|
||||
import { IUser } from './user';
|
||||
import { ALL_OPERATORS } from '../util';
|
||||
import { IProjectStats } from '../services/project-service';
|
||||
import { IProjectStats } from '../features/project/project-service';
|
||||
import { CreateFeatureStrategySchema } from '../openapi';
|
||||
import { ProjectEnvironment } from './stores/project-store';
|
||||
import { ProjectEnvironment } from '../features/project/project-store-type';
|
||||
|
||||
export type Operator = (typeof ALL_OPERATORS)[number];
|
||||
|
||||
@ -478,6 +478,18 @@ export interface IProject {
|
||||
featureNaming?: IFeatureNaming;
|
||||
}
|
||||
|
||||
export interface IProjectApplication {
|
||||
name: string;
|
||||
environments: string[];
|
||||
instances: string[];
|
||||
sdks: IProjectApplicationSdk[];
|
||||
}
|
||||
|
||||
export interface IProjectApplicationSdk {
|
||||
name: string;
|
||||
versions: string[];
|
||||
}
|
||||
|
||||
// mimics UpdateProjectSchema
|
||||
export interface IProjectUpdate {
|
||||
id: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { AccessService } from '../services/access-service';
|
||||
import AddonService from '../services/addon-service';
|
||||
import ProjectService from '../services/project-service';
|
||||
import ProjectService from '../features/project/project-service';
|
||||
import StateService from '../services/state-service';
|
||||
import StrategyService from '../services/strategy-service';
|
||||
import TagTypeService from '../features/tag-type/tag-type-service';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IProjectStore } from './stores/project-store';
|
||||
import { IProjectStore } from '../features/project/project-store-type';
|
||||
import { IEventStore } from './stores/event-store';
|
||||
import { IFeatureTypeStore } from './stores/feature-type-store';
|
||||
import { IStrategyStore } from './stores/strategy-store';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { DoraFeaturesSchema } from '../../openapi';
|
||||
import { IProjectStats } from '../../services/project-service';
|
||||
import { IProjectStats } from '../../features/project/project-service';
|
||||
|
||||
export interface ICreateEnabledDates {
|
||||
created: Date;
|
||||
|
@ -5,7 +5,7 @@ import { createTestConfig } from '../../config/test-config';
|
||||
import { ApiTokenType, IApiToken } from '../../../lib/types/models/api-token';
|
||||
import { DEFAULT_ENV } from '../../../lib/util/constants';
|
||||
import { addDays, subDays } from 'date-fns';
|
||||
import ProjectService from '../../../lib/services/project-service';
|
||||
import ProjectService from '../../../lib/features/project/project-service';
|
||||
import { createProjectService } from '../../../lib/features';
|
||||
import { EventService } from '../../../lib/services';
|
||||
import { IUnleashStores } from '../../../lib/types';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import dbInit, { ITestDb } from '../helpers/database-init';
|
||||
import getLogger from '../../fixtures/no-logger';
|
||||
import FeatureToggleService from '../../../lib/features/feature-toggle/feature-toggle-service';
|
||||
import ProjectService from '../../../lib/services/project-service';
|
||||
import ProjectService from '../../../lib/features/project/project-service';
|
||||
import { AccessService } from '../../../lib/services/access-service';
|
||||
import { MOVE_FEATURE_TOGGLE } from '../../../lib/types/permissions';
|
||||
import { createTestConfig } from '../../config/test-config';
|
||||
|
@ -1,12 +1,9 @@
|
||||
import {
|
||||
IProjectInsert,
|
||||
IProjectStore,
|
||||
} from '../../../lib/types/stores/project-store';
|
||||
import { IEnvironmentStore } from '../../../lib/features/project-environments/environment-store-type';
|
||||
|
||||
import dbInit, { ITestDb } from '../helpers/database-init';
|
||||
import getLogger from '../../fixtures/no-logger';
|
||||
import { IUnleashStores } from '../../../lib/types';
|
||||
import { IProjectStore, IUnleashStores } from '../../../lib/types';
|
||||
import { IProjectInsert } from '../../../lib/features/project/project-store-type';
|
||||
|
||||
let stores: IUnleashStores;
|
||||
let db: ITestDb;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IProjectStats } from '../../lib/services/project-service';
|
||||
import { IProjectStats } from '../../lib/features/project/project-service';
|
||||
import {
|
||||
ICreateEnabledDates,
|
||||
IProjectStatsStore,
|
||||
|
23
src/test/fixtures/fake-project-store.ts
vendored
23
src/test/fixtures/fake-project-store.ts
vendored
@ -1,17 +1,22 @@
|
||||
import {
|
||||
IProjectHealthUpdate,
|
||||
IProjectInsert,
|
||||
IEnvironment,
|
||||
IProject,
|
||||
IProjectApplication,
|
||||
IProjectStore,
|
||||
ProjectEnvironment,
|
||||
} from '../../lib/types/stores/project-store';
|
||||
import { IEnvironment, IProject, IProjectWithCount } from '../../lib/types';
|
||||
IProjectWithCount,
|
||||
} from '../../lib/types';
|
||||
import NotFoundError from '../../lib/error/notfound-error';
|
||||
import {
|
||||
IEnvironmentProjectLink,
|
||||
IProjectMembersCount,
|
||||
ProjectModeCount,
|
||||
} from '../../lib/db/project-store';
|
||||
} from '../../lib/features/project/project-store';
|
||||
import { CreateFeatureStrategySchema } from '../../lib/openapi';
|
||||
import {
|
||||
IProjectHealthUpdate,
|
||||
IProjectInsert,
|
||||
ProjectEnvironment,
|
||||
} from '../../lib/features/project/project-store-type';
|
||||
|
||||
export default class FakeProjectStore implements IProjectStore {
|
||||
projects: IProject[] = [];
|
||||
@ -202,4 +207,10 @@ export default class FakeProjectStore implements IProjectStore {
|
||||
updateProjectEnterpriseSettings(update: IProjectInsert): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
getApplicationsByProject(
|
||||
projectId: string,
|
||||
): Promise<IProjectApplication[]> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user