Service - Notification Manager: Difference between revisions

From Izara Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(7 intermediate revisions by 2 users not shown)
Line 7: Line 7:
= Repository =
= Repository =


https://bitbucket.org/stb_working/notification-manager/src/master/
https://bitbucket.org/izara-core-shared/izara-core-shared-notification-manager
 
= DynamoDB tables =
 
== PendingConsolidation Table ==
 
; notificationGroupId (partition key)
: type: string
: comes from: random UUID
; time (sort key)
: type: number
: {timestamp activity handled in Activity Switchboard}_{small random UUID}
; activityMsg
: type: object
: object containing ''messageAttributes'' and ''message''


= Object Schemas =
= Object Schemas =
Line 31: Line 17:
=== notificationGroup ===
=== notificationGroup ===


* Groups many notificatons together
* Groups many triggerGroups together
* Simplifies management of similar notifications
* Allows for consolidation of notifications at notification group level


<syntaxhighlight lang="JavaScript">
<syntaxhighlight lang="JavaScript">
{
{
objectType: "notificationGroup",
  objectType: "notificationGroup",
canDelete: false,
  canDelete: false,
    complexFilterServiceTag: "complexFilter",
  storageResources: {
     overWriteHandlers: { // optional, if not set will create default handlers, if empty will not create handler and main function
     myGraph: {
create: ['hdrSqs'], // default: ['hdrApi', 'hdrSqs']
      storageType: "graph",
update: ['hdrSqs'], // default: ['hdrApi', 'hdrSqs']
      graphServerTag: "GraphHandler"
get: [], // default: ['hdrApi', 'hdrInv']
    },
delete: [], // default: ['hdrApi', 'hdrSqs']
    dynamoDB: {
},
      storageType: "dynamoDB",
addOnDataStructure: [
      tableName: "NotificationGroupProcessing"
{
    }
type: "versionedData",
  },
versionedDataLabel: "notificationGroupSettings",
  addOnDataStructure: [
storageResourceTag: "myGraph",
    {
fieldNames: [
      type: "versionedData",
{ // fieldName in versionedData should now same in main objectSchema
      versionedDataLabel: "notificationGroupSettings",
fieldName: "notificationGroupName",
      storageResourceTag: "myGraph",
type: "string",
      fieldNames: {
optionalOnCreate: true, // default = false
    "notificationGroupName": {
canUpdate: true, // default = true
      type: "string",
validation: {
      requiredOnCreate: true,
pattern: pattern
      canUpdate: true,
}
      validation: {
},
        pattern: pattern
{  
      }
fieldName: "consolidated",
    },
type: "boolean",
    "consolidatedType": {
requiredOnCreate: true,
      type: "string",
canUpdate: true,
      optionalOnCreate: true,
validation: {
      requiredOnCreate: false,
pattern: pattern
      canUpdate: true,
}
      validation: {
},
        pattern: pattern
{
      }
fieldName: "consolidatedType",
    },
type: "string",
    "consolidatedFrequency": {
optionalOnCreate: true,
      type: "number",
canUpdate: true,
      optionalOnCreate: true,
validation: {
      requiredOnCreate: false,
pattern: pattern
      canUpdate: true,
}
      validation: {
},
        pattern: pattern
{
      }
fieldName: "consolidatedFrequency",
    },
type: "string",
    "consolidatedSendIfEmpty": {
optionalOnCreate: true,
      type: "boolean",
canUpdate: true,
      optionalOnCreate: true,
validation: {
      requiredOnCreate: false,
pattern: pattern
      canUpdate: true,
}
      validation: {
},
        pattern: pattern
{
      }
fieldName: "consolidatedNextSendDue",
    },
type: "number",
    "consolidatedMessageCount": {
optionalOnCreate: true,
      type: "number",
canUpdate: true,
      optionalOnCreate: true,
validation: {
      requiredOnCreate: false,
pattern: pattern
      canUpdate: true,
}
      validation: {
},
        pattern: pattern
{
      }
fieldName: "consolidatedSendIfEmpty",
    },
type: "boolean",
    "consolidatedConfigs": {
optionalOnCreate: true,
      type: "array",
canUpdate: true,
      optionalOnCreate: true,
validation: {
      requiredOnCreate: false,
pattern: pattern
      canUpdate: true,
}
      validation: {
}
        pattern: pattern
]
      }
}
    }
    ],
      }
     // overwriteGeneratedMainFunction: ["update"],
    }
    storageResources: {
  ],
myGraph: {
  fieldNames: {
storageType: "graph",
     notificationGroupId: {
graphServerTag: "GraphHandler"
      type: "string",
}
      randomOnCreate: true,
      canUpdate: false,
      validation: {
    pattern: pattern
      },
      storageResourceTags: ['myGraph', "dynamoDB"]
     },
     },
     fieldNames: { // see Per Service Schemas
     consolidatedLastTimeSent: {
notificationGroupId: {
      type: "number",
    type: "string",
      optionalOnCreate: true,
optionalOnCreate: true,
      canUpdate: true,
canUpdate: false,
      validation: {
validation: {
    pattern: pattern
pattern: pattern
      },
},
      storageResourceTags: ["dynamoDB"]
storageResourceTags: ['myGraph']
},
receiverTag: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
},
userId: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
}
     },
     },
    identifiers: [
  },
{
  identifiers: [
type: "identifier",
    {
fieldName: "notificationGroupId"
      type: "identifier",
}
      fieldName: "notificationGroupId"
    ]
    }
  ]
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 157: Line 127:


