Skip to content

Commit

Permalink
3008: Switched report-server to using server-boilerplate (beyondessen…
Browse files Browse the repository at this point in the history
…tial#2866)

* 3008: Switched report-server to using server-boilerplate
- Moved some types from entity-server to server-boilerplate

* 3008: Removed duplicate 'Joined' type from entity-server

* 3008: Updated default microService api version to accept any version number

* 3008: Switched existing usages of `/fetchReport` endpoint to `GET`

* 3008: Fixed up lesmis ReportRoute to return vitals data successfully

* 3008: Fixed up ReportRoute in lesmis-server
- Vitals will work again as of 3232

* 3008: Added support for POST in FetchReportRoute
- Moved TestReportRoute to POST
- Reworked types a little

* 3008: Updated examples.http

* 3008: Fixed permissions bug in FetchReportRoute
  • Loading branch information
rohan-bes authored Jul 28, 2021
1 parent 34a9a0a commit 23900a5
Show file tree
Hide file tree
Showing 32 changed files with 345 additions and 309 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import { QueryParameters, ApiConnection } from '@tupaia/server-boilerplate';

const { REPORT_API_URL = 'http://localhost:8030/v2' } = process.env;

type RequestBody = Record<string, unknown> | Record<string, unknown>[];

export class ReportConnection extends ApiConnection {
baseUrl = REPORT_API_URL;

async fetchReport(reportCode: string, query: QueryParameters, body: RequestBody) {
return this.post(`fetchReport/${reportCode}`, query, body);
async fetchReport(reportCode: string, query: QueryParameters) {
return this.get(`fetchReport/${reportCode}`, query);
}
}
10 changes: 10 additions & 0 deletions packages/database/src/modelClasses/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import { TYPES } from '../types';

export class ReportType extends DatabaseType {
static databaseType = TYPES.REPORT;

/**
* @returns {Promise<string>} name of permission group
*/
async permissionGroupName() {
const permissionGroup = await this.otherModels.permissionGroup.findById(
this.permission_group_id,
);
return permissionGroup.name;
}
}

export class ReportModel extends DatabaseModel {
Expand Down
1 change: 1 addition & 0 deletions packages/database/src/modelClasses/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export { FacilityModel } from './Facility';
export { GeographicalAreaModel } from './GeographicalArea';
export { MeditrakDeviceModel } from './MeditrakDevice';
export { PermissionGroupModel } from './PermissionGroup';
export { ReportModel, ReportType } from './Report';
export { SurveyScreenComponentModel } from './SurveyScreenComponent';
export { SurveyScreenModel } from './SurveyScreen';
export { UserEntityPermissionModel } from './UserEntityPermission';
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
AncestorDescendantRelationModel as BaseAncestorDescendantRelationModel,
AncestorDescendantRelationType as BaseAncestorDescendantRelationType,
} from '@tupaia/database';
import { Model, DbConditional, Joined } from '@tupaia/server-boilerplate';
import { EntityFields } from './Entity';
import { Model, Joined, DbConditional } from './types';

export type AncestorDescendantRelationFields = Readonly<{
id: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/entity-server/src/models/Entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { EntityModel as BaseEntityModel, EntityType as BaseEntityType } from '@tupaia/database';
import { Model, DbConditional } from './types';
import { Model, DbConditional } from '@tupaia/server-boilerplate';

export type EntityFields = Readonly<{
id: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/entity-server/src/models/EntityHierarchy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
EntityHierarchyModel as BaseEntityHierarchyModel,
EntityHierarchyType as BaseEntityHierarchyType,
} from '@tupaia/database';
import { Model } from './types';
import { Model } from '@tupaia/server-boilerplate';

export type EntityHierarchyFields = Readonly<{
name: string;
Expand Down
23 changes: 0 additions & 23 deletions packages/entity-server/src/models/types.ts

This file was deleted.

5 changes: 2 additions & 3 deletions packages/lesmis-server/src/connections/ReportConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ const { REPORT_API_URL = 'http://localhost:8030/v2' } = process.env;
type ReportObject = {
results: Record<string, unknown>[];
};
type RequestBody = Record<string, unknown> | Record<string, unknown>[];
export class ReportConnection extends SessionHandlingApiConnection {
baseUrl = REPORT_API_URL;

async fetchReport(reportCode: string, query: QueryParameters, body: RequestBody) {
return this.post(`fetchReport/${reportCode}`, query, body);
async fetchReport(reportCode: string, query: QueryParameters): Promise<ReportObject> {
return this.get(`fetchReport/${reportCode}`, query);
}
}
31 changes: 11 additions & 20 deletions packages/lesmis-server/src/routes/ReportRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,11 @@ export class ReportRoute extends Route {
});
return legacyReport.data;
}
const report = await this.reportConnection.fetchReport(
reportCode,
{
organisationUnitCodes: entityCode,
projectCodes: LESMIS_PROJECT_NAME,
hierarchy: LESMIS_HIERARCHY_NAME,
...this.req.query,
},
{},
);
const report = await this.reportConnection.fetchReport(reportCode, {
organisationUnitCodes: entityCode,
hierarchy: LESMIS_HIERARCHY_NAME,
...this.req.query,
});
return report.results;
}
case 'mapOverlay':
Expand All @@ -54,16 +49,12 @@ export class ReportRoute extends Route {
...this.req.query,
});
default:
return this.reportConnection.fetchReport(
reportCode,
{
// Report server can accept arrays so the parameters are plural
organisationUnitCodes: entityCode,
hierarchy: LESMIS_HIERARCHY_NAME,
...this.req.query,
},
{},
);
return this.reportConnection.fetchReport(reportCode, {
// Report server can accept arrays so the parameters are plural
organisationUnitCodes: entityCode,
hierarchy: LESMIS_HIERARCHY_NAME,
...this.req.query,
});
}
}
}
2 changes: 1 addition & 1 deletion packages/report-server/examples.http
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ content-type: {{contentType}}
Authorization: {{authorization}}

