You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Who is asking. NC-Gantt (https://codeberg.org/fds2610/NC-Gantt) is a project planning
app (Gantt chart) for Nextcloud. Projects, subprojects and tasks can be linked to Deck
boards, lists and cards, so that planning and day-to-day work stay in one place: the
plan hands work over to Deck, and Deck stays the single place where that work is done.
What we do today. Deck has an excellent read channel — since Deck 1.18 the
webhook-compatible CardCreatedEvent / CardUpdatedEvent / CardDeletedEvent (#7910) give
us everything we need to follow changes made in Deck. Thank you for those; this
request is only about the other direction.
For writing we have no supported option, so we call Deck's internal services from a
single adapter class (DeckGateway), fetched from the container at call time so that
our app still loads without Deck: CardService (find, create, update, archive),
AssignmentService::assignUser(), BoardService::find(), StackMapper (find, findAll).
These are not meant as an API, and we treat them accordingly: one adapter class, a
contract test that checks every class, method parameter and entity field we touch
against the installed Deck, and a documented review of stable31…stable35 plus master
before every release. That keeps the risk visible, but it does not remove it — and it
puts work on you too, because any refactoring in these services can silently break
third-party apps you never hear about.
Why the internal services are hard to use correctly
Signatures move, by design. Between Deck 1.15 and 1.19, CardService::update()
gained $done, $startdate and $color, partly in the middle of the parameter list. We
now call create() and update() with named arguments resolved through reflection,
because a positional call would break on the next release. That is a workaround, not
an integration.
The acting user comes from the session. CardService and PermissionService receive
the user as private ?string $userId at construction time. In a background job or an
occ command there is no session, so we have to set the "volatile active user" before
calling Deck — and hope that is enough for every code path inside Deck. An API that
takes the acting user as a parameter would make this correct by construction.
No partial updates. update() requires title, stackId, type and owner even when we
only want to move a due date. So every write is a read-modify-write over the whole
card, which loses concurrent edits made in Deck between our read and our write —
exactly the thing a planning app that writes dates must not do. (Same pain as API: Updating items should not require all parameters to be set #1578 on
the REST side.) Deck already has OptionalNullableValue for done and color, so the
idea of "field not supplied ≠ field set to null" exists in the code base; we would
like it for all fields.
Why not the REST/OCS API? An app running inside the same server would have to call its
own server over HTTP, with credentials it does not have, losing the acting user's
session and the transaction context. Talk's "create card" goes that way today (#8116);
we would rather not add another one.
What we need
| Operation | Data
|
|--------------------------------|----------------------------------------------------
-------------------------------------------|
| Create a card | title, description, target list (stack), due date,
start date |
| Read a card | id, title, description, stack/board, due date,
start date, done, archived, deleted, assignees |
| Set dates | due date and start date, each independently, "leave
unchanged" distinguishable from "clear" |
| Mark done / undone | —
|
| Assign / unassign a user | card, user id; a clear, catchable error when the
account has no access to the board |
| Archive a card | (we never delete a card that a user might still
need) |
| List the stacks of a board | id, title, order — to offer a target list
|
| Permissions of the acting user | read / edit / manage on a board, so the UI can hide
what the user may not do |
Permissions stay with Deck. We are explicitly not asking for a way around Deck's
permission checks. Deck should keep checking the rights of the acting person on every
call, exactly as it does for its own controllers, and refuse otherwise. Our app also
never shares a board on the user's behalf: if an assignment fails because the account
cannot see the board, we want to catch that and tell the user, not fix it silently.
Suggested shape
Interfaces in a stable namespace of Deck (for example OCA\Deck\Api*), registered in
the container, versioned with @SInCE tags — the same contract style Nextcloud uses
for OCP, and the same promise the webhook-compatible events already made for reading.
The acting user as an explicit parameter of every call, not read from the session at
construction time, so the API also works in background jobs and occ commands.
Partial updates: a change object or "not supplied" marker per field (Deck's existing
OptionalNullableValue is a good starting point).
Documented exceptions for "not found", "no permission" and "invalid input", so
callers can map them to their own states instead of catching Throwable.
A small surface is fine. The table above would already remove our entire dependency
risk; we would rather have seven stable operations than everything Deck can do.
What this would change for us
Once such an API exists, our adapter would use it from that Deck version on and keep
the current internal calls only as a fallback for older versions — and we would drop
them entirely once those versions are out of support. We are happy to help: reviewing
a draft interface, testing a branch against our integration, or contributing the
implementation if you tell us the shape you would accept.
Who is asking. NC-Gantt (https://codeberg.org/fds2610/NC-Gantt) is a project planning
app (Gantt chart) for Nextcloud. Projects, subprojects and tasks can be linked to Deck
boards, lists and cards, so that planning and day-to-day work stay in one place: the
plan hands work over to Deck, and Deck stays the single place where that work is done.
What we do today. Deck has an excellent read channel — since Deck 1.18 the
webhook-compatible CardCreatedEvent / CardUpdatedEvent / CardDeletedEvent (#7910) give
us everything we need to follow changes made in Deck. Thank you for those; this
request is only about the other direction.
For writing we have no supported option, so we call Deck's internal services from a
single adapter class (DeckGateway), fetched from the container at call time so that
our app still loads without Deck: CardService (find, create, update, archive),
AssignmentService::assignUser(), BoardService::find(), StackMapper (find, findAll).
These are not meant as an API, and we treat them accordingly: one adapter class, a
contract test that checks every class, method parameter and entity field we touch
against the installed Deck, and a documented review of stable31…stable35 plus master
before every release. That keeps the risk visible, but it does not remove it — and it
puts work on you too, because any refactoring in these services can silently break
third-party apps you never hear about.
Why the internal services are hard to use correctly
gained $done, $startdate and $color, partly in the middle of the parameter list. We
now call create() and update() with named arguments resolved through reflection,
because a positional call would break on the next release. That is a workaround, not
an integration.
the user as private ?string $userId at construction time. In a background job or an
occ command there is no session, so we have to set the "volatile active user" before
calling Deck — and hope that is enough for every code path inside Deck. An API that
takes the acting user as a parameter would make this correct by construction.
only want to move a due date. So every write is a read-modify-write over the whole
card, which loses concurrent edits made in Deck between our read and our write —
exactly the thing a planning app that writes dates must not do. (Same pain as API: Updating items should not require all parameters to be set #1578 on
the REST side.) Deck already has OptionalNullableValue for done and color, so the
idea of "field not supplied ≠ field set to null" exists in the code base; we would
like it for all fields.
Why not the REST/OCS API? An app running inside the same server would have to call its
own server over HTTP, with credentials it does not have, losing the acting user's
session and the transaction context. Talk's "create card" goes that way today (#8116);
we would rather not add another one.
What we need
| Operation | Data
|
|--------------------------------|----------------------------------------------------
-------------------------------------------|
| Create a card | title, description, target list (stack), due date,
start date |
| Read a card | id, title, description, stack/board, due date,
start date, done, archived, deleted, assignees |
| Set dates | due date and start date, each independently, "leave
unchanged" distinguishable from "clear" |
| Mark done / undone | —
|
| Assign / unassign a user | card, user id; a clear, catchable error when the
account has no access to the board |
| Archive a card | (we never delete a card that a user might still
need) |
| List the stacks of a board | id, title, order — to offer a target list
|
| Permissions of the acting user | read / edit / manage on a board, so the UI can hide
what the user may not do |
Permissions stay with Deck. We are explicitly not asking for a way around Deck's
permission checks. Deck should keep checking the rights of the acting person on every
call, exactly as it does for its own controllers, and refuse otherwise. Our app also
never shares a board on the user's behalf: if an assignment fails because the account
cannot see the board, we want to catch that and tell the user, not fix it silently.
Suggested shape
the container, versioned with @SInCE tags — the same contract style Nextcloud uses
for OCP, and the same promise the webhook-compatible events already made for reading.
construction time, so the API also works in background jobs and occ commands.
OptionalNullableValue is a good starting point).
callers can map them to their own states instead of catching Throwable.
risk; we would rather have seven stable operations than everything Deck can do.
What this would change for us
Once such an API exists, our adapter would use it from that Deck version on and keep
the current internal calls only as a fallback for older versions — and we would drop
them entirely once those versions are out of support. We are happy to help: reviewing
a draft interface, testing a branch against our integration, or contributing the
implementation if you tell us the shape you would accept.