code: def add_diff(self, original, new):
          
          changes = {}
  
          # Check for additions and updates
          for new_key, new_value in new.items():
  
              # Additions
              if new_key not in original:
                  if 'additions' not in changes:
                      changes['additions'] = {}
                  new_value = self.diff_safe(new_value)
                  changes['additions'][new_key] = new_value
  
              # Updates
              elif original[new_key] != new_value:
                  if 'updates' not in changes:
                      changes['updates'] = {}
  
                  original_value = self.diff_safe(original[new_key])
                  new_value = self.diff_safe(new_value)
  
                  changes['updates'][new_key] = [original_value, new_value]
  
                  # Check for password type fields and redact them
                  if 'password' in new_key:
                      changes['updates'][new_key] = ['*****', '*****']
  
          # Check for deletions
          for original_key, original_value in original.items():
              if original_key not in new:
                  if 'deletions' not in changes:
                      changes['deletions'] = {}
  
                  original_value = self.diff_safe(original_value)
                  changes['deletions'][original_key] = original_value
  
          self.details = changes
docs: Set the details of the change log entry as the difference between two
          dictionaries (original vs. new). The change log uses the following
          format:
  
          {
              'additions': {
                  'field_name': 'value',
                  ...
              },
              'updates': {
                 'field_name': ['original_value', 'new_value'],
                  ...
              },
              'deletions': {
                  'field_name': ['original_value']
              }
          }
  
          Values are tested for equality, there is special case handling for
          `Frame` class instances (see `diff_safe`) and fields with the word
          password in their name are redacted.
  
          Note: Where possible use diff structures that are flat, performing a
          diff on a dictionary which contains sub-dictionaries is not recommended
          as the verbose output (see `diff_to_html`) is optimized for flat
          structures.