-
-
Notifications
You must be signed in to change notification settings - Fork 658
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: expose lifecycle stage in project overview search #7017
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ import type { | |
IFeatureOverview, | ||
IFeatureSearchOverview, | ||
IFeatureSearchStore, | ||
IFlagResolver, | ||
ITag, | ||
} from '../../types'; | ||
import FeatureToggleStore from '../feature-toggle/feature-toggle-store'; | ||
|
@@ -40,9 +41,17 @@ class FeatureSearchStore implements IFeatureSearchStore { | |
|
||
private readonly timer: Function; | ||
|
||
constructor(db: Db, eventBus: EventEmitter, getLogger: LogProvider) { | ||
private flagResolver: IFlagResolver; | ||
|
||
constructor( | ||
db: Db, | ||
eventBus: EventEmitter, | ||
getLogger: LogProvider, | ||
flagResolver: IFlagResolver, | ||
) { | ||
this.db = db; | ||
this.logger = getLogger('feature-search-store.ts'); | ||
this.flagResolver = flagResolver; | ||
this.timer = (action) => | ||
metricsHelper.wrapTimer(eventBus, DB_TIME, { | ||
store: 'feature-search', | ||
|
@@ -65,6 +74,20 @@ class FeatureSearchStore implements IFeatureSearchStore { | |
}; | ||
} | ||
|
||
private getLatestLifecycleStageQuery() { | ||
return this.db('feature_lifecycles') | ||
.select( | ||
'feature as stage_feature', | ||
'stage as latest_stage', | ||
'created_at as entered_stage_at', | ||
) | ||
.distinctOn('stage_feature') | ||
.orderBy([ | ||
'stage_feature', | ||
{ column: 'entered_stage_at', order: 'desc' }, | ||
]); | ||
} | ||
|
||
async searchFeatures( | ||
{ | ||
userId, | ||
|
@@ -86,6 +109,9 @@ class FeatureSearchStore implements IFeatureSearchStore { | |
const validatedSortOrder = | ||
sortOrder === 'asc' || sortOrder === 'desc' ? sortOrder : 'asc'; | ||
|
||
const featureLifecycleEnabled = | ||
this.flagResolver.isEnabled('featureLifecycle'); | ||
|
||
Comment on lines
+112
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Getting worse: Complex Method |
||
const finalQuery = this.db | ||
.with('ranked_features', (query) => { | ||
query.from('features'); | ||
|
@@ -235,6 +261,7 @@ class FeatureSearchStore implements IFeatureSearchStore { | |
.select(selectColumns) | ||
.denseRank('rank', this.db.raw(rankingSql)); | ||
}) | ||
.with('lifecycle', this.getLatestLifecycleStageQuery()) | ||
.with( | ||
'final_ranks', | ||
this.db.raw( | ||
|
@@ -290,10 +317,20 @@ class FeatureSearchStore implements IFeatureSearchStore { | |
.joinRaw('CROSS JOIN total_features') | ||
.whereBetween('final_rank', [offset + 1, offset + limit]) | ||
.orderBy('final_rank'); | ||
if (featureLifecycleEnabled) { | ||
finalQuery.leftJoin( | ||
'lifecycle', | ||
'ranked_features.feature_name', | ||
'lifecycle.stage_feature', | ||
); | ||
} | ||
const rows = await finalQuery; | ||
stopTimer(); | ||
if (rows.length > 0) { | ||
const overview = this.getAggregatedSearchData(rows); | ||
const overview = this.getAggregatedSearchData( | ||
rows, | ||
featureLifecycleEnabled, | ||
); | ||
const features = sortEnvironments(overview); | ||
return { | ||
features, | ||
|
@@ -349,7 +386,10 @@ class FeatureSearchStore implements IFeatureSearchStore { | |
return rankingSql; | ||
} | ||
|
||
getAggregatedSearchData(rows): IFeatureSearchOverview[] { | ||
getAggregatedSearchData( | ||
rows, | ||
featureLifecycleEnabled: boolean, | ||
): IFeatureSearchOverview[] { | ||
Comment on lines
+389
to
+392
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Getting worse: Complex Method |
||
const entriesMap: Map<string, IFeatureSearchOverview> = new Map(); | ||
const orderedEntries: IFeatureSearchOverview[] = []; | ||
|
||
|
@@ -372,6 +412,14 @@ class FeatureSearchStore implements IFeatureSearchStore { | |
environments: [], | ||
segments: row.segment_name ? [row.segment_name] : [], | ||
}; | ||
if (featureLifecycleEnabled) { | ||
entry.lifecycle = row.latest_stage | ||
? { | ||
stage: row.latest_stage, | ||
enteredStageAt: row.entered_stage_at, | ||
} | ||
: undefined; | ||
} | ||
entriesMap.set(row.feature_name, entry); | ||
orderedEntries.push(entry); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❌ Getting worse: Large Method
createStores increases from 106 to 112 lines of code, threshold = 70
Suppress