-
Notifications
You must be signed in to change notification settings - Fork 9
electionObj data schema
[note: this may not yet be consistent in the code, but we will refactor]
- electionDoc - the mongodb document where webComponent.webComponent==="ElectionDoc"
- electionObj - the webComponent of an electionDoc with other doc's "joined" in, as object of objects
- object of object is of the form
{
"id1": {...},
"id2": {...},
...
}
where ids are either integers 0, 1, 2, ... or they are Mongo ObjectID's
- Iota - a mongodb model for the
iotas
collection where every document has a basic schema including a
{
_id: ObjectId,
subject: string,
description: string,
parentId, ObjectId.toString(),
webComponent, {webComponent: string, ...any},
component: {component: string, ...any},
bp_info: {...any},
userId: ObjectId.toString()
}
The definition for the electionObj that is used by other component to reference the content of an election setup.
function Component(props) {
const {electionOM, ...}=props
const [electionObj, electionMethods]=electionOM
...
}
Whenever the content of electionObj is changed, electionOM will change, which will cause a rerender of the component Don't depend on electionObj or electionMethods to change to cause a re-render. The change may be deeper.
It might seem efficient for components to only take properties within electionObj - like questions, and that can be done like this:
// don't do this unless it's really needed
function Component(props){
const [electionObj, electionMethods]=props
return <Questions={electionObj.questions} >
But if the component is going to be using helper methods like electionMethods.areQuestionsLocked() that depends on other properties in the electionObj - so the Question component wouldn't rerender in this case. For this project the number of components that would get rerendered is reasonable so we won't worry about it for now. Later, if we need to, we can look at optimizing.
Tentative/draft/work-in-progress*
const addDays = (date, days) => {
return new Date(date.getTime() + days * 86400000)
}
const initialDate = new Date(2021, 11, 7)
const modInviteSentDate = addDays(initialDate, 2)
const modInviteDeadline = addDays(modInviteSentDate, 2)
const modInviteAcceptDate = addDays(modInviteDeadline, 2)
const modReminder1 = addDays(modInviteAcceptDate, 2)
const modReminder2 = addDays(modReminder1, 2)
const modFinal = addDays(modReminder2, 2)
const candInviteSent = addDays(modFinal, 2)
const candInviteAccepted = addDays(candInviteSent, 2)
const candReminder = addDays(candInviteAccepted, 2)
const candFinal = addDays(candReminder, 2)
const undebate = addDays(candFinal, 2)
const election = addDays(undebate, 2)
const electionsData = {
elections: [
{
_id: "mongoobjid",
electionName: "U.S Presidential Election",
organizationName: "United States Federal Government",
electionDate: '2022-11-07T23:59:59.999Z',
questions: {
0: {
text: "What is your favorite color?",
time: "30",
},
1: {
text: "Do you have a pet?",
time: "60",
},
2: {
text: "Should we try to fix income inequality?",
time: "90",
},
},
script: {
0: {
text: "Welcome everyone. Our first question is: What is your favorite color?",
},
1: {
text: "Thank you. Our next Question is: Do you have a pet?",
},
2: {
text: "Great. And our last question is: Should we try to fix income inequality?",
},
3: {
text: "Thanks everyone for watching this!",
},
},
moderator: {
"recorders": { // not part of ElectionDoc, auto generated, may be empty or not present
"628d076dcf19df5aa438c07a": Object {
"_id": "628d076dcf19df5aa438c07a",
"bp_info": {
"office": "Moderator",
},
"component": {
"component": "undebateCreator",
},
"description": "Moderator Recorder for #4",
"parentId": "628c73daf2014b3f4c5da4ee",
"subject": "Moderator Recorder for #4",
"userId": "628d0a2afacbb605f4d8e6ac",
"path": "/some-moderator-specific-recorder-path",
},
},
"submissions": {
"628d2d25c945f836b8be0901": {
"_id": "628d2d25c945f836b8be0901",
"component": {
"component": "MergeParticipants",
"participant": {
"listening": "https://res.cloudinary.com/hf6mryjpf/video/upload/v1566510649/5d5b73c01e3b194174cd9b92-0-seat2.webm",
"name": "david",
"speaking": [
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566510654/5d5b73c01e3b194174cd9b92-1-speaking.webm",
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566510659/5d5b73c01e3b194174cd9b92-2-speaking.webm",
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566510665/5d5b73c01e3b194174cd9b92-3-speaking.webm",
],
},
},
"description": "Moderator Recording for #4",
"parentId": "628d0b225f7a7746488c0bff",
"subject": "Moderator Recording for #4",
"userId": "628d0a2afacbb605f4d8e6ac",
},
},
"viewers": {
"628d0b225f7a7746488c0bff": {
"_id": "628d0b225f7a7746488c0bff",
"bp_info": {
"office": "Moderator",
},
"description": "Moderator Viewer for #4",
"parentId": "628c73daf2014b3f4c5da4ee",
"subject": "Moderator Viewer for #4",
"userId": "628d0a2afacbb605f4d8e6ac",
"webComponent": {
"webComponent": "CandidateConversation",
},
"path": "/some-moderator-specific-viewer-path",
},
},
},
candidates: {
"61e76bbefeaa4a25840d85d0":
{
uniqueId: "61e76bbefeaa4a25840d85d0",
name: "Sarah Jones",
email: "sarahjones@mail.com",
office: "President of the U.S.",
region: "United States",
invitations: [ // derived data - list may be empty or not present
{
_id: ""
sentDate: candInviteSent,
responseDate: candInviteAccepted,
status: "Declined",
parentId: "",
},
],
"recorders": { // derived data - list may be empty or not present
"628d076dcf19df5aa438c07a": {
"_id": "628d076dcf19df5aa438c07a",
"bp_info": {
"office": "Moderator",
},
"component": Object {
"component": "undebateCreator",
},
"description": "Moderator Recorder for #4",
"parentId": "628c73daf2014b3f4c5da4ee",
"subject": "Moderator Recorder for #4",
"userId": "628d0a2afacbb605f4d8e6ac",
},
},
submissions: { // derived data - list may be empty or not present
"628d2d25c945f836b8be0901": {
"_id": "628d2d25c945f836b8be0901",
"component": {
"component": "MergeParticipants",
"participant": {
"listening": "https://res.cloudinary.com/hf6mryjpf/video/upload/v1566510649/5d5b73c01e3b194174cd9b92-0-seat2.webm",
"name": "david",
"speaking": Array [
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566510654/5d5b73c01e3b194174cd9b92-1-speaking.webm",
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566510659/5d5b73c01e3b194174cd9b92-2-speaking.webm",
"https://res.cloudinary.com/hf6mryjpf/video/upload/v1566510665/5d5b73c01e3b194174cd9b92-3-speaking.webm",
],
},
},
"description": "Moderator Recording for #4",
"parentId": "628d0b225f7a7746488c0bff",
"subject": "Moderator Recording for #4",
"userId": "628d0a2afacbb605f4d8e6ac",
},
},
}
"61e76bfc8a82733d08f0cf12":
{
uniqueId: "61e76bfc8a82733d08f0cf12",
name: "Michael Jefferson",
email: "mikejeff@mail.com",
office: "President of the U.S.",
region: "United States",
invitations: [
text: "Hi Mike, please send answers",
sentDate: candInviteSent,
responseDate: candInviteAccepted,
status: "Accepted",
],
submission: [
link: "",
date: "",
],
},
},
timeline: {
moderatorDeadlineReminderEmails: {
0: {
date: "2022-01-07T22:09:32.952Z",
sent: true
},
1: {
date: "2022-01-07T22:09:32.952Z",
sent: false
}
},
moderatorSubmissionDeadline: {
0: {
date: "2022-01-07T22:09:32.952Z",
sent: true
},
},
candidateDeadlineReminderEmails: {
0: {
date: "2022-01-07T22:09:32.952Z",
sent: true
},
1: {
date: "2022-01-07T22:09:32.952Z",
sent: false
}
},
candidateSubmissionDeadline: {
0: {
date: "2022-01-07T22:09:32.952Z",
sent: true
}
},
moderatorInviteDeadline: {
0: {
date: "2022-01-07T22:09:32.952Z",
sent: true
},
1: {
date: "2022-01-07T22:09:32.952Z",
sent: false
}
},
},
undebateDate: undebate,
},
],
}
electionMethods={
upsert: (obj)=>{},
areQuestionsLocked: ()=>{},
createNew: ()=>{},
sendInvite: ()=>{},
sendCandidateInvites: ()={},
...
- obj - an object that only contains the portion of electionObj that needs to be changed.
When there is new input from the user, upsert is called to update the electionObj. It will be updated and cause a new version of electionOM to be generated, which will cause all components with it as a prop to rerender. Changes will also be accumulated and sent to the database in a timely manner.
electionMethods.upsert({moderator: {email: 'new email address', {name: 'name'})
// or if the user deletes something:
electionMethods.upsert({moderator: {email: undefined, name: undefined})
Returns true if Questions can not be changed - for example because invite has been sent to the moderator to record.
Create a new, empty electionObj and navigate to the Configure Election page #23
email an invitation to the moderator of the electionObj
email invitations to the candidates in the electionObj.candidates