; notificationGroupId (identifier)
; notificationGroupId (identifier)
: comes from: random UUID
: comes from: randomOnCreate
; consolidatedLastTimeSent
: start time for recurring or last time for send consolidated message
; notificationGroupName
; notificationGroupName
: string name set by reciever service, optional
: string name set by user
; receiverTag
: set by the creating service
: eg ContactMethodEmail
; consolidated
: true|false
; consolidatedType
; consolidatedType
: overview|detailed
: none | recurring | messageCount
: ''overview'' sends a count of each type of notification, ''detailed'' lists each activity message
: ''none'' is not consolidated, process immediately
: ''recurring'' process at a specific frequency
: ''messageCount'' process when a specific number of messages have been received
; consolidatedFrequency
; consolidatedFrequency
: not sure, maybe use some sort of standard like cron
: for consolidatedType = recurring, number of milliseconds between each processing
; consolidatedNextSendDue
: timestamp for next due time to send notification
; consolidatedSendIfEmpty
; consolidatedSendIfEmpty
: true|false
: setting for if have no consolidated message
; userId
: true = send message out
: for createdBy relationship
: false = not send message out
; consolidatedMessageCount
: send a consolidated message when the number of messages reaches
; consolidatedConfigs
: pattern for message to send data in consolidated message


 
=== consolidated ===
=== notification ===
 
 
<syntaxhighlight lang="JavaScript">
<syntaxhighlight lang="JavaScript">
{
{
objectType: "notification",
  objectType: "consolidated",
canDelete: false,
  canDelete: false,
complexFilterServiceTag: "complexFilter",
  storageResources: {
     overWriteHandlers: { // optional, if not set will create default handlers, if empty will not create handler and main function
     dynamoDB: {
create: ['hdrSqs'], // default: ['hdrApi', 'hdrSqs']
      storageType: "dynamoDB",
update: ['hdrSqs'], // default: ['hdrApi', 'hdrSqs']
      tableName: "PendingConsolidation"
get: [], // default: ['hdrApi', 'hdrInv']
    }
delete: [], // default: ['hdrApi', 'hdrSqs']
  },
},
  fieldNames: {
addOnDataStructure: [
    notificationGroupId: {
{
      type: "string",
type: "versionedData",
      canUpdate: false,
versionedDataLabel: "notificationSettings",
      storageResourceTags: ['dynamoDB'],
storageResourceTag: "myGraph",
      fromObjType: {
fieldNames: [
    serviceTag: "NotificationManager",
{ // fieldName in versionedData should now same in main objectSchema
    objectType: "notificationGroup"
fieldName: "notificationName",
      }
type: "string",
optionalOnCreate: true, // default = false
canUpdate: true, // default = true
validation: {
pattern: pattern
}
}
]
}
    ],
  // overwriteGeneratedMainFunction: ["update"],
    storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "GraphHandler"
}
     },
     },
     fieldNames: {
     checkedTriggerTime: {
notificationId: {
      type: "string",
    type: "string",
      requiredOnCreate: true,
optionalOnCreate: true,
      canUpdate: false,
canUpdate: false,
      validation: {
validation: {
    pattern: pattern
pattern: pattern
      },
},
      storageResourceTags: ['dynamoDB']
storageResourceTags: ['myGraph']
},
userId: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
}
     },
     },
     identifiers: [
     activityMsg: {
{
      type: "object",
type: "identifier",
      requiredOnCreate: true,
fieldName: "notificationId"
      canUpdate: false,
}
      validation: {
    ]
    pattern: pattern
}
      },
