create order entry
This commit is contained in:
parent
7fc89a63f2
commit
f346bfbe99
2 changed files with 191 additions and 0 deletions
|
|
@ -62,3 +62,8 @@ exports.TOTAL_TIPS = 'totalTips'
|
||||||
exports.PROFILE_BINARY = 'profileBinary'
|
exports.PROFILE_BINARY = 'profileBinary'
|
||||||
|
|
||||||
exports.POSTS_NEW = 'posts'
|
exports.POSTS_NEW = 'posts'
|
||||||
|
|
||||||
|
// For Coordinates
|
||||||
|
exports.COORDINATES = 'coordinates'
|
||||||
|
|
||||||
|
exports.COORDINATE_INDEX = 'coordinateIndex'
|
||||||
|
|
|
||||||
186
services/schema/index.js
Normal file
186
services/schema/index.js
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
const getGunUser = () => require('../gunDB/Mediator').getUser()
|
||||||
|
const Key = require('../gunDB/contact-api/key')
|
||||||
|
/**
|
||||||
|
* @typedef {import('../gunDB/contact-api/SimpleGUN').ISEA} ISEA
|
||||||
|
* @typedef { 'spontaneousPayment' | 'tip' | 'service' | 'product' | 'other' } OrderType
|
||||||
|
*
|
||||||
|
* This represents a settled order only, unsettled orders have no coordinate
|
||||||
|
* @typedef {object} CoordinateOrder
|
||||||
|
* @prop {string} fromLndPub
|
||||||
|
* @prop {string} toLndPub
|
||||||
|
* @prop {string} fromGunPub
|
||||||
|
* @prop {string} toGunPub
|
||||||
|
* @prop {boolean} inbound
|
||||||
|
*
|
||||||
|
* @prop {string=} ownerGunPub Reserved for buddy system:
|
||||||
|
* can be undefined, '', 'me', or node owner pub key to represent node owner,
|
||||||
|
* otherwise it represents a buddy
|
||||||
|
*
|
||||||
|
* @prop {number} coordinateIndex can be payment_index, or add_index depending on if it's a payment or an invoice
|
||||||
|
* @prop {string} coordinateHash can be payment_hash, or r_hash depending on if it's a payment or an invoice,
|
||||||
|
* if it's a r_hash, must be hex encoded
|
||||||
|
*
|
||||||
|
* @prop {OrderType} type
|
||||||
|
* @prop {number} amount
|
||||||
|
* @prop {string=} description
|
||||||
|
* @prop {string=} metadata JSON encoded string to store extra data for special use cases
|
||||||
|
* @prop {number=} timestamp timestamp will be added at processing time if empty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {CoordinateOrder} order
|
||||||
|
*/
|
||||||
|
const checkOrderInfo = (order = {}) => {
|
||||||
|
const {
|
||||||
|
fromLndPub,
|
||||||
|
toLndPub,
|
||||||
|
fromGunPub,
|
||||||
|
toGunPub,
|
||||||
|
inbound,
|
||||||
|
type,
|
||||||
|
amount,
|
||||||
|
description,
|
||||||
|
coordinateIndex,
|
||||||
|
coordinateHash,
|
||||||
|
metadata,
|
||||||
|
} = order
|
||||||
|
|
||||||
|
if (typeof fromLndPub !== 'string' || fromLndPub === '') {
|
||||||
|
return 'invalid or no "fromLndPub" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
if (typeof toLndPub !== 'string' || toLndPub === '') {
|
||||||
|
return 'invalid or no "toLndPub" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
if (typeof fromGunPub !== 'string' || fromGunPub === '') {
|
||||||
|
return 'invalid or no "fromGunPub" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
if (typeof toGunPub !== 'string' || toGunPub === '') {
|
||||||
|
return 'invalid or no "toGunPub" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
if (typeof inbound !== 'boolean') {
|
||||||
|
return 'invalid or no "inbound" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
if (typeof type !== 'string' || type === '') {
|
||||||
|
return 'invalid or no "type" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
if (typeof amount !== 'number') {
|
||||||
|
return 'invalid or no "amount" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof coordinateIndex !== 'number') {
|
||||||
|
return 'invalid or no "coordinateIndex" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
if (typeof coordinateHash !== 'string' || coordinateHash === '') {
|
||||||
|
return 'invalid or no "coordinateHash" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (description && (typeof description !== 'string' || description === '')) {
|
||||||
|
return 'invalid "description" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
if (metadata && (typeof metadata !== 'string' || metadata === '')) {
|
||||||
|
return 'invalid "metadata" field provided to order coordinate'
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
class SchemaManager {
|
||||||
|
constructor({ memIndex = false }) {//config flag?
|
||||||
|
this.memIndex = memIndex
|
||||||
|
this.orderCreateIndexCallbacks.push(this.dateIndexCreateCb) //create more Cbs and p
|
||||||
|
}
|
||||||
|
|
||||||
|
dateIndexName = 'dateIndex'
|
||||||
|
|
||||||
|
memIndex = false //save the index data in memory for faster access
|
||||||
|
|
||||||
|
// MEM INDEX, will be used only if memIndex === true
|
||||||
|
memDateIndex = {} //not implemented yet
|
||||||
|
|
||||||
|
memGunPubIndex = {} //not implemented yet
|
||||||
|
|
||||||
|
memLndPubIndex = {} //not implemented yet
|
||||||
|
|
||||||
|
memTypeIndex = {} //not implemented yet
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {((order : CoordinateOrder,coordinate : string)=>void)[]}
|
||||||
|
*/
|
||||||
|
orderCreateIndexCallbacks = []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {CoordinateOrder} orderInfo
|
||||||
|
* @param {ISEA} SEA
|
||||||
|
*/
|
||||||
|
async AddOrder(orderInfo, SEA) {
|
||||||
|
|
||||||
|
const checkErr = checkOrderInfo(orderInfo)
|
||||||
|
if (checkErr) {
|
||||||
|
throw new Error(checkErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {CoordinateOrder}
|
||||||
|
*/
|
||||||
|
const filteredOrder = {
|
||||||
|
fromLndPub: orderInfo.fromLndPub,
|
||||||
|
toLndPub: orderInfo.toLndPub,
|
||||||
|
fromGunPub: orderInfo.fromGunPub,
|
||||||
|
toGunPub: orderInfo.toGunPub,
|
||||||
|
inbound: orderInfo.inbound,
|
||||||
|
ownerGunPub: orderInfo.ownerGunPub,
|
||||||
|
coordinateIndex: orderInfo.coordinateIndex,
|
||||||
|
coordinateHash: orderInfo.coordinateHash,
|
||||||
|
type: orderInfo.type,
|
||||||
|
amount: orderInfo.amount,
|
||||||
|
description: orderInfo.description,
|
||||||
|
metadata: orderInfo.metadata,
|
||||||
|
|
||||||
|
timestamp: orderInfo.timestamp || Date.now(),
|
||||||
|
}
|
||||||
|
const orderString = JSON.stringify(filteredOrder)
|
||||||
|
const mySecret = require('../gunDB/Mediator').getMySecret()
|
||||||
|
const encryptedOrderString = await SEA.encrypt(orderString, mySecret)
|
||||||
|
const coordinatePub = filteredOrder.inbound ? filteredOrder.toLndPub : filteredOrder.fromLndPub
|
||||||
|
const coordinate = `${coordinatePub}__${filteredOrder.coordinateIndex}__${filteredOrder.coordinateHash}`
|
||||||
|
await new Promise((res, rej) => {
|
||||||
|
getGunUser()
|
||||||
|
.get(Key.COORDINATES)
|
||||||
|
.get(coordinate)
|
||||||
|
.put(encryptedOrderString, ack => {
|
||||||
|
if (ack.err && typeof ack.err !== 'number') {
|
||||||
|
rej(
|
||||||
|
new Error(
|
||||||
|
`Error saving coordinate order to user-graph: ${ack}`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
res()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
//update all indexes with
|
||||||
|
this.orderCreateIndexCallbacks.forEach(cb => cb(filteredOrder, coordinate))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {CoordinateOrder} orderInfo
|
||||||
|
* @param {string} coordinate
|
||||||
|
*/
|
||||||
|
dateIndexCreateCb(orderInfo, coordinate) {
|
||||||
|
const date = new Date(orderInfo.timestamp)
|
||||||
|
//use UTC for consistency?
|
||||||
|
const year = date.getUTCFullYear().toString()
|
||||||
|
const month = date.getUTCMonth().toString()
|
||||||
|
|
||||||
|
getGunUser()
|
||||||
|
.get(Key.COORDINATE_INDEX)
|
||||||
|
.get(this.dateIndexName)
|
||||||
|
.get(year)
|
||||||
|
.get(month)
|
||||||
|
.set(coordinate)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue