Browse Source

Merge branch 'main' into bugfix/data-gathering-blocked-by-failed-jobs

pull/7720/head
Thomas Kaul 5 days ago
committed by GitHub
parent
commit
715f9f81e4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      CHANGELOG.md
  2. 11
      apps/api/src/app/admin/admin.controller.ts
  3. 1
      apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts
  4. 29
      apps/api/src/services/queues/data-gathering/data-gathering.service.spec.ts
  5. 6
      apps/api/src/services/queues/data-gathering/data-gathering.service.ts
  6. 7
      apps/client/src/app/components/access-table/access-table.component.html
  7. 6
      apps/client/src/app/components/access-table/access-table.component.ts

3
CHANGELOG.md

@ -9,12 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Harmonized the icons and labels in the access table to share the portfolio
- Migrated the create and edit access dialogs to dedicated routes - Migrated the create and edit access dialogs to dedicated routes
- Improved the response of the historical market data gathering endpoint for a specific date
- Introduced a timeout for the asset profile and the historical market data gathering jobs - Introduced a timeout for the asset profile and the historical market data gathering jobs
- Reduced the number of attempts of the asset profile and the historical market data gathering jobs - Reduced the number of attempts of the asset profile and the historical market data gathering jobs
### Fixed ### Fixed
- Fixed the country mapping of Macau in the _Financial Modeling Prep_ service
- Fixed the asset profile and historical market data gathering of a symbol getting blocked permanently by a failed job by discarding the failed jobs - Fixed the asset profile and historical market data gathering of a symbol getting blocked permanently by a failed job by discarding the failed jobs
- Fixed the asset profile data gathering of a symbol in the admin control panel by removing an existing job before enqueueing a new one - Fixed the asset profile data gathering of a symbol in the admin control panel by removing an existing job before enqueueing a new one

11
apps/api/src/app/admin/admin.controller.ts

@ -218,11 +218,20 @@ export class AdminController {
); );
} }
return this.dataGatheringService.gatherSymbolForDate({ const marketData = await this.dataGatheringService.gatherSymbolForDate({
dataSource, dataSource,
date, date,
symbol symbol
}); });
if (!marketData) {
throw new HttpException(
getReasonPhrase(StatusCodes.NOT_FOUND),
StatusCodes.NOT_FOUND
);
}
return marketData;
} }
@HasPermission(permissions.accessAdminControl) @HasPermission(permissions.accessAdminControl)

1
apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts

@ -56,6 +56,7 @@ export class FinancialModelingPrepService
private static countriesMapping = { private static countriesMapping = {
'Czech Republic': 'CZ', 'Czech Republic': 'CZ',
'Korea (the Republic of)': 'KR', 'Korea (the Republic of)': 'KR',
Macau: 'MO',
'Russian Federation': 'RU', 'Russian Federation': 'RU',
'Taiwan (Province of China)': 'TW', 'Taiwan (Province of China)': 'TW',
Turkey: 'TR' Turkey: 'TR'

29
apps/api/src/services/queues/data-gathering/data-gathering.service.spec.ts

@ -219,5 +219,34 @@ describe('DataGatheringService', () => {
}) })
); );
}); });
it('returns the upserted market data', async () => {
dataProviderService.getHistoricalRaw.mockResolvedValue({
'YAHOO-AAPL': {
'2026-08-22': { marketPrice: 100 }
}
});
prismaService.marketData.upsert.mockResolvedValue({ marketPrice: 100 });
const marketData = await dataGatheringService.gatherSymbolForDate({
dataSource: 'YAHOO',
date: parseDate('2026-08-22'),
symbol: 'AAPL'
});
expect(marketData).toEqual({ marketPrice: 100 });
});
it('returns undefined if the data provider has no market price', async () => {
dataProviderService.getHistoricalRaw.mockResolvedValue({});
const marketData = await dataGatheringService.gatherSymbolForDate({
dataSource: 'YAHOO',
date: parseDate('2026-08-22'),
symbol: 'AAPL'
});
expect(marketData).toBeUndefined();
});
}); });
}); });

6
apps/api/src/services/queues/data-gathering/data-gathering.service.ts

@ -348,10 +348,10 @@ export class DataGatheringService {
}); });
} }
} catch (error) { } catch (error) {
this.logger.error(error.message); this.logger.error(error?.message);
} finally {
return undefined;
} }
return undefined;
} }
public async gatherSymbols({ public async gatherSymbols({

7
apps/client/src/app/components/access-table/access-table.component.html

@ -15,7 +15,7 @@
} @else if (element.type === 'PUBLIC') { } @else if (element.type === 'PUBLIC') {
<span i18n>Public</span> <span i18n>Public</span>
} @else if (element.type === 'MCP') { } @else if (element.type === 'MCP') {
<span>MCP</span> <span>Model Context Protocol (MCP)</span>
} }
</td> </td>
</ng-container> </ng-container>
@ -112,10 +112,11 @@
} }
<button mat-menu-item (click)="onDeleteAccess(element.id)"> <button mat-menu-item (click)="onDeleteAccess(element.id)">
<span class="align-items-center d-flex"> <span class="align-items-center d-flex">
<ion-icon class="mr-2" name="remove-circle-outline" />
@if (isReceivedAccess()) { @if (isReceivedAccess()) {
<span i18n>Remove</span> <ion-icon class="mr-2" name="trash-outline" />
<span i18n>Delete</span>
} @else { } @else {
<ion-icon class="mr-2" name="remove-circle-outline" />
<span i18n>Revoke</span> <span i18n>Revoke</span>
} }
</span> </span>

6
apps/client/src/app/components/access-table/access-table.component.ts

@ -31,7 +31,8 @@ import {
createOutline, createOutline,
ellipsisHorizontal, ellipsisHorizontal,
linkOutline, linkOutline,
removeCircleOutline removeCircleOutline,
trashOutline
} from 'ionicons/icons'; } from 'ionicons/icons';
import ms from 'ms'; import ms from 'ms';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@ -107,7 +108,8 @@ export class GfAccessTableComponent {
createOutline, createOutline,
ellipsisHorizontal, ellipsisHorizontal,
linkOutline, linkOutline,
removeCircleOutline removeCircleOutline,
trashOutline
}); });
this.hasPermissionToEnableMcp = hasPermission( this.hasPermissionToEnableMcp = hasPermission(

Loading…
Cancel
Save