</syntaxhighlight>
      storageResourceTags: ['dynamoDB']
 
==== fieldNames ====
 
; notificationId (identifier)
: comes from: random UUID
; notificationName
: string name set by reciever service, optional
; userId
: for createdBy relationship
 
 
=== notificationTrigger ===
 
<syntaxhighlight lang="JavaScript">
{
objectType: "notificationTrigger",
canDelete: false,
    complexFilterServiceTag: "complexFilter",
    overWriteHandlers: { // optional, if not set will create default handlers, if empty will not create handler and main function
create: ['hdrSqs'], // default: ['hdrApi', 'hdrSqs']
update: [], // default: ['hdrApi', 'hdrSqs']
get: [], // default: ['hdrApi', 'hdrInv']
delete: [], // default: ['hdrApi', 'hdrSqs']
},
    // overwriteGeneratedMainFunction: ["create"],
    storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "GraphHandler"
}
     },
     },
     fieldNames: {
     flowTag: {
notificationTriggerId: {
      type: "string",
type: "string",
      requiredOnCreate: true,
optionalOnCreate: true,
      canUpdate: false,
canUpdate: false,
      validation: {
validation: {
    pattern: pattern
pattern: pattern
      },
},
      storageResourceTags: ['dynamoDB']
storageResourceTags: ['myGraph']
},
propertyName: {
type: "string",
optionalOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
},
valueType: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
},
valueString: {
type: "string",
optionalOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
},
valueNumber: {
type: "number",
optionalOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
},
values: {
type: "arrayMixed",
optionalOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
},
userId: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['myGraph']
}
     },
     },
     identifiers: [
     flowStep: {
{
      type: "string",
type: "identifier",
      requiredOnCreate: true,
fieldName: "notificationTriggerId"
      canUpdate: false,
}
      validation: {
    ]
    pattern: pattern
}
      },
</syntaxhighlight>
      storageResourceTags: ['dynamoDB']
 
    }
