-
-
-
In Progress
-
-
XMPP Integration in Sztab - Architecture Outline and Initial Scope
1. XMPP's Place in Sztab
1.1 Sztab => User Notifications
The primary and most immediate use of XMPP. Sztab publishes human-readable messages to individual users via Tigase's REST API. The user receives them in any XMPP client (Conversations, Gajim, etc.). Sztab has no knowledge of XMPP protocol internals — it only speaks to Tigase over HTTP.
Event types in scope long-term:
- Issue assigned, reassigned, or overdue
- Comment posted on a watched issue or PR
@mentionin any comment- PR review requested or completed
- Branch push linked to an issue (via SZ-122 auto-linking)
- PAT approaching expiry
- Scheduled reminders (standup prompts, overdue digests) — later phase
1.2 Intra-Sztab Component Communication
XMPP pub/sub (XEP-0060) as an internal async event bus between Sztab's own components, specifically where HTTP callbacks are today synchronous and fragile.
The primary candidate is the Sztabina => Spring Boot post-receive hook. Today this is a synchronous HTTP callback that fails silently if Spring Boot is temporarily unavailable. Replacing it with an XMPP pub/sub node makes delivery async and decoupled - Sztabina publishes a
git.pushevent, Spring Boot consumes it when ready.Candidate internal pub/sub topics:
Topic Publisher Subscriber sztab.git.pushSztabina Spring Boot (issue auto-linking, PR update) sztab.git.pr.openedSztabina Spring Boot (PR lifecycle) sztab.import.progressImport worker (SZ-130) Spring Boot (status updates) sztab.ai.query.resultAI backend (future) Spring Boot (Copilot responses) This pattern also future-proofs Sztab for additional services without introducing a separate message broker (Kafka, RabbitMQ) into the stack. Tigase is already in the infrastructure - it earns its place as a lightweight internal bus at no additional operational cost.
Important constraint: Tigase must not become a hard dependency for synchronous, latency-sensitive operations. Intra-process Spring application events remain the right tool inside the Spring Boot backend itself. XMPP pub/sub is for cross-process, cross-language async delivery only.
1.3 Sztab Service Status Announcements
XMPP has a well-established presence and availability model (RFC 6121) that maps naturally onto service status. Sztab can maintain a bot JID (e.g.
sztab@tigase.example.com) whose XMPP presence reflects the health of the Sztab service.Two mechanisms are relevant here:
Presence (RFC 6121) The Sztab bot JID publishes presence stanzas reflecting service state:
available- Sztab is fully operationalaway- degraded (e.g. Sztabina unreachable, background jobs stalled)unavailable- Sztab is down or in maintenance
Any XMPP user who has subscribed to the bot JID sees this in their client's contact list as a live status indicator - no polling, no dashboard required.
Service announcements via MUC or pub/sub (XEP-0045 / XEP-0060) For broadcast announcements (planned maintenance, release deployments, incident notifications), Sztab can publish to a dedicated XMPP channel or pub/sub node:
sztab-announce@conference.tigase.example.com(MUC room)- or
sztab.statuspub/sub node
Stakeholders subscribe once and receive all future announcements passively. This is particularly useful for Artur and Andrzej - operational awareness without checking a separate status page.
2. What Is Not XMPP's Job in Sztab
To keep the architecture honest:
- Intra-Spring Boot communication - Spring application events
- Synchronous service-to-service calls - HTTP/REST as today
- Database-backed state - PostgreSQL as today
- Authentication - Sztab's own session/PAT mechanism
XMPP handles async human-facing delivery and async cross-process eventing. Nothing else.
3. Initial Scope: First Cut
3.1 Objectives
Deliver two things only:
- Sztab => User notifications for a defined initial event set
- Sztab service status announcements via bot presence and a status pub/sub node
No inbound message handling. No bot commands. No pub/sub for internal component communication. Those are follow-on phases.
3.2 Core Abstraction
A
NotificationEventdomain object:public record NotificationEvent( String recipientJid, // resolved from user profile NotificationEventType type, Map<String, String> payload // issueId, title, actor, link, etc. ) {}NotificationEventTypeenum — initial values:ISSUE_ASSIGNEDCOMMENT_POSTEDMENTIONPR_REVIEW_REQUESTEDPR_REVIEW_COMPLETED
3.3 Components to Build
User JID field Optional per-user profile field. If absent, XMPP delivery is silently skipped for that user. User-supplied — no JID resolution or directory lookup in this phase.
Notification dispatch service Thin orchestration layer. Receives
NotificationEventvia Spring application events. Fans out to registeredNotificationChannelAdapterimplementations. Only the XMPP adapter is registered in this phase.public interface NotificationChannelAdapter { void deliver(NotificationEvent event); }Tigase REST adapter Implements
NotificationChannelAdapter. POSTs to Tigase's HTTP API to deliver a message to the recipient JID. This is the only component in Sztab that knows XMPP exists. Configured viaapplication.yml:sztab: notifications: xmpp: enabled: true tigase-rest-url: https://tigase.example.com bot-jid: sztab@tigase.example.com credentials: username: sztab-bot password: ${SZTAB_XMPP_BOT_PASSWORD}Message templates Plain text only. One template per event type. Short and actionable:
[Sztab] SZ-00132: "Bug in login flow" assigned to you by artur. View: https://sztab.local/issues/SZ-00132Sztab bot presence publisher A Spring
@Componentthat connects to Tigase on startup and publishes presence on behalf of the bot JID. Presence is updated by a health check scheduler:- Healthy =>
available - Degraded (Sztabina unreachable, job queue stalled) =>
away - Shutdown hook =>
unavailable
Status announcement publisher On significant events (startup, shutdown, deployment, detected degradation), Sztab publishes a plain-text message to the
sztab.statuspub/sub node on Tigase. Administrators subscribe to this node once to receive all future announcements.3.4 Explicit Out of Scope for This Cut
- Inbound XMPP message handling
- Bot commands (
/status,/create, etc.) - Email, SMS, or any other notification channel
- Per-user notification preferences
- Digest or batching of notifications
- MUC room management
- Intra-component pub/sub (Sztabina → Spring Boot)
- GenAI / RAG
- Admin UI for XMPP config:
application.ymlonly
3.5 Issues to File
Issue Description SZ-77 (update) Umbrella: pluggable NotificationChannelAdapterarchitectureNew User JID field - profile settings and persistence New Tigase REST adapter - NotificationChannelAdapterimplementationNew Initial five NotificationEventTypevalues wired to dispatchNew Sztab bot presence publisher - health-driven presence updates New Status announcement publisher - startup, shutdown, degradation events
4. Natural Follow-On Phases
For reference: not in scope now, but the architecture above accommodates all of these without structural change:
- Phase 2 - Intra-component pub/sub: Sztabina => Spring Boot via
sztab.git.pushnode replacing synchronous HTTP hook - Phase 3 - Bot command handling: inbound message parsing,
/status,/create issue, structured query responses - Phase 4 - Per-user notification preferences: which event types to receive, per channel
- Phase 5 - Executive NL query interface via XMPP bot backed by Sztab Copilot / RAG
| Type |
New Feature
|
| Priority |
Normal
|
| Assignee | |
| Version |
none
|
| Sprints |
n/a
|
| Customer |
n/a
|
This could/should probably be more general to send notifications. And we could support different channels through plugins or modules, like XMPP, email, text messages (Twillio API), etc...