A notification interface, with SMTP as the built-in notifier #4
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
Depends on
#5 postulo-apprise: notifications through Apprise, as the first plugin built outside the core
Postulo/postulo
Reference
Postulo/postulo#4
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Observation
This issue is the interface and the built-in notifier. The Apprise plugin is filed separately and depends on this.
What happens today
Postulo sends no notifications of any kind. The wiki says so plainly (Tracking applications: "Reminders do not notify you"): a reminder appears on the dashboard when its time comes and nowhere else. The only outbound email is django-allauth's — verification and password reset — through Django's
MAILERS.The plugin system covers exactly one kind of thing: capture sources, discovered through the
postulo.sourcesentry-point group bysrc/postulo/plugins/registry.py. Sources are stateless — a URL and some HTML in, aJobPostingDataout — so nothing was built for a plugin that needs per-user configuration or secrets.Background work:
django-tasks-dbis installed and its worker exists, but nothing has ever enqueued a task and no scheduler runs. Notifications are the first feature that genuinely needs one.What changes
1. A second plugin kind. An entry-point group
postulo.notifiers, with the loader inplugins/registry.pygeneralised to handle more than one group. The contract, in the same spirit as sources — no base class, a handful of names:name,versionconfig_fields()— what this notifier needs from a person (an address; an Apprise URL), so Postulo can build the settings form without knowing the pluginsend(notification, config)— deliver one messagetest(config)— behind a "send a test" button2. Per-user channels. A
NotificationChannelmodel: owner, plugin name, configuration, enabled, and which events it wants. Configuration will hold secrets (an Apprise URL embeds a bot token), so it is never rendered back in full, and is either encrypted at rest or the reason it is not gets written down.3. The events. An initial, small set, each a plain dataclass any notifier can format:
Not status changes the person made themselves — telling somebody what they just did is noise.
4. The built-in SMTP notifier. Uses
MAILERS, so it shares configuration with #3's verification mail and there is one place to set up email.5. Scheduling. Reminders falling due need something to notice. The plan settled on a management command driven by the host's cron (
manage.py send_due_reminders), because a single-instance application does not need a worker for one job a minute; the alternative is finally using thedjango-tasks-dbworker. Either way the container gets a documented way to run it — a cron-style sidecar in Compose, or a loop in the entrypoint.6. Documentation. Tracking applications stops saying reminders do not notify; Configuration gains the channel settings;
docs/PLUGINS.mdgains a notifier section beside the source one.Classification
An enhancement, and not a breaking change: off unless a person configures a channel, no schema removed, no operator action required on upgrade. The scheduling piece is the only thing an operator has to opt into, and it is documented rather than forced.
Open questions
SECRET_KEY, a dedicatedPOSTULO_FIELD_KEY, or accept that the database already holds the person's whole job search and document the trade-off?