+
+ % for obj, source_data in created[:max_diffs]:
+
${model} created in ${target_title}: ${obj}
+ <% diff = make_diff({}, source_data, nature="create") %>
+
+ ${diff.render_html()}
+
+ % endfor
+ % if len(created) > max_diffs:
+
${model} - ${app.render_quantity(len(created) - max_diffs)} more records created in ${target_title} - not shown here
+ % endif
+
+ % for obj, source_data, target_data in updated[:max_diffs]:
+
${model} updated in ${target_title}: ${obj}
+ <% diff = make_diff(target_data, source_data, nature="update") %>
+
+ ${diff.render_html()}
+
+ % endfor
+ % if len(updated) > max_diffs:
+
${model} - ${app.render_quantity(len(updated) - max_diffs)} more records updated in ${target_title} - not shown here
+ % endif
+
+ % for obj, target_data in deleted[:max_diffs]:
+
${model} deleted in ${target_title}: ${obj}
+ <% diff = make_diff(target_data, {}, nature="delete") %>
+
+ ${diff.render_html()}
+
+ % endfor
+ % if len(deleted) > max_diffs:
+
${model} - ${app.render_quantity(len(deleted) - max_diffs)} more records deleted in ${target_title} - not shown here
+ % endif
+
+
+
+ % endfor
+
+
diff --git a/src/wuttasync/emails.py b/src/wuttasync/emails.py
new file mode 100644
index 0000000..b34112d
--- /dev/null
+++ b/src/wuttasync/emails.py
@@ -0,0 +1,166 @@
+# -*- coding: utf-8; -*-
+################################################################################
+#
+# WuttaSync -- Wutta Framework for data import/export and real-time sync
+# Copyright © 2024-2025 Lance Edgar
+#
+# This file is part of Wutta Framework.
+#
+# Wutta Framework is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# Wutta Framework is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# Wutta Framework. If not, see