==== fieldNames ====
  },
 
  identifiers: [
; notificationTriggerId (identifier)
     {
: comes from: random UUID
      type: "partitionKey",
; propertyName
      fieldName: "notificationGroupId"
: can be a nested property, use dot notation
: "serviceName" and "topicName" valueTypes do not have propertyName
; valueType
: property|attribute|serviceName|topicName
; valueString
: type: string
; valueNumber
: type: number
; values
: type: arrayMixed
; userId
: for createdBy relationship
 
 
=== consolidated ===
 
<syntaxhighlight lang="JavaScript">
{
objectType: "consolidated",
canDelete: false,
     complexFilterServiceTag: "complexFilter",
    storageResources: {
dynamoDB: {
storageType: "dynamoDB",
tableName: "PendingConsolidation"
}
     },
     },
     fieldNames: {
     {
notificationGroupId: {
      type: "sortKey",
type: "string",
      fieldName: "checkedTriggerTime"
requiredOnCreate: true,
    }
canUpdate: false,
  ]
validation: {
pattern: pattern
},
storageResourceTags: ['dynamoDB'],
fromServiceNameTag: "NotificationMgr" ,
fromObjectType: "notificationGroup"
},
time: {
type: "string",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['dynamoDB']
},
activityMsg: {
type: "object",
requiredOnCreate: true,
canUpdate: false,
validation: {
pattern: pattern
},
storageResourceTags: ['dynamoDB']
}
    },
    identifiers: [
{
type: "partitionKey",
fieldName: "notificationGroupId"
},
{
type: "sortKey",
fieldName: "time"
}
    ]
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 428: Line 223:


; notificationGroupId (partition key)
; notificationGroupId (partition key)
: comes from: random UUID
: comes from: randomOnCreate
; time (sort key)
; checkedTriggerTime (sort key)
: comes from {timestamp activity handled in Activity Switchboard}_{small random UUID}
: comes from {timestamp activity handled in Activity Switchboard}_{small random UUID}
: adding the UUID to ensure no clashing records with the same timestamp and notificationGroupId
: adding the UUID to ensure no clashing records with the same timestamp and notificationGroupId
; activityMsg
; activityMsg
: copy of the message delivered from Activity Switchboard
: the message delivered from Activity Switchboard
 
; flowTag
: defines the consolidated configuration for the notification group
; flowType
: defines the consolidated configuration for the notification group


== Object Relationships ==
== Object Relationships ==


=== has_notificationGroup ===
=== ownsNotificationGroup ===
<syntaxhighlight lang="JavaScript">
<syntaxhighlight lang="JavaScript">
{
{
"has_notificationGroup": {
  "ownsNotificationGroup": {
properties: {
    fieldNames: {
"originTimestamp": {
      "originTimestamp": {
    type: "number",           // "string" | "number" ...
    type: "number",
requiredOnCreate: true,  // default=false
    requiredOnCreate: true,  // default = false
canUpdate: true,          // default = true
    canUpdate: true,          // default = true
validation: {}            // ajv syntax
    validation: {}            // ajv syntax
}
      }
},
    },
storageResources: {
    storageResources: {
myGraph: {
      myGraph: {
storageType: "graph",
    storageType: "graph",
graphServerTag: "graphHandler"
    graphServerTag: "GraphHandler"
}
      }
},
    },
links: [
    links: [
{
      {
storageResourceTags: ["myGraph"],
    storageResourceTags: ["myGraph"],
from: {
    from: {
objType: {
      objType: {
serviceTag: "UserContactManager",
        serviceTag: "UserAccount",
objectType: "userContact"
        objectType: "user"
},
      },
linkType: "one",
      linkType: "one",
},
    },
to: {
    to: {
objType: {
      objType: {
serviceTag: "NotificationManager",
        serviceTag: "NotificationManager",
objectType: "notificationGroup"
        objectType: "notificationGroup"
},
      },
requiredOnCreate: true,
      requiredOnCreate: true,
linkType: "many",
      linkType: "many",
handler: true
      handler: true
}
    }
}
      }
]
    ]
}
  }
}
}
</syntaxhighlight>
</syntaxhighlight>
: links userContact to notificationGroup
: links the user to their created notification group


=== disabled_notificationGroup ===
=== hasTriggerGroup ===
<syntaxhighlight lang="JavaScript">
<syntaxhighlight lang="JavaScript">
{
{
"disabled_notificationGroup": {
  "hasTriggerGroup": {
properties: {
    canChangeToRelTypes: [
"originTimestamp": {
      {
    type: "number",            // "string" | "number" ...
    serviceTag: "NotificationManager",
requiredOnCreate: true,  // default=false
    relationshipTag: "disabledTriggerGroup"
canUpdate: true,          // default = true
      }
validation: {}            // ajv syntax
    ],
}
    fieldNames: {
},
      "originTimestamp": {
storageResources: {
    type: "number",            // "string" | "number" ...
myGraph: {
    requiredOnCreate: true,  // default = false
storageType: "graph",
    canUpdate: true,          // default = true
graphServerTag: "GraphHandler"
    validation: {}            // ajv syntax
}
      }
},
    },
links: [
    storageResources: {
{
      myGraph: {
storageResourceTags: ["myGraph"],
    storageType: "graph",
from: {
    graphServerTag: "GraphHandler"
objType: {
      }
serviceTag: "UserContactManager",
    },
objectType: "userContact"
    links: [
},
      {
linkType: "one"
    storageResourceTags: ["myGraph"],
},
    from: {
to: {
      objType: {
objType: {
        serviceTag: "NotificationManager",
serviceTag: "NotificationManager",
        objectType: "notificationGroup"
objectType: "notificationGroup"
      },
},
      linkType: "many",
linkType: "many",
      handler: true
handler: true
    },
}
    to: {
}
      objType: {
]
        serviceTag: "ActivitySwitchboard",
}
        objectType: "triggerGroup"
      },
      linkType: "many"
    }
      }
    ]
  }
}
}
</syntaxhighlight>
</syntaxhighlight>


 
=== disabledTriggerGroup ===
=== has_notification ===
<syntaxhighlight lang="JavaScript">
<syntaxhighlight lang="JavaScript">
{
{
"has_notification": {
  "disabledTriggerGroup": {
properties: {
    canChangeToRelTypes: [
"originTimestamp": {
      {
    type: "number",            // "string" | "number" ...
    serviceTag: "NotificationManager",
requiredOnCreate: true,  // default=false
    relationshipTag: "hasTriggerGroup"
canUpdate: true,          // default = true
      }
validation: {}            // ajv syntax
    ],
}
    fieldNames: {
},
      "originTimestamp": {
storageResources: {
    type: "number",            // "string" | "number" ...
myGraph: {
    requiredOnCreate: true,  // default = false
storageType: "graph",
    canUpdate: true,          // default = true
graphServerTag: "GraphHandler"
    validation: {}            // ajv syntax
}
      }
},
    },
links: [
    storageResources: {
{
      myGraph: {
storageResourceTags: ["myGraph"],
    storageType: "graph",
from: {
    graphServerTag: "GraphHandler"
objType: {
      }
serviceTag: "NotificationManager",
    },
objectType: "notificationGroup"
    links: [
},
      {
linkType: "one",
    storageResourceTags: ["myGraph"],
handler: true
    from: {
},
      objType: {
to: {
        serviceTag: "NotificationManager",
objType: {
        objectType: "notificationGroup"
serviceTag: "NotificationManager",
      },
objectType: "notification"
      linkType: "many",
},
      handler: true
requiredOnCreate: true,
    },
linkType: "many",
    to: {
handler: true
      objType: {
}
        serviceTag: "ActivitySwitchboard",
}
        objectType: "triggerGroup"
]
      },
}
      linkType: "many"
}
    }
</syntaxhighlight>
      }
 
    ]
 
  }
=== disabled_notification ===
<syntaxhighlight lang="JavaScript">
{
"disabled_notification": {
properties: {
"originTimestamp": {
    type: "number",            // "string" | "number" ...
requiredOnCreate: true,  // default=false
canUpdate: true,          // default = true
validation: {}            // ajv syntax
}
},
storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "graphHandler"
}
},
links: [
{
storageResourceTags: ["myGraph"],
from: {
objType: {
serviceTag: "NotificationManager",
objectType: "notificationGroup"
},
linkType: "one",
handler: true
},
to: {
objType: {
serviceTag: "NotificationManager",
objectType: "notification"
},
linkType: "many",
handler: true
}
}
]
}
}
</syntaxhighlight>
 
 
=== has_notificationTrigger ===
<syntaxhighlight lang="JavaScript">
{
"has_notificationTrigger": {
properties: {
"originTimestamp": {
    type: "number",           // "string" | "number" ...
requiredOnCreate: true,  // default=false
canUpdate: true,          // default = true
validation: {}            // ajv syntax
}
},
storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "graphHandler"
}
},
links: [
{
storageResourceTags: ["myGraph"],
from: {
objType: {
serviceTag: "NotificationManager",
objectType: "notification"
},
linkType: "one",
handler: true
},
to: {
objType: {
serviceTag: "NotificationManager",
objectType: "notificationTrigger"
},
requiredOnCreate: true,
linkType: "many",
handler: true
}
}
]
}
}
</syntaxhighlight>
 
 
=== disabled_notificationTrigger ===
<syntaxhighlight lang="JavaScript">
{
"disabled_notificationTrigger": {
properties: {
"originTimestamp": {
    type: "number",            // "string" | "number" ...
requiredOnCreate: true,  // default=false
canUpdate: true,          // default = true
validation: {}            // ajv syntax
}
},
storageResources: {
myGraph: {
storageType: "graph",
graphServerTag: "graphHandler"
}
},
links: [
{
storageResourceTags: ["myGraph"],
from: {
objType: {
serviceTag: "NotificationManager",
objectType: "notification"
},
linkType: "one",
handler: true
},
to: {
objType: {
serviceTag: "NotificationManager",
objectType: "notificationTrigger"
},
linkType: "many",
handler: true
}
}
]
}
}
}
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 05:59, 11 September 2025

