RatingService: Convert to TypeScript
This was an adventure, and was also used as a peer programming exercise to introduce TypeScript to other programmers in the office. This class has far too many dependencies, which made this difficult. The approach was to create .d.ts files for dependencies and wait on moving those over for now, otherwise the task will never get done. The RatingServicePublic trait was left as such for the time being; I was able to work around a bug that was making it difficult to mix it into a prototype. There were no logic changes; this was just type refactoring.master
parent
8f7afd22e5
commit
767a248e44
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* Representation of actions to be performed by the client
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to be performed by the client
|
||||||
|
*
|
||||||
|
* TODO: More specific types
|
||||||
|
*/
|
||||||
|
export interface ClientAction
|
||||||
|
{
|
||||||
|
/** Action to be performed */
|
||||||
|
action: string;
|
||||||
|
|
||||||
|
/** Action arguments */
|
||||||
|
[P: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Set of actions */
|
||||||
|
export type ClientActions = ClientAction[];
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* Contains Program base class
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export declare abstract class Program
|
||||||
|
{
|
||||||
|
readonly ineligibleLockCount: number;
|
||||||
|
|
||||||
|
getId(): string;
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* Contains program Quote class
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @todo Use ``document'' terminology in place of ``quote''
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Program } from "../program/Program";
|
||||||
|
import { Quote, QuoteId } from "./Quote";
|
||||||
|
|
||||||
|
|
||||||
|
export declare class BaseQuote implements Quote
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieve Program associated with quote
|
||||||
|
*
|
||||||
|
* @return quote program
|
||||||
|
*/
|
||||||
|
getProgram(): Program;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the program id associated with the quote
|
||||||
|
*
|
||||||
|
* @return program id
|
||||||
|
*/
|
||||||
|
getProgramId(): string;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the quote id
|
||||||
|
*
|
||||||
|
* The quote id is immutable. A different quote id would represent a
|
||||||
|
* different quote, therefore a new object should be created with the
|
||||||
|
* desired quote id.
|
||||||
|
*
|
||||||
|
* @return quote id
|
||||||
|
*/
|
||||||
|
getId(): QuoteId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the id of the current step
|
||||||
|
*
|
||||||
|
* @return id of current step
|
||||||
|
*/
|
||||||
|
getCurrentStepId(): number;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an explicit lock, providing a reason for doing so
|
||||||
|
*
|
||||||
|
* @param reason - lock reason
|
||||||
|
* @param step - step that user may not navigate prior
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
setExplicitLock( reason: string, step: number ): this;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the date that the premium was calculated as a Unix timestamp
|
||||||
|
*
|
||||||
|
* @param timestamp - Unix timestamp representing premium date
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
setLastPremiumDate( timestamp: UnixTimestamp ): this;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the last time the premium was calculated
|
||||||
|
*
|
||||||
|
* @return last calculated time or 0
|
||||||
|
*/
|
||||||
|
getLastPremiumDate(): UnixTimestamp;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* Generic interface to represent quotes
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @todo Use ``document'' terminology in place of ``quote''
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Program } from "../program/Program";
|
||||||
|
import { QuoteId } from "../document/Document";
|
||||||
|
|
||||||
|
|
||||||
|
export declare interface Quote
|
||||||
|
{
|
||||||
|
// TODO: the easejs interface is empty; is this actually needed?
|
||||||
|
}
|
||||||
|
|
||||||
|
export { QuoteId };
|
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
* General server actions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ClientActions } from "../client/action/ClientAction";
|
||||||
|
import { ServerSideQuote } from "./quote/ServerSideQuote";
|
||||||
|
import { UserRequest } from "./request/UserRequest";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General server actions
|
||||||
|
*/
|
||||||
|
export declare class Server
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Send response to user
|
||||||
|
*
|
||||||
|
* @param request - request to respond to
|
||||||
|
* @param quote - quote associated with request
|
||||||
|
* @param data - data with which to reply
|
||||||
|
* @param actions - optional client actions
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
sendResponse(
|
||||||
|
request: UserRequest,
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
data: Record<string, any>,
|
||||||
|
actions?: ClientActions,
|
||||||
|
): this;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send response to user
|
||||||
|
*
|
||||||
|
* @param request - request to respond to
|
||||||
|
* @param message - message to display to user
|
||||||
|
* @param actions - optional client actions
|
||||||
|
* @param btn_caption - optional caption for acknowledgement button
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
sendError(
|
||||||
|
request: UserRequest,
|
||||||
|
message: string,
|
||||||
|
actions?: ClientActions,
|
||||||
|
btn_caption?: string,
|
||||||
|
): this;
|
||||||
|
}
|
|
@ -28,6 +28,8 @@ const {
|
||||||
ReplSetServers: ReplSetServers,
|
ReplSetServers: ReplSetServers,
|
||||||
} = require( 'mongodb/lib/mongodb' );
|
} = require( 'mongodb/lib/mongodb' );
|
||||||
|
|
||||||
|
const easejs = require( 'easejs' );
|
||||||
|
|
||||||
const regex_base = /^\/quote\/([a-z0-9-]+)\/?(?:\/(\d+)\/?(?:\/(.*))?|\/(program.js))?$/;
|
const regex_base = /^\/quote\/([a-z0-9-]+)\/?(?:\/(\d+)\/?(?:\/(.*))?|\/(program.js))?$/;
|
||||||
const regex_step = /^step\/(\d+)\/?(?:\/(post|visit))?$/;
|
const regex_step = /^step\/(\d+)\/?(?:\/(post|visit))?$/;
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ const {
|
||||||
ExportService,
|
ExportService,
|
||||||
},
|
},
|
||||||
|
|
||||||
RatingService,
|
RatingService: { RatingService },
|
||||||
RatingServicePublish,
|
RatingServicePublish,
|
||||||
TokenedService,
|
TokenedService,
|
||||||
},
|
},
|
||||||
|
@ -136,7 +138,7 @@ exports.init = function( logger, enc_service, conf )
|
||||||
server.init( server_cache, exports.rater );
|
server.init( server_cache, exports.rater );
|
||||||
|
|
||||||
// TODO: temporary proof-of-concept
|
// TODO: temporary proof-of-concept
|
||||||
rating_service = RatingService.use(
|
rating_service = easejs( RatingService ).use(
|
||||||
RatingServicePublish( amqplib, exports.post_rate_publish, logger )
|
RatingServicePublish( amqplib, exports.post_rate_publish, logger )
|
||||||
)(
|
)(
|
||||||
logger, dao, server, exports.rater
|
logger, dao, server, exports.rater
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/**
|
||||||
|
* Mongo DB DAO for program server
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ClassificationData, WorksheetData } from "../rater/Rater";
|
||||||
|
import { PositiveInteger } from "../../numeric";
|
||||||
|
import { QuoteId } from "../../document/Document";
|
||||||
|
import { ServerSideQuote } from "../quote/ServerSideQuote";
|
||||||
|
|
||||||
|
/** Success or failure callback */
|
||||||
|
type Callback = ( quote: ServerSideQuote ) => void;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MongoDB-backed data store
|
||||||
|
*/
|
||||||
|
export declare class MongoServerDao
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Saves a quote to the database
|
||||||
|
*
|
||||||
|
* A full save will include all metadata.
|
||||||
|
*
|
||||||
|
* @param quote - the quote to save
|
||||||
|
* @param success - function to call on success
|
||||||
|
* @param failure - function to call if save fails
|
||||||
|
* @param save_data - quote data to save (optional)
|
||||||
|
*/
|
||||||
|
saveQuote(
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
success: Callback,
|
||||||
|
failure: Callback,
|
||||||
|
save_data: Record<string, any>,
|
||||||
|
): this;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges bucket data with the existing bucket (rather than overwriting the
|
||||||
|
* entire bucket)
|
||||||
|
*
|
||||||
|
* @param quote - quote to save
|
||||||
|
* @param data - bucket data
|
||||||
|
* @param success - successful callback
|
||||||
|
* @param failure - failure callback
|
||||||
|
*/
|
||||||
|
mergeBucket(
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
data: Record<string, any>,
|
||||||
|
success: Callback,
|
||||||
|
failure: Callback,
|
||||||
|
): this;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save quote classification data
|
||||||
|
*
|
||||||
|
* @param quote - quote to save
|
||||||
|
* @param classes - classification data
|
||||||
|
* @param success - successful callback
|
||||||
|
* @param failure - failure callback
|
||||||
|
*/
|
||||||
|
saveQuoteClasses(
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
classes: ClassificationData,
|
||||||
|
success: Callback,
|
||||||
|
failure: Callback,
|
||||||
|
): this;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the quote state to the database
|
||||||
|
*
|
||||||
|
* The quote state includes the current step, the top visited step and the
|
||||||
|
* explicit lock message.
|
||||||
|
*
|
||||||
|
* @param quote - the quote to save
|
||||||
|
* @param success - function to call on success
|
||||||
|
* @param failure - function to call if save fails
|
||||||
|
*/
|
||||||
|
saveQuoteState(
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
success: Callback,
|
||||||
|
failure: Callback,
|
||||||
|
): this;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the quote lock state to the database
|
||||||
|
*
|
||||||
|
* @param quote - the quote to save
|
||||||
|
* @param success - function to call on success
|
||||||
|
* @param failure - function to call if save fails
|
||||||
|
*/
|
||||||
|
saveQuoteLockState(
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
success: Callback,
|
||||||
|
failure: Callback,
|
||||||
|
): this
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save worksheet data
|
||||||
|
*
|
||||||
|
* @param qid - quote identifier
|
||||||
|
* @param data - worksheet data
|
||||||
|
* @param callback - callback
|
||||||
|
*/
|
||||||
|
setWorksheets(
|
||||||
|
qid: QuoteId,
|
||||||
|
data: WorksheetData,
|
||||||
|
callback: NodeCallback<void>,
|
||||||
|
): this;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve worksheet data
|
||||||
|
*
|
||||||
|
* @param qid - quote identifier
|
||||||
|
* @param supplier - supplier id
|
||||||
|
* @param index - worksheet index
|
||||||
|
* @param callback - callback
|
||||||
|
*/
|
||||||
|
getWorksheet(
|
||||||
|
qid: QuoteId,
|
||||||
|
supplier: string,
|
||||||
|
index: PositiveInteger,
|
||||||
|
callback: ( data: WorksheetData | null ) => void,
|
||||||
|
): this;
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* Priority log typescript type definitions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export declare interface PriorityLog
|
||||||
|
{
|
||||||
|
readonly PRIORITY_ERROR: number;
|
||||||
|
readonly PRIORITY_IMPORTANT: number;
|
||||||
|
readonly PRIORITY_DB: number;
|
||||||
|
readonly PRIORITY_INFO: number;
|
||||||
|
readonly PRIORITY_SOCKET: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to the log at the given priority
|
||||||
|
*
|
||||||
|
* If the priority is less than or equal to the set priority for this
|
||||||
|
* object, it will be logged. Otherwise, the message will be ignored.
|
||||||
|
*
|
||||||
|
* The first argument should be the priority. The remaining arguments should
|
||||||
|
* be provided in a sprintf()-style fashion
|
||||||
|
*
|
||||||
|
* @param priority - logging priority
|
||||||
|
* @param ...args - sprintf-style aruments
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
log( priority: number, ...args: Array<string|number> ): this;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* Augments a quote with additional data for use by the quote server
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @todo Use ``document'' terminology in place of ``quote''
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Program } from "../../program/Program";
|
||||||
|
import { BaseQuote } from "../../quote/BaseQuote";
|
||||||
|
|
||||||
|
|
||||||
|
export declare class ServerSideQuote extends BaseQuote
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Last rated date, if any
|
||||||
|
*
|
||||||
|
* @return last rated date
|
||||||
|
*/
|
||||||
|
getRatedDate(): UnixTimestamp;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the timestamp of the first time quote was rated
|
||||||
|
*
|
||||||
|
* @param timestamp - Unix timestamp representing first rated date
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
setRatedDate( timestamp: UnixTimestamp ): this;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* Rating process manager
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Rater } from "./Rater";
|
||||||
|
|
||||||
|
|
||||||
|
export declare class ProcessManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the rater associated with the given id
|
||||||
|
*
|
||||||
|
* @param id - rater id
|
||||||
|
*
|
||||||
|
* @return requested rater
|
||||||
|
*/
|
||||||
|
byId( id: string ): Rater;
|
||||||
|
}
|
|
@ -69,6 +69,9 @@ const _signum = {
|
||||||
*
|
*
|
||||||
* Handles formatting and sending requests to the rating process; and
|
* Handles formatting and sending requests to the rating process; and
|
||||||
* processing replies.
|
* processing replies.
|
||||||
|
*
|
||||||
|
* TODO: Rename this class and provide a more generic interface. The caller
|
||||||
|
* does not care that this sends data to another process for rating.
|
||||||
*/
|
*/
|
||||||
module.exports = Class( 'ProcessManager',
|
module.exports = Class( 'ProcessManager',
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
/**
|
||||||
|
* Contains Rater interface
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ClientActions } from "../../client/action/ClientAction";
|
||||||
|
import { ServerSideQuote } from "../quote/ServerSideQuote";
|
||||||
|
import { UserSession } from "../request/UserSession";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Result of rating */
|
||||||
|
export interface RateResult
|
||||||
|
{
|
||||||
|
/** Whether all suppliers were not able to provide rates */
|
||||||
|
_unavailable_all: '0' | '1';
|
||||||
|
|
||||||
|
/** Result data */
|
||||||
|
[P: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of rating with an individual supplier
|
||||||
|
*
|
||||||
|
* This gets combined into a single RateResult prefixed with each supplier
|
||||||
|
* id and an underscore.
|
||||||
|
*/
|
||||||
|
export interface SupplierRateResult
|
||||||
|
{
|
||||||
|
/** Rating worksheet data */
|
||||||
|
__worksheet?: WorksheetData,
|
||||||
|
|
||||||
|
/** Classification system results */
|
||||||
|
__classes?: ClassificationData,
|
||||||
|
|
||||||
|
/** Basic profiling data */
|
||||||
|
__perf: PerformanceData,
|
||||||
|
|
||||||
|
/** Ineligible message, if any */
|
||||||
|
ineligible: string,
|
||||||
|
|
||||||
|
/** Submit message, if any */
|
||||||
|
submit: string,
|
||||||
|
|
||||||
|
/** Final premium */
|
||||||
|
premium: number,
|
||||||
|
|
||||||
|
/** Rating data */
|
||||||
|
[P: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Basic profiling data */
|
||||||
|
export interface PerformanceData
|
||||||
|
{
|
||||||
|
/** Timestamp of beginning of rating */
|
||||||
|
start: UnixTimestampMillis;
|
||||||
|
|
||||||
|
/** Timestamp of end of rating */
|
||||||
|
end: UnixTimestampMillis;
|
||||||
|
|
||||||
|
/** Total rating time */
|
||||||
|
total: Milliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Worksheet data from rater
|
||||||
|
*
|
||||||
|
* These data come from the compiled raters.
|
||||||
|
*
|
||||||
|
* TODO: Fill in a schema here
|
||||||
|
*/
|
||||||
|
export type WorksheetData = Record<string, any>;
|
||||||
|
|
||||||
|
|
||||||
|
/** Classification results */
|
||||||
|
export type ClassificationData = Record<string, boolean>;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a rater that will generate a quote from a given set of values
|
||||||
|
*/
|
||||||
|
export interface Rater
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Asynchronously performs rating
|
||||||
|
*
|
||||||
|
* @param quote - quote to perform rating on
|
||||||
|
* @param session - user session
|
||||||
|
* @param indv - individual supplier to rate (otherwise empty)
|
||||||
|
* @param success - continuation when rating is successful
|
||||||
|
* @param failure - continuation when rating fails
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
rate(
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
session: UserSession,
|
||||||
|
indv: string,
|
||||||
|
success: ( rate_data: RateResult, actions: ClientActions ) => void,
|
||||||
|
failure: ( message: string ) => void,
|
||||||
|
): this;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
* User request abstraction
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { UserSession } from "./UserSession";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of request from user
|
||||||
|
*/
|
||||||
|
export declare class UserRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieve the current session
|
||||||
|
*
|
||||||
|
* @return current session
|
||||||
|
*/
|
||||||
|
getSession(): UserSession;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* UserResponse class
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manipulates response to user request
|
||||||
|
*/
|
||||||
|
export declare class UserResponse
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* UserSession class
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2019 R-T Specialty, LLC.
|
||||||
|
*
|
||||||
|
* This file is part of the Liza Data Collection Framework.
|
||||||
|
*
|
||||||
|
* liza is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session management
|
||||||
|
*/
|
||||||
|
export declare class UserSession
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Whether the user is logged in as an internal user
|
||||||
|
*
|
||||||
|
* @return true if internal user, otherwise false
|
||||||
|
*/
|
||||||
|
isInternal(): boolean;
|
||||||
|
}
|
|
@ -19,33 +19,60 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Class = require( 'easejs' ).Class;
|
import { ClientActions } from "../../client/action/ClientAction";
|
||||||
|
import { MongoServerDao } from "../db/MongoServerDao";
|
||||||
|
import { PositiveInteger } from "../../numeric";
|
||||||
|
import { PriorityLog } from "../log/PriorityLog";
|
||||||
|
import { ProcessManager } from "../rater/ProcessManager";
|
||||||
|
import { Program } from "../../program/Program";
|
||||||
|
import { QuoteId } from "../../quote/Quote";
|
||||||
|
import { ClassificationData, RateResult, WorksheetData } from "../rater/Rater";
|
||||||
|
import { Server } from "../Server";
|
||||||
|
import { ServerSideQuote } from "../quote/ServerSideQuote";
|
||||||
|
import { UserRequest } from "../request/UserRequest";
|
||||||
|
import { UserResponse } from "../request/UserResponse";
|
||||||
|
|
||||||
|
type RequestCallback = () => void;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XXX: Half-assed, quick refactoring to extract from Server class; this is not
|
* Handle rating requests
|
||||||
* yet complete!
|
*
|
||||||
|
* XXX: This class was extracted from Server and needs additional
|
||||||
|
* refactoring, testing, and cleanup.
|
||||||
*
|
*
|
||||||
* TODO: Logging should be implemented by observers
|
* TODO: Logging should be implemented by observers
|
||||||
*/
|
*/
|
||||||
module.exports = Class( 'RatingService',
|
export class RatingService
|
||||||
{
|
{
|
||||||
logger: null,
|
/**
|
||||||
|
* Initialize rating service
|
||||||
dao: null,
|
*
|
||||||
|
* @param _logger - logging system
|
||||||
_server: null,
|
* @param _dao - database connection
|
||||||
|
* @param _server - server actions
|
||||||
_raters: null,
|
* @param _rater_manager - rating manager
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private readonly _logger: PriorityLog,
|
||||||
|
private readonly _dao: MongoServerDao,
|
||||||
|
private readonly _server: Server,
|
||||||
|
private readonly _rater_manager: ProcessManager,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
|
||||||
__construct: function( logger, dao, server, raters )
|
/**
|
||||||
|
* TODO: Remove once traits subtypes are converted to TS
|
||||||
|
*
|
||||||
|
* This works around an easejs bug where prototype constructors are not
|
||||||
|
* properly invoked. Note that technically the constructor above is
|
||||||
|
* invoked twice by easejs: once with no arguments, and again when
|
||||||
|
* calling this method with the proper arguments.
|
||||||
|
*/
|
||||||
|
__construct()
|
||||||
{
|
{
|
||||||
this._logger = logger;
|
(<any>RatingService ).apply( this, arguments );
|
||||||
this._dao = dao;
|
}
|
||||||
this._server = server;
|
|
||||||
this._raters = raters;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,15 +81,21 @@ module.exports = Class( 'RatingService',
|
||||||
* Note that the continuation will be called after all data saving is
|
* Note that the continuation will be called after all data saving is
|
||||||
* complete; the request will be sent back to the client before then.
|
* complete; the request will be sent back to the client before then.
|
||||||
*
|
*
|
||||||
* @param {UserRequest} request user request to satisfy
|
* @param request - user request to satisfy
|
||||||
* @param {UserResponse} response pending response
|
* @param _response - pending response
|
||||||
* @param {Quote} quote quote to export
|
* @param quote - quote to export
|
||||||
* @param {string} cmd applicable of command request
|
* @param cmd - applicable of command request
|
||||||
* @param {Function} callback continuation after saving is complete
|
* @param callback - continuation after saving is complete
|
||||||
*
|
*
|
||||||
* @return Server self to allow for method chaining
|
* @return Server self to allow for method chaining
|
||||||
*/
|
*/
|
||||||
'public request': function( request, response, quote, cmd, callback )
|
request(
|
||||||
|
request: UserRequest,
|
||||||
|
_response: UserResponse,
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
cmd: string,
|
||||||
|
callback: RequestCallback
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// cmd represents a request for a single rater
|
// cmd represents a request for a single rater
|
||||||
if ( !cmd && this._isQuoteValid( quote ) )
|
if ( !cmd && this._isQuoteValid( quote ) )
|
||||||
|
@ -89,12 +122,12 @@ module.exports = Class( 'RatingService',
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
_getProgramRater: function( program, quote )
|
private _getProgramRater( program: Program, quote: ServerSideQuote )
|
||||||
{
|
{
|
||||||
var rater = this._raters.byId( program.getId() );
|
var rater = this._rater_manager.byId( program.getId() );
|
||||||
|
|
||||||
// if a rater could not be found, we can't do any rating
|
// if a rater could not be found, we can't do any rating
|
||||||
if ( rater === null )
|
if ( rater === null )
|
||||||
|
@ -107,10 +140,20 @@ module.exports = Class( 'RatingService',
|
||||||
}
|
}
|
||||||
|
|
||||||
return rater;
|
return rater;
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
_isQuoteValid: function( quote )
|
/**
|
||||||
|
* Whether quote is still valid
|
||||||
|
*
|
||||||
|
* TODO: This class shouldn't be making this determination, and this
|
||||||
|
* method is nondeterministic.
|
||||||
|
*
|
||||||
|
* @param quote - quote to check
|
||||||
|
*
|
||||||
|
* @return whether quote is still valid
|
||||||
|
*/
|
||||||
|
private _isQuoteValid( quote: ServerSideQuote ): boolean
|
||||||
{
|
{
|
||||||
// quotes are valid for 30 days
|
// quotes are valid for 30 days
|
||||||
var re_date = Math.round( ( ( new Date() ).getTime() / 1000 ) -
|
var re_date = Math.round( ( ( new Date() ).getTime() / 1000 ) -
|
||||||
|
@ -129,14 +172,19 @@ module.exports = Class( 'RatingService',
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
_performRating: function( request, program, quote, indv, c )
|
private _performRating(
|
||||||
|
request: UserRequest,
|
||||||
|
program: Program,
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
indv: string,
|
||||||
|
c: RequestCallback,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var _self = this;
|
var rater = this._getProgramRater( program, quote );
|
||||||
|
|
||||||
var rater = this._getProgramRater( program );
|
|
||||||
if ( !rater )
|
if ( !rater )
|
||||||
{
|
{
|
||||||
this._server.sendError( request, 'Unable to perform rating.' );
|
this._server.sendError( request, 'Unable to perform rating.' );
|
||||||
|
@ -150,49 +198,51 @@ module.exports = Class( 'RatingService',
|
||||||
);
|
);
|
||||||
|
|
||||||
rater.rate( quote, request.getSession(), indv,
|
rater.rate( quote, request.getSession(), indv,
|
||||||
function( rate_data, actions )
|
( rate_data: RateResult, actions: ClientActions ) =>
|
||||||
{
|
{
|
||||||
actions = actions || [];
|
actions = actions || [];
|
||||||
|
|
||||||
_self.postProcessRaterData(
|
this.postProcessRaterData(
|
||||||
request, rate_data, actions, program, quote
|
request, rate_data, actions, program, quote
|
||||||
);
|
);
|
||||||
|
|
||||||
const class_dest = {};
|
const class_dest = {};
|
||||||
|
|
||||||
const cleaned = _self._cleanRateData(
|
const cleaned = this._cleanRateData(
|
||||||
rate_data,
|
rate_data,
|
||||||
class_dest
|
class_dest
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: move me during refactoring
|
// TODO: move me during refactoring
|
||||||
_self._dao.saveQuoteClasses( quote, class_dest );
|
this._dao.saveQuoteClasses(
|
||||||
|
quote, class_dest, () => {}, () => {}
|
||||||
|
);
|
||||||
|
|
||||||
// save all data server-side (important: do after
|
// save all data server-side (important: do after
|
||||||
// post-processing); async
|
// post-processing); async
|
||||||
_self._saveRatingData( quote, rate_data, indv, function()
|
this._saveRatingData( quote, rate_data, indv, function()
|
||||||
{
|
{
|
||||||
// we're done
|
// we're done
|
||||||
c();
|
c();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// no need to wait for the save; send the response
|
// no need to wait for the save; send the response
|
||||||
_self._server.sendResponse( request, quote, {
|
this._server.sendResponse( request, quote, {
|
||||||
data: cleaned,
|
data: cleaned,
|
||||||
initialRatedDate: quote.getRatedDate(),
|
initialRatedDate: quote.getRatedDate(),
|
||||||
lastRatedDate: quote.getLastPremiumDate()
|
lastRatedDate: quote.getLastPremiumDate()
|
||||||
}, actions );
|
}, actions );
|
||||||
},
|
},
|
||||||
function( message )
|
( message: string ) =>
|
||||||
{
|
{
|
||||||
_self._sendRatingError( request, quote, program,
|
this._sendRatingError( request, quote, program,
|
||||||
Error( message )
|
Error( message )
|
||||||
);
|
);
|
||||||
|
|
||||||
c();
|
c();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,32 +252,32 @@ module.exports = Class( 'RatingService',
|
||||||
* this is to allow us to reference the data (e.g. for reporting) even if
|
* this is to allow us to reference the data (e.g. for reporting) even if
|
||||||
* the client does not save it.
|
* the client does not save it.
|
||||||
*
|
*
|
||||||
* @param {Quote} quote quote to save data to
|
* @param quote - quote to save data to
|
||||||
* @param {Object} data rating data
|
* @param data - rating data
|
||||||
*
|
* @param indv - individual supplier, or empty
|
||||||
* @return {undefined}
|
* @param c - callback
|
||||||
*/
|
*/
|
||||||
_saveRatingData: function( quote, data, indv, c )
|
private _saveRatingData(
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
data: RateResult,
|
||||||
|
indv: string,
|
||||||
|
c: RequestCallback
|
||||||
|
): void
|
||||||
{
|
{
|
||||||
// only update the last premium calc date on the initial request
|
// only update the last premium calc date on the initial request
|
||||||
if ( !indv )
|
if ( !indv )
|
||||||
{
|
{
|
||||||
var cur_date = Math.round(
|
var cur_date = <UnixTimestamp>Math.round(
|
||||||
( new Date() ).getTime() / 1000
|
( new Date() ).getTime() / 1000
|
||||||
);
|
);
|
||||||
|
|
||||||
quote.setLastPremiumDate( cur_date );
|
quote.setLastPremiumDate( cur_date );
|
||||||
quote.setRatedDate( cur_date );
|
quote.setRatedDate( cur_date );
|
||||||
|
|
||||||
function done()
|
|
||||||
{
|
|
||||||
c();
|
|
||||||
}
|
|
||||||
|
|
||||||
// save the last prem status (we pass an empty object as the save
|
// save the last prem status (we pass an empty object as the save
|
||||||
// data argument to ensure that we do not save the actual bucket
|
// data argument to ensure that we do not save the actual bucket
|
||||||
// data, which may cause a race condition with the below merge call)
|
// data, which may cause a race condition with the below merge call)
|
||||||
this._dao.saveQuote( quote, done, done, {} );
|
this._dao.saveQuote( quote, c, c, {} );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -239,24 +289,26 @@ module.exports = Class( 'RatingService',
|
||||||
// user a rate (if this save fails, it's likely we have bigger problems
|
// user a rate (if this save fails, it's likely we have bigger problems
|
||||||
// anyway); this can also be done concurrently with the above request
|
// anyway); this can also be done concurrently with the above request
|
||||||
// since it only modifies a portion of the bucket
|
// since it only modifies a portion of the bucket
|
||||||
this._dao.mergeBucket( quote, data );
|
this._dao.mergeBucket( quote, data, () => {}, () => {} );
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process rater data returned from a rater
|
* Process rater data returned from a rater
|
||||||
*
|
*
|
||||||
* @param {UserRequest} request user request to satisfy
|
* @param _request - user request to satisfy
|
||||||
* @param {Object} data rating data returned
|
* @param data - rating data returned
|
||||||
* @param {Array} actions actions to send to client
|
* @param actions - actions to send to client
|
||||||
* @param {Program} program program used to perform rating
|
* @param program - program used to perform rating
|
||||||
* @param {Quote} quote quote used for rating
|
* @param quote - quote used for rating
|
||||||
*
|
|
||||||
* @return {undefined}
|
|
||||||
*/
|
*/
|
||||||
'virtual protected postProcessRaterData': function(
|
protected postProcessRaterData(
|
||||||
request, data, actions, program, quote
|
_request: UserRequest,
|
||||||
)
|
data: RateResult,
|
||||||
|
actions: ClientActions,
|
||||||
|
program: Program,
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
): void
|
||||||
{
|
{
|
||||||
var meta = data._cmpdata || {};
|
var meta = data._cmpdata || {};
|
||||||
|
|
||||||
|
@ -284,18 +336,18 @@ module.exports = Class( 'RatingService',
|
||||||
// have a race condition with async. rating (the /visit request may
|
// have a race condition with async. rating (the /visit request may
|
||||||
// be made while we're rating, and when we come back we would then
|
// be made while we're rating, and when we come back we would then
|
||||||
// update the step id with a prior, incorrect step)
|
// update the step id with a prior, incorrect step)
|
||||||
this._dao.saveQuoteLockState( quote );
|
this._dao.saveQuoteLockState( quote, () => {}, () => {} );
|
||||||
}
|
}
|
||||||
|
|
||||||
// if any have been deferred, instruct the client to request them
|
// if any have been deferred, instruct the client to request them
|
||||||
// individually
|
// individually
|
||||||
if ( Array.isArray( meta.deferred ) && ( meta.deferred.length > 0 ) )
|
if ( Array.isArray( meta.deferred ) && ( meta.deferred.length > 0 ) )
|
||||||
{
|
{
|
||||||
var torate = [];
|
var torate: string[] = [];
|
||||||
|
|
||||||
meta.deferred.forEach( function( alias )
|
meta.deferred.forEach( ( alias: string ) =>
|
||||||
{
|
{
|
||||||
actions.push( { action: 'indvRate', id: alias } );
|
actions.push( { action: 'indvRate', after: alias } );
|
||||||
torate.push( alias );
|
torate.push( alias );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
@ -308,17 +360,29 @@ module.exports = Class( 'RatingService',
|
||||||
torate.join( ',' )
|
torate.join( ',' )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
_sendRatingError: function( request, quote, program, err )
|
/**
|
||||||
|
* Send rating error to user and log
|
||||||
|
*
|
||||||
|
* @param request - user request to satisfy
|
||||||
|
* @param quote - problem quote
|
||||||
|
* @param err - error
|
||||||
|
*/
|
||||||
|
private _sendRatingError(
|
||||||
|
request: UserRequest,
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
program: Program,
|
||||||
|
err: Error,
|
||||||
|
): void
|
||||||
{
|
{
|
||||||
// well that's no good
|
// well that's no good
|
||||||
this._logger.log( this._logger.PRIORITY_ERROR,
|
this._logger.log( this._logger.PRIORITY_ERROR,
|
||||||
"Rating for quote %d (program %s) failed: %s",
|
"Rating for quote %d (program %s) failed: %s",
|
||||||
quote.getId(),
|
quote.getId(),
|
||||||
program.getId(),
|
program.getId(),
|
||||||
err.message + '\n-!' + err.stack.replace( /\n/g, '\n-!' )
|
err.message + '\n-!' + ( err.stack || "" ).replace( /\n/g, '\n-!' )
|
||||||
);
|
);
|
||||||
|
|
||||||
this._server.sendError( request,
|
this._server.sendError( request,
|
||||||
|
@ -328,18 +392,25 @@ module.exports = Class( 'RatingService',
|
||||||
// show details for internal users
|
// show details for internal users
|
||||||
( ( request.getSession().isInternal() )
|
( ( request.getSession().isInternal() )
|
||||||
? '<br /><br />[Internal] ' + err.message + '<br /><br />' +
|
? '<br /><br />[Internal] ' + err.message + '<br /><br />' +
|
||||||
'<hr />' + err.stack.replace( /\n/g, '<br />' )
|
'<hr />' + ( err.stack || "" ).replace( /\n/g, '<br />' )
|
||||||
: ''
|
: ''
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
_processWorksheetData: function( qid, data )
|
/**
|
||||||
|
* Process and save worksheet data from rating results
|
||||||
|
*
|
||||||
|
* @param qid - quote id
|
||||||
|
* @param data - rating result
|
||||||
|
*/
|
||||||
|
private _processWorksheetData( qid: QuoteId, data: RateResult ): void
|
||||||
{
|
{
|
||||||
// TODO: this should be done earlier on, so that this is not necessary
|
// TODO: this should be done earlier on, so that this is not necessary
|
||||||
var wre = /^(.+)___worksheet$/,
|
const wre = /^(.+)___worksheet$/;
|
||||||
worksheets = {};
|
|
||||||
|
const worksheets: Record<string, WorksheetData> = {};
|
||||||
|
|
||||||
// extract worksheets for each supplier
|
// extract worksheets for each supplier
|
||||||
for ( var field in data )
|
for ( var field in data )
|
||||||
|
@ -354,33 +425,44 @@ module.exports = Class( 'RatingService',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _self = this;
|
this._dao.setWorksheets( qid, worksheets, ( err: Error | null ) =>
|
||||||
this._dao.setWorksheets( qid, worksheets, function( err )
|
|
||||||
{
|
{
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
_self._logger.log( this._logger.PRIORITY_ERROR,
|
this._logger.log( this._logger.PRIORITY_ERROR,
|
||||||
"Failed to save rating worksheets for quote %d",
|
"Failed to save rating worksheets for quote %d",
|
||||||
quote.getId(),
|
qid,
|
||||||
err.message + '\n-!' + err.stack.replace( /\n/g, '\n-!' )
|
err.message + '\n-!' + ( err.stack || "" ).replace( /\n/g, '\n-!' )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
serveWorksheet: function( request, quote, supplier, index )
|
/**
|
||||||
|
* Serve worksheet data to user
|
||||||
|
*
|
||||||
|
* @param request - user request to satisfy
|
||||||
|
* @param quote - quote from which to look up worksheet data
|
||||||
|
* @param supplier - supplier name
|
||||||
|
* @param index - worksheet index
|
||||||
|
*/
|
||||||
|
serveWorksheet(
|
||||||
|
request: UserRequest,
|
||||||
|
quote: ServerSideQuote,
|
||||||
|
supplier: string,
|
||||||
|
index: PositiveInteger,
|
||||||
|
): void
|
||||||
{
|
{
|
||||||
var qid = quote.getId(),
|
var qid = quote.getId();
|
||||||
_self = this;
|
|
||||||
|
|
||||||
this._dao.getWorksheet( qid, supplier, index, function( data )
|
this._dao.getWorksheet( qid, supplier, index, data =>
|
||||||
{
|
{
|
||||||
_self._server.sendResponse( request, quote, {
|
this._server.sendResponse( request, quote, {
|
||||||
data: data
|
data: data
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -389,15 +471,18 @@ module.exports = Class( 'RatingService',
|
||||||
* There are certain data saved server-side that there is no use serving to
|
* There are certain data saved server-side that there is no use serving to
|
||||||
* the client.
|
* the client.
|
||||||
*
|
*
|
||||||
* @param {Object} data rate data
|
* @param data - rate data
|
||||||
|
* @param classes - classification data
|
||||||
*
|
*
|
||||||
* @return {Object} modified rate data
|
* @return modified rate data
|
||||||
*/
|
*/
|
||||||
'private _cleanRateData': function( data, classes )
|
private _cleanRateData(
|
||||||
|
data: RateResult,
|
||||||
|
classes: ClassificationData
|
||||||
|
): RateResult
|
||||||
{
|
{
|
||||||
classes = classes || {};
|
// forceful cast because the below loop will copy everything
|
||||||
|
const result = <RateResult>{};
|
||||||
var result = {};
|
|
||||||
|
|
||||||
// clear class data
|
// clear class data
|
||||||
for ( var key in data )
|
for ( var key in data )
|
||||||
|
@ -415,6 +500,5 @@ module.exports = Class( 'RatingService',
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
} );
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Trait } = require( 'easejs' );
|
const { Interface, Trait } = require( 'easejs' );
|
||||||
const RatingService = require( './RatingService' );
|
const { RatingService } = require( './RatingService' );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +51,8 @@ const RatingService = require( './RatingService' );
|
||||||
* See the body of `#_sendMessage' for their values.
|
* See the body of `#_sendMessage' for their values.
|
||||||
*/
|
*/
|
||||||
module.exports = Trait( 'RatingServicePublish' )
|
module.exports = Trait( 'RatingServicePublish' )
|
||||||
.extend( RatingService,
|
.implement( Interface( { 'postProcessRaterData': [] } ) )
|
||||||
|
.extend(
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* AMQP library (amqplib API)
|
* AMQP library (amqplib API)
|
||||||
|
@ -75,7 +76,7 @@ module.exports = Trait( 'RatingServicePublish' )
|
||||||
*
|
*
|
||||||
* @type {DebugLog}
|
* @type {DebugLog}
|
||||||
*/
|
*/
|
||||||
'private _logger': null,
|
'private _log': null,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,7 +90,7 @@ module.exports = Trait( 'RatingServicePublish' )
|
||||||
{
|
{
|
||||||
this._amqp = amqp;
|
this._amqp = amqp;
|
||||||
this._conf = conf;
|
this._conf = conf;
|
||||||
this._logger = logger;
|
this._log = logger;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,7 +105,7 @@ module.exports = Trait( 'RatingServicePublish' )
|
||||||
*
|
*
|
||||||
* @return {undefined}
|
* @return {undefined}
|
||||||
*/
|
*/
|
||||||
'override protected postProcessRaterData'(
|
'abstract override postProcessRaterData'(
|
||||||
request, data, actions, program, quote
|
request, data, actions, program, quote
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -127,13 +128,13 @@ module.exports = Trait( 'RatingServicePublish' )
|
||||||
quote
|
quote
|
||||||
);
|
);
|
||||||
} )
|
} )
|
||||||
.then( () => this._logger.log(
|
.then( () => this._log.log(
|
||||||
this._logger.PRIORITY_INFO,
|
this._log.PRIORITY_INFO,
|
||||||
"Published quote " + quote.getId() +
|
"Published quote " + quote.getId() +
|
||||||
" to post-rate exchange '" + exchange + "'"
|
" to post-rate exchange '" + exchange + "'"
|
||||||
) )
|
) )
|
||||||
.catch( e => this._logger.log(
|
.catch( e => this._log.log(
|
||||||
this._logger.PRIORITY_ERROR,
|
this._log.PRIORITY_ERROR,
|
||||||
"Post-rate exchange publish failure for quote " +
|
"Post-rate exchange publish failure for quote " +
|
||||||
quote.getId() + ": " + e.message
|
quote.getId() + ": " + e.message
|
||||||
) );
|
) );
|
||||||
|
|
|
@ -19,10 +19,9 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict'
|
import { expect } from 'chai';
|
||||||
|
import { RatingService as Sut } from "../../../src/server/service/RatingService";
|
||||||
|
|
||||||
const { expect } = require( 'chai' );
|
|
||||||
const Sut = require( '../../../' ).server.service.RatingService;
|
|
||||||
const RatingServiceStub = require( '../../../' ).test.server.service.RatingServiceStub;
|
const RatingServiceStub = require( '../../../' ).test.server.service.RatingServiceStub;
|
||||||
|
|
||||||
describe( 'RatingService', () =>
|
describe( 'RatingService', () =>
|
||||||
|
@ -49,15 +48,13 @@ describe( 'RatingService', () =>
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
|
||||||
const sut = Sut.extend(
|
const sut = new class extends Sut
|
||||||
{
|
{
|
||||||
'override postProcessRaterData'(
|
postProcessRaterData()
|
||||||
request, data, actions, program, quote
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
} )( logger, dao, server, raters );
|
}( logger, dao, server, raters );
|
||||||
|
|
||||||
sut.request( request, response, quote, 'something', () => {} );
|
sut.request( request, response, quote, 'something', () => {} );
|
||||||
} );
|
} );
|
||||||
|
@ -87,9 +84,9 @@ describe( 'RatingService', () =>
|
||||||
|
|
||||||
quote.getRatedDate = () => initial_date;
|
quote.getRatedDate = () => initial_date;
|
||||||
|
|
||||||
const sut = Sut( logger, dao, server, raters );
|
const sut = new Sut( logger, dao, server, raters );
|
||||||
|
|
||||||
server.sendResponse = ( request, quote, resp, actions ) =>
|
server.sendResponse = ( _request: any, _quote: any, resp: any, _actions: any ) =>
|
||||||
{
|
{
|
||||||
expect( getLastPremiumDateCallCount ).to.equal( 2 );
|
expect( getLastPremiumDateCallCount ).to.equal( 2 );
|
||||||
expect( resp.initialRatedDate ).to.equal( initial_date );
|
expect( resp.initialRatedDate ).to.equal( initial_date );
|
||||||
|
@ -98,7 +95,7 @@ describe( 'RatingService', () =>
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
|
||||||
sut.request( request, response, quote, null, () => {} );
|
sut.request( request, response, quote, "", () => {} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
} );
|
} );
|
Loading…
Reference in New Issue