-
Notifications
You must be signed in to change notification settings - Fork 338
🧾Add share metadata #8069
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
Open
AndyScherzinger
wants to merge
7
commits into
main
Choose a base branch
from
feat/noid/share-metadata
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
🧾Add share metadata #8069
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
1754b60
feat(migration): add created_at and last_modified_at timestamp column…
510a8db
feat(migration): backfill board last_modified into deck_board_acl sha…
ad2c131
feat(db): record creation and modification timestamps on deck_board_a…
1f1a8ae
test(migration): verify AclTimestampBackfill backfill logic and AclMa…
157cce2
perf(migration): replace N+1 updates in AclTimestampBackfill with gro…
2278db5
fix(meta-data): set/update share meta-data on create/update
AndyScherzinger 7e3e603
docs(version): Bump version to trigger DB migration
AndyScherzinger 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
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 |
|---|---|---|
| @@ -1,96 +1,97 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| - SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors | ||
| - SPDX-License-Identifier: AGPL-3.0-or-later | ||
| --> | ||
| <info xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd"> | ||
| <id>deck</id> | ||
| <name>Deck</name> | ||
| <summary>Personal planning and team project organization</summary> | ||
| <description>Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud. | ||
|
|
||
|
|
||
| - 📥 Add your tasks to cards and put them in order | ||
| - 📄 Write down additional notes in Markdown | ||
| - 🔖 Assign labels for even better organization | ||
| - 👥 Share with your team, friends or family | ||
| - 📎 Attach files and embed them in your Markdown description | ||
| - 💬 Discuss with your team using comments | ||
| - ⚡ Keep track of changes in the activity stream | ||
| - 🚀 Get your project organized | ||
|
|
||
| </description> | ||
| <version>4.0.0-dev.1</version> | ||
| <licence>agpl</licence> | ||
| <author>Julius Härtl</author> | ||
| <namespace>Deck</namespace> | ||
| <types> | ||
| <dav/> | ||
| </types> | ||
| <documentation> | ||
| <user>https://deck.readthedocs.io/en/latest/User_documentation_en/</user> | ||
| <developer>https://deck.readthedocs.io/en/latest/API/</developer> | ||
| </documentation> | ||
| <category>organization</category> | ||
| <category>office</category> | ||
| <website>https://github.com/nextcloud/deck</website> | ||
| <bugs>https://github.com/nextcloud/deck/issues</bugs> | ||
| <repository type="git">https://github.com/nextcloud/deck.git</repository> | ||
| <screenshot>https://download.bitgrid.net/nextcloud/deck/screenshots/1.0/Deck-1.png</screenshot> | ||
| <screenshot>https://download.bitgrid.net/nextcloud/deck/screenshots/1.0/Deck-2.png</screenshot> | ||
| <dependencies> | ||
| <database min-version="9.4">pgsql</database> | ||
| <database>sqlite</database> | ||
| <database min-version="8.0">mysql</database> | ||
| <nextcloud min-version="35" max-version="35"/> | ||
| </dependencies> | ||
| <background-jobs> | ||
| <job>OCA\Deck\Cron\DeleteCron</job> | ||
| <job>OCA\Deck\Cron\ScheduledNotifications</job> | ||
| <job>OCA\Deck\Cron\CardDescriptionActivity</job> | ||
| <job>OCA\Deck\Cron\SessionsCleanup</job> | ||
| </background-jobs> | ||
| <repair-steps> | ||
| <live-migration> | ||
| <step>OCA\Deck\Migration\DeletedCircleCleanup</step> | ||
| </live-migration> | ||
| <post-migration> | ||
| <step>OCA\Deck\Migration\LabelMismatchCleanup</step> | ||
| </post-migration> | ||
| </repair-steps> | ||
| <commands> | ||
| <command>OCA\Deck\Command\UserExport</command> | ||
| <command>OCA\Deck\Command\BoardImport</command> | ||
| <command>OCA\Deck\Command\TransferOwnership</command> | ||
| <command>OCA\Deck\Command\CalendarToggle</command> | ||
| </commands> | ||
| <activity> | ||
| <settings> | ||
| <setting>OCA\Deck\Activity\SettingChanges</setting> | ||
| <setting>OCA\Deck\Activity\SettingDescription</setting> | ||
| <setting>OCA\Deck\Activity\SettingComment</setting> | ||
| </settings> | ||
| <filters> | ||
| <filter>OCA\Deck\Activity\Filter</filter> | ||
| </filters> | ||
| <providers> | ||
| <provider>OCA\Deck\Activity\DeckProvider</provider> | ||
| </providers> | ||
| </activity> | ||
| <fulltextsearch> | ||
| <provider min-version="16">OCA\Deck\Provider\DeckProvider</provider> | ||
| </fulltextsearch> | ||
| <navigations> | ||
| <navigation> | ||
| <name>Deck</name> | ||
| <route>deck.page.index</route> | ||
| <icon>deck.svg</icon> | ||
| <order>10</order> | ||
| </navigation> | ||
| </navigations> | ||
| <sabre> | ||
| <calendar-plugins> | ||
| <plugin>OCA\Deck\DAV\CalendarPlugin</plugin> | ||
| </calendar-plugins> | ||
| </sabre> | ||
| </info> | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| - SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors | ||
| - SPDX-License-Identifier: AGPL-3.0-or-later | ||
| --> | ||
| <info xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd"> | ||
| <id>deck</id> | ||
| <name>Deck</name> | ||
| <summary>Personal planning and team project organization</summary> | ||
| <description>Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud. | ||
|
|
||
|
|
||
| - 📥 Add your tasks to cards and put them in order | ||
| - 📄 Write down additional notes in Markdown | ||
| - 🔖 Assign labels for even better organization | ||
| - 👥 Share with your team, friends or family | ||
| - 📎 Attach files and embed them in your Markdown description | ||
| - 💬 Discuss with your team using comments | ||
| - ⚡ Keep track of changes in the activity stream | ||
| - 🚀 Get your project organized | ||
|
|
||
| </description> | ||
| <version>4.0.0-dev.2</version> | ||
| <licence>agpl</licence> | ||
| <author>Julius Härtl</author> | ||
| <namespace>Deck</namespace> | ||
| <types> | ||
| <dav/> | ||
| </types> | ||
| <documentation> | ||
| <user>https://deck.readthedocs.io/en/latest/User_documentation_en/</user> | ||
| <developer>https://deck.readthedocs.io/en/latest/API/</developer> | ||
| </documentation> | ||
| <category>organization</category> | ||
| <category>office</category> | ||
| <website>https://github.com/nextcloud/deck</website> | ||
| <bugs>https://github.com/nextcloud/deck/issues</bugs> | ||
| <repository type="git">https://github.com/nextcloud/deck.git</repository> | ||
| <screenshot>https://download.bitgrid.net/nextcloud/deck/screenshots/1.0/Deck-1.png</screenshot> | ||
| <screenshot>https://download.bitgrid.net/nextcloud/deck/screenshots/1.0/Deck-2.png</screenshot> | ||
| <dependencies> | ||
| <database min-version="9.4">pgsql</database> | ||
| <database>sqlite</database> | ||
| <database min-version="8.0">mysql</database> | ||
| <nextcloud min-version="35" max-version="35"/> | ||
| </dependencies> | ||
| <background-jobs> | ||
| <job>OCA\Deck\Cron\DeleteCron</job> | ||
| <job>OCA\Deck\Cron\ScheduledNotifications</job> | ||
| <job>OCA\Deck\Cron\CardDescriptionActivity</job> | ||
| <job>OCA\Deck\Cron\SessionsCleanup</job> | ||
| </background-jobs> | ||
| <repair-steps> | ||
| <live-migration> | ||
| <step>OCA\Deck\Migration\DeletedCircleCleanup</step> | ||
| </live-migration> | ||
| <post-migration> | ||
| <step>OCA\Deck\Migration\LabelMismatchCleanup</step> | ||
| <step>OCA\Deck\Migration\AclTimestampBackfill</step> | ||
| </post-migration> | ||
| </repair-steps> | ||
| <commands> | ||
| <command>OCA\Deck\Command\UserExport</command> | ||
| <command>OCA\Deck\Command\BoardImport</command> | ||
| <command>OCA\Deck\Command\TransferOwnership</command> | ||
| <command>OCA\Deck\Command\CalendarToggle</command> | ||
| </commands> | ||
| <activity> | ||
| <settings> | ||
| <setting>OCA\Deck\Activity\SettingChanges</setting> | ||
| <setting>OCA\Deck\Activity\SettingDescription</setting> | ||
| <setting>OCA\Deck\Activity\SettingComment</setting> | ||
| </settings> | ||
| <filters> | ||
| <filter>OCA\Deck\Activity\Filter</filter> | ||
| </filters> | ||
| <providers> | ||
| <provider>OCA\Deck\Activity\DeckProvider</provider> | ||
| </providers> | ||
| </activity> | ||
| <fulltextsearch> | ||
| <provider min-version="16">OCA\Deck\Provider\DeckProvider</provider> | ||
| </fulltextsearch> | ||
| <navigations> | ||
| <navigation> | ||
| <name>Deck</name> | ||
| <route>deck.page.index</route> | ||
| <icon>deck.svg</icon> | ||
| <order>10</order> | ||
| </navigation> | ||
| </navigations> | ||
| <sabre> | ||
| <calendar-plugins> | ||
| <plugin>OCA\Deck\DAV\CalendarPlugin</plugin> | ||
| </calendar-plugins> | ||
| </sabre> | ||
| </info> |
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
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,68 @@ | ||
| <?php | ||
|
|
||
| /** | ||
| * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors | ||
| * SPDX-License-Identifier: AGPL-3.0-or-later | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace OCA\Deck\Migration; | ||
|
|
||
| use OCP\DB\QueryBuilder\IQueryBuilder; | ||
| use OCP\IDBConnection; | ||
| use OCP\Migration\IOutput; | ||
| use OCP\Migration\IRepairStep; | ||
|
|
||
| class AclTimestampBackfill implements IRepairStep { | ||
| public function __construct( | ||
| private IDBConnection $db, | ||
| ) { | ||
| } | ||
|
|
||
| public function getName(): string { | ||
| return 'Backfill board last_modified into deck_board_acl created_at / last_modified_at'; | ||
| } | ||
|
|
||
| public function run(IOutput $output): void { | ||
| $selectQb = $this->db->getQueryBuilder(); | ||
| $selectQb->select('a.id AS acl_id', 'b.last_modified AS board_last_modified') | ||
| ->from('deck_board_acl', 'a') | ||
| ->join('a', 'deck_boards', 'b', $selectQb->expr()->eq('b.id', 'a.board_id')) | ||
| ->where($selectQb->expr()->eq('a.created_at', $selectQb->createNamedParameter(0, IQueryBuilder::PARAM_INT))); | ||
|
|
||
| $result = $selectQb->executeQuery(); | ||
| $rows = $result->fetchAll(); | ||
| $result->closeCursor(); | ||
|
|
||
| if ($rows === []) { | ||
| $output->info('AclTimestampBackfill: no rows to update'); | ||
| return; | ||
| } | ||
|
|
||
| // Group ACL IDs by target timestamp to issue one UPDATE per group | ||
| // rather than one UPDATE per row (avoids N+1 queries). | ||
| $now = time(); | ||
| $groups = []; | ||
| foreach ($rows as $row) { | ||
| $timestamp = ((int)$row['board_last_modified'] > 0) ? (int)$row['board_last_modified'] : $now; | ||
| $groups[$timestamp][] = (int)$row['acl_id']; | ||
| } | ||
|
|
||
| $updated = 0; | ||
| foreach ($groups as $timestamp => $ids) { | ||
| // Chunk at 1000 for Oracle compatibility (same limit used by chunkQuery). | ||
| foreach (array_chunk($ids, 1000) as $chunk) { | ||
| $updateQb = $this->db->getQueryBuilder(); | ||
| $updateQb->update('deck_board_acl') | ||
| ->set('created_at', $updateQb->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT)) | ||
| ->set('last_modified_at', $updateQb->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT)) | ||
| ->where($updateQb->expr()->in('id', $updateQb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY))); | ||
| $updateQb->executeStatement(); | ||
| $updated += count($chunk); | ||
| } | ||
| } | ||
|
|
||
| $output->info('AclTimestampBackfill: updated ' . $updated . ' row(s)'); | ||
| } | ||
| } | ||
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,41 @@ | ||
| <?php | ||
|
|
||
| /** | ||
| * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors | ||
| * SPDX-License-Identifier: AGPL-3.0-or-later | ||
| */ | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace OCA\Deck\Migration; | ||
|
|
||
| use Closure; | ||
| use OCP\DB\ISchemaWrapper; | ||
| use OCP\Migration\IOutput; | ||
| use OCP\Migration\SimpleMigrationStep; | ||
|
|
||
| class Version11002Date20260611000000 extends SimpleMigrationStep { | ||
| public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { | ||
| /** @var ISchemaWrapper $schema */ | ||
| $schema = $schemaClosure(); | ||
| $table = $schema->getTable('deck_board_acl'); | ||
|
|
||
| if (!$table->hasColumn('created_at')) { | ||
| $table->addColumn('created_at', 'integer', [ | ||
| 'notnull' => true, | ||
| 'default' => 0, | ||
| 'unsigned' => true, | ||
| ]); | ||
| } | ||
|
|
||
| if (!$table->hasColumn('last_modified_at')) { | ||
| $table->addColumn('last_modified_at', 'integer', [ | ||
| 'notnull' => true, | ||
| 'default' => 0, | ||
| 'unsigned' => true, | ||
| ]); | ||
| } | ||
|
|
||
| return $schema; | ||
| } | ||
| } |
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.
idk if we should really backfill that way, does the app you're doing all that for not have an option to have an unknown value?
The values we're writing in here 99% of the time are not the real created/last_modified of the acl, so an unknown value would be better imo, or at least just the "now" value so it is clear that the value was written when the update was done.
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.
We can use any we would want, the share review app would else have to assume one and either that is a fully hard-coded and fixed date, no matter the share, or needs to be computed each time the shares are loaded for review. So to me, compute-once made the most sense and going with a creation/modification date of the board itself seemed most feasible. However we could also go for
$nowif you think that would be better. But in any care I suggest to pre-compute and migrate to a date and not have a fallback logic because we lacked dates in the past.WDYT @grnd-alt @blizzz ? "No date" feels wrong to me, but that might be me, than we can also just leave it at
0and take that as "unknown".Both has its advantages, one is unknown: cause it hasn't been tracked but mid-term I find this confusing to users when there are shares with known and unknown dates.
Both works for me. I can find a way to explain the unknown in the review app of course.