Overview

Consolidates and sends notifications to any number of receiver services. Will be used for user notifications but can have other types of receiver services added. Activities are received from Activity Switchboard service.

Notification groups set whether activities are considated (eg per day/per month/per x number of activities), if considated activities are stored here until sending is triggered, according to the considation rules. If not consolidated they are sent on immediately.

Repository

https://bitbucket.org/izara-core-shared/izara-core-shared-notification-manager

Object Schemas

Additional Information
Per Service Schemas

objType

notificationGroup

  • Groups many triggerGroups together
{
  objectType: "notificationGroup",
  canDelete: false,
  storageResources: {
    myGraph: {
      storageType: "graph",
      graphServerTag: "GraphHandler"
    },
    dynamoDB: {
      storageType: "dynamoDB",
      tableName: "NotificationGroupProcessing"
    }
  },
  addOnDataStructure: [
    {
      type: "versionedData",
      versionedDataLabel: "notificationGroupSettings",
      storageResourceTag: "myGraph",
      fieldNames: {
	    "notificationGroupName": {
	      type: "string",
	      requiredOnCreate: true,
	      canUpdate: true,
	      validation: {
	        pattern: pattern
	      }
	    },
	    "consolidatedType": {
	      type: "string",
	      optionalOnCreate: true,
	      requiredOnCreate: false,
	      canUpdate: true,
	      validation: {
	        pattern: pattern
	      }
	    },
	    "consolidatedFrequency": {
	      type: "number",
	      optionalOnCreate: true,
	      requiredOnCreate: false,
	      canUpdate: true,
	      validation: {
	        pattern: pattern
	      }
	    },
	    "consolidatedSendIfEmpty": {
	      type: "boolean",
	      optionalOnCreate: true,
	      requiredOnCreate: false,
	      canUpdate: true,
	      validation: {
	        pattern: pattern
	      }
	    },
	    "consolidatedMessageCount": {
	      type: "number",
	      optionalOnCreate: true,
	      requiredOnCreate: false,
	      canUpdate: true,
	      validation: {
	        pattern: pattern
	      }
    	},
	    "consolidatedConfigs": {
	      type: "array",
    	  optionalOnCreate: true,
    	  requiredOnCreate: false,
    	  canUpdate: true,
	      validation: {
	        pattern: pattern
	      }
    	}
      }
    }
  ],
  fieldNames: {
    notificationGroupId: {
      type: "string",
      randomOnCreate: true,
      canUpdate: false,
      validation: {
	    pattern: pattern
      },
      storageResourceTags: ['myGraph', "dynamoDB"]
    },
    consolidatedLastTimeSent: {
      type: "number",
      optionalOnCreate: true,
      canUpdate: true,
      validation: {
	    pattern: pattern
      },
      storageResourceTags: ["dynamoDB"]
    },
  },	
  identifiers: [
    {
      type: "identifier",
      fieldName: "notificationGroupId"
    }
  ]
}