### Fetch Report With Test Config
POST {{baseUrl}}/testFetchReport/xx?organisationUnitCodes=TO&hierarchy=psss&period=2020 HTTP/1.1
POST {{baseUrl}}/testReport?organisationUnitCodes=TO&hierarchy=psss&period=2020 HTTP/1.1
content-type: {{contentType}}
Authorization: {{authorization}}

Expand Down
22 changes: 22 additions & 0 deletions packages/report-server/src/@types/express/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Tupaia
* Copyright (c) 2017 - 2021 Beyond Essential Systems Pty Ltd
*/
import { AccessPolicy } from '@tupaia/access-policy';
import { ReportServerModelRegistry } from '../../types';

declare global {
namespace Express {
export interface Request {
accessPolicy: AccessPolicy;
models: ReportServerModelRegistry;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ctx: any;
}

export interface Response {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ctx: any;
}
}
}
8 changes: 4 additions & 4 deletions packages/report-server/src/aggregator/Aggregator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class Aggregator extends BaseAggregator {
async fetchAnalytics(
dataElementCodes: string[],
aggregationList: (string | AggregationObject)[] | undefined,
organisationUnitCodes: string,
organisationUnitCodes: string[],
hierarchy: string | undefined,
periodParams: PeriodParams,
) {
Expand All @@ -36,7 +36,7 @@ export class Aggregator extends BaseAggregator {
return super.fetchAnalytics(
dataElementCodes,
{
organisationUnitCodes: organisationUnitCodes.split(','),
organisationUnitCodes,
hierarchy,
period,
startDate,
Expand All @@ -50,7 +50,7 @@ export class Aggregator extends BaseAggregator {
async fetchEvents(
programCode: string,
aggregationList: (string | AggregationObject)[] | undefined,
organisationUnitCodes: string,
organisationUnitCodes: string[],
hierarchy: string | undefined,
periodParams: PeriodParams,
dataElementCodes?: string[],
Expand All @@ -62,7 +62,7 @@ export class Aggregator extends BaseAggregator {
return super.fetchEvents(
programCode,
{
organisationUnitCodes: organisationUnitCodes.split(','),
organisationUnitCodes,
hierarchy,
dataElementCodes,
period,
Expand Down
55 changes: 0 additions & 55 deletions packages/report-server/src/app/addRoutesToApp.ts

This file was deleted.

60 changes: 17 additions & 43 deletions packages/report-server/src/app/createApp.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,25 @@
/**
* Tupaia
* Copyright (c) 2017 - 2020 Beyond Essential Systems Pty Ltd
* Copyright (c) 2017 - 2021 Beyond Essential Systems Pty Ltd
*/

import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import errorHandler from 'api-error-handler';
import { Authenticator } from '@tupaia/auth';
import { TupaiaDatabase, ModelRegistry } from '@tupaia/database';
import { buildBasicBearerAuthMiddleware } from '@tupaia/server-boilerplate';

import { addRoutesToApp } from './addRoutesToApp';

import { ReportsRequest } from '../types';
import { MicroServiceApiBuilder, handleWith } from '@tupaia/server-boilerplate';
import { TupaiaDatabase } from '@tupaia/database';
import {
FetchReportRequest,
FetchReportRoute,
TestReportRequest,
TestReportRoute,
} from '../routes';

/**
* Set up express server with middleware,
* Set up express server
*/
export function createApp(database: TupaiaDatabase, models: ModelRegistry) {
const app = express();

/**
* Add middleware
*/
app.use(cors());
app.use(bodyParser.json({ limit: '50mb' }));
app.use(errorHandler());

/**
* Add singletons to be attached to req for every route
*/
app.use((req: ReportsRequest, res, next) => {
req.database = database;
req.models = models;
next();
});

/**
* Attach authentication to each endpoint
*/
app.use(buildBasicBearerAuthMiddleware('report-server', new Authenticator(models)));

/**
* Add all routes to the app
*/
addRoutesToApp(app);

return app;
export function createApp() {
return new MicroServiceApiBuilder(new TupaiaDatabase())
.useBasicBearerAuth('report-server')
.get<FetchReportRequest>('fetchReport/:reportCode', handleWith(FetchReportRoute))
.post<FetchReportRequest>('fetchReport/:reportCode', handleWith(FetchReportRoute))
.post<TestReportRequest>('testReport', handleWith(TestReportRoute))
.build();
}
24 changes: 5 additions & 19 deletions packages/report-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,19 @@

import '@babel/polyfill';

import {} from 'dotenv/config'; // Load the environment variables into process.env
import * as dotenv from 'dotenv';

import http from 'http';
import { TupaiaDatabase, ModelRegistry } from '@tupaia/database';
// import { Analytic, Builder, FetchOptions, IndicatorType, ModelRegistry } from './types';
import { createApp } from './app';

import winston from './log';

/**
* Set up database
*/
const database = new TupaiaDatabase();
const models = new ModelRegistry(database);
dotenv.config(); // Load the environment variables into process.env

/**
* Set up actual app with routes etc.
* Set up app with routes etc.
*/
const app = createApp(database, models);
const app = createApp();

/**
* Start the server
Expand All @@ -36,13 +30,5 @@ winston.info(`Running on port ${port}`);
* Notify PM2 that we are ready
* */
if (process.send) {
(async () => {
try {
await database.waitForChangeChannel();
winston.info('Successfully connected to pubsub service');
process.send('ready');
} catch (error) {
winston.error(error.message);
}
})();
process.send('ready');
}
Loading

0 comments on commit 23900a5

Please sign in to comment.