mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	1-3085: count flags in each stage (#8699)
This PR adds the next query to the lifecycle read model: how many flags are in each stage.
This commit is contained in:
		
							parent
							
								
									0a250a7526
								
							
						
					
					
						commit
						b141981f91
					
				@ -197,3 +197,79 @@ describe('Average time calculation', () => {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('count current flags in each stage', () => {
 | 
				
			||||||
 | 
					    test('it counts the number of flags in each stage for the given project', async () => {
 | 
				
			||||||
 | 
					        const project = await db.stores.projectStore.create({
 | 
				
			||||||
 | 
					            name: 'project',
 | 
				
			||||||
 | 
					            id: randomId(),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const flags = [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                name: randomId(),
 | 
				
			||||||
 | 
					                stages: ['initial', 'pre-live', 'live', 'archived'],
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                name: randomId(),
 | 
				
			||||||
 | 
					                stages: ['initial', 'archived'],
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                name: randomId(),
 | 
				
			||||||
 | 
					                stages: ['initial', 'pre-live', 'live', 'archived'],
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            { name: randomId(), stages: ['initial', 'pre-live', 'live'] },
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (const { name, stages } of flags) {
 | 
				
			||||||
 | 
					            const flag = await db.stores.featureToggleStore.create(project.id, {
 | 
				
			||||||
 | 
					                name,
 | 
				
			||||||
 | 
					                createdByUserId: 1,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (const stage of stages) {
 | 
				
			||||||
 | 
					                await db.stores.featureLifecycleStore.insert([
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        feature: flag.name,
 | 
				
			||||||
 | 
					                        stage: stage as StageName,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                ]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const otherProject = await db.stores.projectStore.create({
 | 
				
			||||||
 | 
					            name: 'project',
 | 
				
			||||||
 | 
					            id: randomId(),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        const flagInOtherProject = await db.stores.featureToggleStore.create(
 | 
				
			||||||
 | 
					            otherProject.id,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                name: randomId(),
 | 
				
			||||||
 | 
					                createdByUserId: 1,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await db.stores.featureLifecycleStore.insert([
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                feature: flagInOtherProject.name,
 | 
				
			||||||
 | 
					                stage: 'initial',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                feature: flagInOtherProject.name,
 | 
				
			||||||
 | 
					                stage: 'pre-live',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const readModel = new ProjectLifecycleSummaryReadModel(db.rawDatabase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const result = await readModel.getCurrentFlagsInEachStage(project.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(result).toMatchObject({
 | 
				
			||||||
 | 
					            initial: 4,
 | 
				
			||||||
 | 
					            'pre-live': 3,
 | 
				
			||||||
 | 
					            live: 3,
 | 
				
			||||||
 | 
					            completed: 0,
 | 
				
			||||||
 | 
					            archived: 3,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -89,7 +89,28 @@ export class ProjectLifecycleSummaryReadModel
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async getCurrentFlagsInEachStage(projectId: string) {
 | 
					    async getCurrentFlagsInEachStage(projectId: string) {
 | 
				
			||||||
        return 0;
 | 
					        const query = this.db('feature_lifecycles as fl')
 | 
				
			||||||
 | 
					            .innerJoin('features as f', 'fl.feature', 'f.name')
 | 
				
			||||||
 | 
					            .where('f.project', projectId)
 | 
				
			||||||
 | 
					            .select('fl.stage')
 | 
				
			||||||
 | 
					            .count('fl.feature as flag_count')
 | 
				
			||||||
 | 
					            .groupBy('fl.stage');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const result = await query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return result.reduce(
 | 
				
			||||||
 | 
					            (acc, row) => {
 | 
				
			||||||
 | 
					                acc[row.stage] = Number(row.flag_count);
 | 
				
			||||||
 | 
					                return acc;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                initial: 0,
 | 
				
			||||||
 | 
					                'pre-live': 0,
 | 
				
			||||||
 | 
					                live: 0,
 | 
				
			||||||
 | 
					                completed: 0,
 | 
				
			||||||
 | 
					                archived: 0,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async getArchivedFlagsOverLastMonth(projectId: string) {
 | 
					    async getArchivedFlagsOverLastMonth(projectId: string) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user