fieldNames

notificationGroupId (identifier)
comes from: randomOnCreate
consolidatedLastTimeSent
start time for recurring or last time for send consolidated message
notificationGroupName
string name set by user
consolidatedType
none | recurring | messageCount
none is not consolidated, process immediately
recurring process at a specific frequency
messageCount process when a specific number of messages have been received
consolidatedFrequency
for consolidatedType = recurring, number of milliseconds between each processing
consolidatedSendIfEmpty
setting for if have no consolidated message
true = send message out
false = not send message out
consolidatedMessageCount
send a consolidated message when the number of messages reaches
consolidatedConfigs
pattern for message to send data in consolidated message

consolidated

					
{
  objectType: "consolidated",
  canDelete: false,
  storageResources: {
    dynamoDB: {
      storageType: "dynamoDB",
      tableName: "PendingConsolidation"
    }
  },
  fieldNames: {
    notificationGroupId: {
      type: "string",
      canUpdate: false,
      storageResourceTags: ['dynamoDB'],
      fromObjType: {
	    serviceTag: "NotificationManager",
	    objectType: "notificationGroup"
      }
    },
    checkedTriggerTime: {
      type: "string",
      requiredOnCreate: true,
      canUpdate: false,
      validation: {
	    pattern: pattern
      },
      storageResourceTags: ['dynamoDB']
    },
    activityMsg: {
      type: "object",
      requiredOnCreate: true,
      canUpdate: false,
      validation: {
	    pattern: pattern
      },
      storageResourceTags: ['dynamoDB']
    },
    flowTag: {
      type: "string",
      requiredOnCreate: true,
      canUpdate: false,
      validation: {
	    pattern: pattern
      },
      storageResourceTags: ['dynamoDB']
    },
    flowStep: {
      type: "string",
      requiredOnCreate: true,
      canUpdate: false,
      validation: {
	    pattern: pattern
      },
      storageResourceTags: ['dynamoDB']
    }
  },
  identifiers: [
    {
      type: "partitionKey",
      fieldName: "notificationGroupId"
    },
    {
      type: "sortKey",
      fieldName: "checkedTriggerTime"
    }
  ]
}

