-
Notifications
You must be signed in to change notification settings - Fork 4
feat: live updates via notify_push (REST transport for realtime-updates) #1453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
aca4c72
openspec: add live-updates change (notify_push backend)
rubenvdlinde 7e1acc2
feat(push): add PushEvents constants for notify_push channel names
rubenvdlinde 6f50f8f
feat(rbac): add PermissionHandler::getReadableByUsers() for push fan-out
rubenvdlinde 22ae2fb
feat(push): implement NotifyPushListener for real-time object updates
rubenvdlinde 382f0e7
feat(push): register NotifyPushListener for object lifecycle events
rubenvdlinde ba032e9
feat(push): wrap bulk-import paths in NotifyPushListener batch mode
rubenvdlinde d4a9aa8
test(push): add unit and integration tests for notify_push implementa…
rubenvdlinde cdd1793
feat(push): add admin status badge and Deck integration documentation
rubenvdlinde cee5b03
fix(quality): repair pre-existing phpcs violations and test regressions
rubenvdlinde 54c71b3
docs(push): document OpenRegister's own notify_push events
rubenvdlinde 6f9c0ff
feat(docker): add notify_push push server to dev compose
rubenvdlinde 218a323
feat(docker): add redis service required by notify_push
rubenvdlinde b5f9110
fix(push): use notify_push wire format (user/message/body)
rubenvdlinde d34f16e
docs(push): correct OR push events wire format example
rubenvdlinde 8d471a3
docs(push): add test-merge script + subscription cost guidelines
rubenvdlinde c7fa927
docs: drop revert framing from test-merge script
rubenvdlinde a22c81a
fix(push): bypass RBAC + multitenancy on listener-side schema/registe…
rubenvdlinde File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [CONCERN] notify_push port 7867 exposed on all interfaces — unauthenticated WebSocket endpoint The |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| --- | ||
| title: Deck Integration | ||
| sidebar_position: 2 | ||
| description: How OpenRegister integrates with the Nextcloud Deck app, including push events and card–object linking | ||
| keywords: | ||
| - OpenRegister | ||
| - Deck | ||
| - Kanban | ||
| - notify_push | ||
| - real-time | ||
| --- | ||
|
|
||
| # Deck Integration | ||
|
|
||
| OpenRegister integrates with the Nextcloud Deck app to allow Kanban-style task boards to be linked directly to register objects. Deck cards represent tasks or action items; by linking them to objects you get traceable work attached to your data. | ||
|
|
||
| ## Overview | ||
|
|
||
| - Deck cards can be linked to any OpenRegister object via a link table managed by `DeckCardService`. | ||
| - When a Deck board or card changes, Deck fires `notify_custom` push events via `notify_push`. Frontend consumers can listen for these events to refresh linked-object views in real time. | ||
| - OpenRegister's own push events (`or-object-*` and `or-collection-*`) complement Deck events, providing object-level invalidation alongside card-level updates. | ||
|
|
||
| ## Backend integration | ||
|
|
||
| | Class | Responsibility | | ||
| |---|---| | ||
| | `OCA\OpenRegister\Service\DeckCardService` | Creates, retrieves, and deletes Deck cards linked to OR objects; wraps the Deck REST API. | | ||
| | `OCA\OpenRegister\Controller\DeckController` | REST controller exposing card link endpoints under `/api/objects/{register}/{schema}/{uuid}/deck`. | | ||
|
|
||
| The integration uses the Deck REST API (`/api/v1/boards`, `/api/v1/boards/{id}/stacks`, `/api/v1/boards/{id}/stacks/{stackId}/cards`) rather than the Deck PHP service layer, so it does not require Deck to be installed on the same Nextcloud instance — it can target a remote Deck instance. | ||
|
|
||
| ## Linking cards to objects | ||
|
|
||
| A Deck card is linked to an OpenRegister object through the `deck` property on the `ObjectEntity`. The property holds an array of card-link descriptors: | ||
|
|
||
| ```json | ||
| { | ||
| "@self": { "id": "550e8400-e29b-41d4-a716-446655440000" }, | ||
| "deck": [ | ||
| { | ||
| "boardId": 5, | ||
| "stackId": 12, | ||
| "cardId": 99, | ||
| "title": "Review permit application", | ||
| "url": "https://nextcloud.example.com/apps/deck#/board/5" | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| `DeckCardService` is responsible for hydrating this array and for creating new cards via the API. | ||
|
|
||
| The link is stored on the object itself (as part of the JSONB blob). There is no separate join table — the `deck` property is the canonical record of which cards are attached to which object. | ||
|
|
||
| ## Push events | ||
|
|
||
| Deck emits `notify_custom` events via the Nextcloud `notify_push` app. Both constants live in `OCA\Deck\NotifyPushEvents`: | ||
|
|
||
| | Event string | Fired when | Payload fields | | ||
| |---|---|---| | ||
| | `deck_board_update` | A board is updated, a member is added/removed, or ACL changes | `id` (board ID) | | ||
| | `deck_card_update` | A card is created, updated, moved, or deleted | `boardId`, `cardId` | | ||
|
|
||
| These events are fired server-side by `OCA\Deck\Listeners\LiveUpdateListener`. Connected browser clients receive them via the `notify_push` WebSocket or SSE channel. | ||
|
|
||
| **OpenRegister contrast:** OR emits the following event strings (see `OCA\OpenRegister\Push\PushEvents`): | ||
|
|
||
| | Event string pattern | Fired when | | ||
| |---|---| | ||
| | `or-object-{uuid}` | Any object lifecycle event (create, update, delete) | | ||
| | `or-collection-{register-slug}-{schema-slug}` | Object created or deleted (collection invalidation) | | ||
|
|
||
| Deck and OR events are independent streams. A frontend widget that shows an object with linked Deck cards should subscribe to both. | ||
|
|
||
| ## Subscribing from the frontend | ||
|
|
||
| `@conduction/nextcloud-vue` provides composables for subscribing to `notify_push` events. Use the `useNotifyPush` composable (available from the upcoming `add-live-updates-plugin` change): | ||
|
|
||
| ```js | ||
| import { useNotifyPush } from '@conduction/nextcloud-vue' | ||
|
|
||
| const { subscribe } = useNotifyPush() | ||
|
|
||
| // Subscribe to object-level OR events | ||
| subscribe(`or-object-${objectUuid}`, ({ data }) => { | ||
| const payload = JSON.parse(data) | ||
| // refresh object view | ||
| }) | ||
|
|
||
| // Subscribe to Deck card updates for the board that owns the linked card | ||
| subscribe('deck_card_update', ({ data }) => { | ||
| const { boardId, cardId } = JSON.parse(data) | ||
| // refresh card list for the affected board | ||
| }) | ||
| ``` | ||
|
|
||
| Cross-reference: the `add-live-updates-plugin` change in `nextcloud-vue` provides the full composable implementation including reconnection handling and per-user event routing. | ||
|
|
||
| ## Configuration | ||
|
|
||
| The Deck integration requires: | ||
|
|
||
| 1. **notify_push installed and running** — check the admin settings Push Notifications section in OpenRegister for status. | ||
| 2. **Deck app installed** — the integration uses Deck's REST API, which must be reachable. | ||
| 3. **Admin credentials or app password** — `DeckCardService` uses the current user's session; board access follows Deck's own RBAC. | ||
|
|
||
| ## Related documentation | ||
|
|
||
| - [n8n Integration](./n8n.md) — trigger n8n workflows on OR object events | ||
| - [Custom Webhooks](./custom-webhooks.md) — push events to arbitrary HTTP endpoints | ||
| - [Deck app documentation](https://github.com/nextcloud/deck) | ||
| - [notify_push configuration](https://github.com/nextcloud/notify_push#configuration) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[BLOCKER] Redis port 6379 bound to 0.0.0.0 with no authentication
The new
redisservice exposes port6379:6379on all host interfaces with norequirepass, no--bind 127.0.0.1. Any process reachable on the host network can read and write the Redis instance, including Nextcloud session data and the notify_push channel state. At minimum addcommand: redis-server --requirepass ChangeMeand align theREDIS_URLin thenotify_pushservice.