Skip to content

electionObj data schema

David edited this page Jun 25, 2022 · 8 revisions

Terminology:

[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: ()={},
    ...

Election Methods

upsert(obj)

  • 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.

Example:

electionMethods.upsert({moderator: {email: 'new email address', {name: 'name'})

// or if the user deletes something:

electionMethods.upsert({moderator: {email: undefined, name:  undefined})

areQuestionsLocked()

Returns true if Questions can not be changed - for example because invite has been sent to the moderator to record.

createNew()

Create a new, empty electionObj and navigate to the Configure Election page #23

sendInvite()

email an invitation to the moderator of the electionObj

sendCandidateInvites()

email invitations to the candidates in the electionObj.candidates

Clone this wiki locally