fieldNames

notificationGroupId (partition key)
comes from: randomOnCreate
checkedTriggerTime (sort key)
comes from {timestamp activity handled in Activity Switchboard}_{small random UUID}
adding the UUID to ensure no clashing records with the same timestamp and notificationGroupId
activityMsg
the message delivered from Activity Switchboard
flowTag
defines the consolidated configuration for the notification group
flowType
defines the consolidated configuration for the notification group

Object Relationships

ownsNotificationGroup

{
  "ownsNotificationGroup": {
     fieldNames: {
       "originTimestamp": {
	     type: "number",
	     requiredOnCreate: true,  	// default = false
	    canUpdate: true,          	// default = true
	    validation: {}            	// ajv syntax
      }
    },
    storageResources: {
      myGraph: {
	    storageType: "graph",
	    graphServerTag: "GraphHandler"
      }
    },
    links: [
      {
	    storageResourceTags: ["myGraph"],
	    from: {
	      objType: {
	        serviceTag: "UserAccount",
	        objectType: "user"
	      },
	      linkType: "one",
	    },
	    to: {
	      objType: {
	        serviceTag: "NotificationManager",
	        objectType: "notificationGroup"
	      },
	      requiredOnCreate: true,
	      linkType: "many",
	      handler: true
	    }
      }
    ]
  }
}
links the user to their created notification group

