Skip to content

Commit 56098c4

Browse files
committed
feat: add factory for releasees
1 parent 95535ce commit 56098c4

File tree

4 files changed

+69
-7
lines changed

4 files changed

+69
-7
lines changed

src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import schema from './schema';
2828
import { graphqlUploadExpress } from 'graphql-upload';
2929
import { metricsMiddleware, createMetricsServer, graphqlMetricsPlugin } from './metrics';
3030
import { requestLogger } from './utils/logger';
31+
import ReleasesFactory from './models/releasesFactory';
3132

3233
/**
3334
* Option to enable playground
@@ -164,12 +165,16 @@ class HawkAPI {
164165
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
165166
const businessOperationsFactory = new BusinessOperationsFactory(mongo.databases.hawk!, dataLoaders);
166167

168+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
169+
const releasesFactory = new ReleasesFactory(mongo.databases.events!);
170+
167171
return {
168172
usersFactory,
169173
workspacesFactory,
170174
projectsFactory,
171175
plansFactory,
172176
businessOperationsFactory,
177+
releasesFactory,
173178
};
174179
}
175180

src/models/releasesFactory.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { Collection, Db, ObjectId } from 'mongodb';
2+
import type { ReleaseDBScheme } from '@hawk.so/types';
3+
4+
/**
5+
* ReleasesFactory
6+
* Helper for accessing releases collection
7+
*/
8+
export default class ReleasesFactory {
9+
/**
10+
* DataBase collection to work with
11+
*/
12+
private readonly collection: Collection<ReleaseDBScheme>;
13+
14+
/**
15+
* Creates releases factory instance
16+
* @param dbConnection - connection to Events DB
17+
*/
18+
constructor(dbConnection: Db) {
19+
this.collection = dbConnection.collection<ReleaseDBScheme>('releases');
20+
}
21+
22+
/**
23+
* Find one release document by projectId and release label.
24+
* Tries both exact string match and numeric fallback (if release can be cast to number).
25+
*/
26+
public async findByProjectAndRelease(
27+
projectId: string | ObjectId,
28+
release: string
29+
): Promise<ReleaseDBScheme | null> {
30+
const projectIdStr = projectId.toString();
31+
32+
// Try exact match as stored
33+
let doc = await this.collection.findOne({
34+
projectId: projectIdStr,
35+
release: release as ReleaseDBScheme['release'],
36+
});
37+
38+
// Fallback if release stored as number
39+
if (!doc) {
40+
const asNumber = Number(release);
41+
42+
if (!Number.isNaN(asNumber)) {
43+
doc = await this.collection.findOne({
44+
projectId: projectIdStr,
45+
release: asNumber as unknown as ReleaseDBScheme['release'],
46+
});
47+
}
48+
}
49+
50+
return doc;
51+
}
52+
}
53+
54+

src/resolvers/project.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const { ApolloError, UserInputError } = require('apollo-server-express');
66
const Validator = require('../utils/validator');
77
const EventsFactory = require('../models/eventsFactory');
88
const getEventsFactory = require('./helpers/eventsFactory').default;
9+
const ReleasesFactory = require('../models/releasesFactory').default;
910
const ProjectToWorkspace = require('../models/projectToWorkspace');
1011
const { dateFromObjectId } = require('../utils/dates');
1112
const ProjectModel = require('../models/project').default;
@@ -570,13 +571,9 @@ module.exports = {
570571
* @param {Object} args
571572
* @param {string} args.release - release identifier
572573
*/
573-
async releaseDetails(project, { release }) {
574-
const releasesCollection = mongo.databases.events.collection('releases');
575-
576-
const releaseDoc = await releasesCollection.findOne({
577-
projectId: project._id.toString(),
578-
release: release,
579-
});
574+
async releaseDetails(project, { release }, { factories }) {
575+
const releasesFactory = factories.releasesFactory;
576+
const releaseDoc = await releasesFactory.findByProjectAndRelease(project._id, release);
580577

581578
let enrichedFiles = Array.isArray(releaseDoc?.files) ? releaseDoc.files : [];
582579

src/types/graphql.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import ProjectsFactory from '../models/projectsFactory';
55
// import Accounting from 'codex-accounting-sdk';
66
import PlansFactory from '../models/plansFactory';
77
import BusinessOperationsFactory from '../models/businessOperationsFactory';
8+
import ReleasesFactory from '../models/releasesFactory';
89

910
/**
1011
* Resolver's Context argument
@@ -86,6 +87,11 @@ export interface ContextFactories {
8687
* Allows to work with the Business Operations models
8788
*/
8889
businessOperationsFactory: BusinessOperationsFactory;
90+
91+
/**
92+
* Releases factory for working with releases
93+
*/
94+
releasesFactory: ReleasesFactory;
8995
}
9096

9197
/**

0 commit comments

Comments
 (0)