hasTriggerGroup

{
  "hasTriggerGroup": {
    canChangeToRelTypes: [
      {
	    serviceTag: "NotificationManager",
	    relationshipTag: "disabledTriggerGroup"
      }
    ],
    fieldNames: {
      "originTimestamp": {
	    type: "number",            	// "string" | "number" ...
	    requiredOnCreate: true,  	// default = false
	    canUpdate: true,          	// default = true
	    validation: {}            	// ajv syntax
      }
    },
    storageResources: {
      myGraph: {
	    storageType: "graph",
	    graphServerTag: "GraphHandler"
      }
    },
    links: [
      {
	    storageResourceTags: ["myGraph"],
	    from: {
	      objType: {
	        serviceTag: "NotificationManager",
	        objectType: "notificationGroup"
    	  },
	      linkType: "many",
	      handler: true
    	},
	    to: {
	      objType: {
	        serviceTag: "ActivitySwitchboard",
	        objectType: "triggerGroup"
	      },
	      linkType: "many"
    	}
      }
    ]
  }
}

disabledTriggerGroup

{
  "disabledTriggerGroup": {
    canChangeToRelTypes: [
      {
	    serviceTag: "NotificationManager",
	    relationshipTag: "hasTriggerGroup"
      }
    ],
    fieldNames: {
      "originTimestamp": {
	    type: "number",            	// "string" | "number" ...
	    requiredOnCreate: true,  	// default = false
	    canUpdate: true,          	// default = true
	    validation: {}            	// ajv syntax
      }
    },
    storageResources: {
      myGraph: {
	    storageType: "graph",
	    graphServerTag: "GraphHandler"
      }
    },
    links: [
      {
	    storageResourceTags: ["myGraph"],
	    from: {
	      objType: {
	        serviceTag: "NotificationManager",
	        objectType: "notificationGroup"
	      },
	      linkType: "many",
	      handler: true
	    },
	    to: {
	      objType: {
	        serviceTag: "ActivitySwitchboard",
	        objectType: "triggerGroup"
	      },
	      linkType: "many"
    	}
      }
    ]
  }
}

value or values array

  • Either 'value' or 'values' should be set, not both, if 'values' is used it means any of the elements in the 'values' array can match.
  • To achieve this on Activity Switchboard a new trigger group is created for each element, each activity group has the full list of other triggers, and one option from this trigger's values array. If a notification has multiple values type triggers than a new trigger group on Activity Switchboard is created for each combination.
  • "serviceName" and "topicName" valueTypes do not have propertyName

serviceName and topicName triggers

  • Notifications do not have to set their serviceName and/or topicName, if not set then any message that matches the properties will pass
  • Can set only the serviceName, then any message that passess the properties and is from that serviceName passes
  • Can set serviceName+topicName, then only messages in that topic will pass
  • serviceName and topicName can both be submitted as "values" array, creating multiple trigger groups for each combination

Consolidated notifications

How to trigger processing for time based consolidations

  • ....
  • maybe can use some sort of queue to store a list of NotificationGroup’s that are due to be sent (either because consolidatedSendIfEmpty == true or there are some activities waiting to be processed)

Formating the notification body

  • Initially the format will be hardwired and simple, but in the future we could create templates for formating the notification body
  • The notificationBody is currently sent to receiver as a JSON stringified object containing all activityMsgs

Ideas

  • overview notifications currently count per notification, but could be extended to do aggregates on a per notification, per field level
  • If set to overview maybe can store just aggregate/s needed for the consolidated notification, at the moment store entire messages, create the overview once when sending notification

Working documents

Working documents - Notification Manager