From ac6c0c44b9e8f511fa40536e91b22c912e85ddf8 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Thu, 11 Dec 2025 09:33:18 -0300 Subject: [PATCH 1/4] fix: add status and created_at fields to file upload response Return status, statusText and created_at in the API response after file upload to display immediately in the files list without needing to reload. Also removed unused etag, path and type fields. Uses FileMapper to get status text and returns FileEntity directly from save() method instead of additional database query. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Controller/FileController.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Controller/FileController.php b/lib/Controller/FileController.php index db3525c9b6..dc2cf23192 100644 --- a/lib/Controller/FileController.php +++ b/lib/Controller/FileController.php @@ -12,6 +12,7 @@ use OCA\Files_Sharing\SharedStorage; use OCA\Libresign\AppInfo\Application; use OCA\Libresign\Db\File as FileEntity; +use OCA\Libresign\Db\FileMapper; use OCA\Libresign\Db\SignRequestMapper; use OCA\Libresign\Exception\LibresignException; use OCA\Libresign\Helper\JSActions; @@ -62,6 +63,7 @@ public function __construct( private IUserSession $userSession, private SessionService $sessionService, private SignRequestMapper $signRequestMapper, + private FileMapper $fileMapper, private IdentifyMethodService $identifyMethodService, private RequestSignatureService $requestSignatureService, private AccountService $accountService, @@ -438,16 +440,16 @@ public function save(array $file, string $name = '', array $settings = []): Data 'userManager' => $this->userSession->getUser(), 'status' => FileEntity::STATUS_DRAFT, ]; - $this->requestSignatureService->save($data); + $file = $this->requestSignatureService->save($data); return new DataResponse( [ 'message' => $this->l10n->t('Success'), 'name' => $name, 'id' => $node->getId(), - 'etag' => $node->getEtag(), - 'path' => $node->getPath(), - 'type' => $node->getType(), + 'status' => $file->getStatus(), + 'statusText' => $this->fileMapper->getTextOfStatus($file->getStatus()), + 'created_at' => $file->getCreatedAt()->format(\DateTimeInterface::ATOM), ], Http::STATUS_OK ); From 12e08cc2269d9e19d4498509a99150cb6ba67027 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Thu, 11 Dec 2025 09:46:45 -0300 Subject: [PATCH 2/4] docs: update LibresignNextcloudFile type definition Update psalm type to reflect the actual fields returned by the file upload endpoint: status, statusText, and created_at instead of etag, path, and type. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/ResponseDefinitions.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 45ebfc0ce0..1b811823a6 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -44,9 +44,9 @@ * message: string, * name: string, * id: int, - * etag: string, - * path: string, - * type: string, + * status: int, + * statusText: string, + * created_at: string, * } * @psalm-type LibresignIdentifyAccount = array{ * id: non-negative-int, From ed27dc3cd43b91b9d42d1a4037a41d2a12d2b204 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Thu, 11 Dec 2025 09:47:55 -0300 Subject: [PATCH 3/4] docs: regenerate OpenAPI documentation Update OpenAPI spec and TypeScript types to reflect changes in LibresignNextcloudFile response type with status, statusText, and created_at fields. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- openapi-full.json | 15 ++++++++------- openapi.json | 15 ++++++++------- src/types/openapi/openapi-full.ts | 7 ++++--- src/types/openapi/openapi.ts | 7 ++++--- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/openapi-full.json b/openapi-full.json index 2f9c5fc7f6..2dfd0dd25c 100644 --- a/openapi-full.json +++ b/openapi-full.json @@ -527,9 +527,9 @@ "message", "name", "id", - "etag", - "path", - "type" + "status", + "statusText", + "created_at" ], "properties": { "message": { @@ -542,13 +542,14 @@ "type": "integer", "format": "int64" }, - "etag": { - "type": "string" + "status": { + "type": "integer", + "format": "int64" }, - "path": { + "statusText": { "type": "string" }, - "type": { + "created_at": { "type": "string" } } diff --git a/openapi.json b/openapi.json index 40c56ead10..7aa0a06562 100644 --- a/openapi.json +++ b/openapi.json @@ -457,9 +457,9 @@ "message", "name", "id", - "etag", - "path", - "type" + "status", + "statusText", + "created_at" ], "properties": { "message": { @@ -472,13 +472,14 @@ "type": "integer", "format": "int64" }, - "etag": { - "type": "string" + "status": { + "type": "integer", + "format": "int64" }, - "path": { + "statusText": { "type": "string" }, - "type": { + "created_at": { "type": "string" } } diff --git a/src/types/openapi/openapi-full.ts b/src/types/openapi/openapi-full.ts index 056feb247b..554d3c9294 100644 --- a/src/types/openapi/openapi-full.ts +++ b/src/types/openapi/openapi-full.ts @@ -1611,9 +1611,10 @@ export type components = { name: string; /** Format: int64 */ id: number; - etag: string; - path: string; - type: string; + /** Format: int64 */ + status: number; + statusText: string; + created_at: string; }; Notify: { date: string; diff --git a/src/types/openapi/openapi.ts b/src/types/openapi/openapi.ts index c296233c7b..77df93997d 100644 --- a/src/types/openapi/openapi.ts +++ b/src/types/openapi/openapi.ts @@ -1155,9 +1155,10 @@ export type components = { name: string; /** Format: int64 */ id: number; - etag: string; - path: string; - type: string; + /** Format: int64 */ + status: number; + statusText: string; + created_at: string; }; Notify: { date: string; From 15b6f266b0f77e0add74773eec3a40183297286f Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Thu, 11 Dec 2025 11:08:20 -0300 Subject: [PATCH 4/4] feat: introduce FileStatus enum for type-safe status handling Add FileStatus backed enum to provide compile-time type safety for file status values. This replaces the previous int-based approach with a proper enum that: - Eliminates the need for default fallback in match expressions - Provides IDE autocomplete for all valid status values - Throws ValueError for invalid status codes instead of silently returning unknown status - Accepts both int and FileStatus for backward compatibility Updated getTextOfStatus() to use FileStatus enum with automatic conversion from int via FileStatus::from(). Removed null return type as status column is NOT NULL in database, ensuring statusText is always a string. This improves code maintainability and prevents invalid status values from being used throughout the codebase. Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Db/FileMapper.php | 19 +++++++++++-------- lib/Db/IdDocsMapper.php | 2 +- lib/Enum/FileStatus.php | 24 ++++++++++++++++++++++++ lib/ResponseDefinitions.php | 2 +- 4 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 lib/Enum/FileStatus.php diff --git a/lib/Db/FileMapper.php b/lib/Db/FileMapper.php index 28dc846700..1f3f2fda51 100644 --- a/lib/Db/FileMapper.php +++ b/lib/Db/FileMapper.php @@ -8,6 +8,7 @@ namespace OCA\Libresign\Db; +use OCA\Libresign\Enum\FileStatus; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\QBMapper; use OCP\Comments\ICommentsManager; @@ -245,21 +246,23 @@ public function getFileType(int $id): string { return 'not_libresign_file'; } - public function getTextOfStatus(int $status): ?string { + public function getTextOfStatus(int|FileStatus $status): string { + if (is_int($status)) { + $status = FileStatus::from($status); + } return match ($status) { // TRANSLATORS Name of the status when document is not a LibreSign file - File::STATUS_NOT_LIBRESIGN_FILE => $this->l->t('not LibreSign file'), + FileStatus::NOT_LIBRESIGN_FILE => $this->l->t('not LibreSign file'), // TRANSLATORS Name of the status that the document is still as a draft - File::STATUS_DRAFT => $this->l->t('draft'), + FileStatus::DRAFT => $this->l->t('draft'), // TRANSLATORS Name of the status that the document can be signed - File::STATUS_ABLE_TO_SIGN => $this->l->t('available for signature'), + FileStatus::ABLE_TO_SIGN => $this->l->t('available for signature'), // TRANSLATORS Name of the status when the document has already been partially signed - File::STATUS_PARTIAL_SIGNED => $this->l->t('partially signed'), + FileStatus::PARTIAL_SIGNED => $this->l->t('partially signed'), // TRANSLATORS Name of the status when the document has been completely signed - File::STATUS_SIGNED => $this->l->t('signed'), + FileStatus::SIGNED => $this->l->t('signed'), // TRANSLATORS Name of the status when the document was deleted - File::STATUS_DELETED => $this->l->t('deleted'), - default => '', + FileStatus::DELETED => $this->l->t('deleted'), }; } diff --git a/lib/Db/IdDocsMapper.php b/lib/Db/IdDocsMapper.php index 801a597d07..76e58cdfb3 100644 --- a/lib/Db/IdDocsMapper.php +++ b/lib/Db/IdDocsMapper.php @@ -303,7 +303,7 @@ private function getIdDocStatusText(int $status): string { return match ($status) { File::STATUS_ABLE_TO_SIGN => $this->l10n->t('waiting for approval'), File::STATUS_SIGNED => $this->l10n->t('approved'), - default => $this->fileMapper->getTextOfStatus($status) ?? '', + default => $this->fileMapper->getTextOfStatus($status), }; } } diff --git a/lib/Enum/FileStatus.php b/lib/Enum/FileStatus.php new file mode 100644 index 0000000000..8157c3b63d --- /dev/null +++ b/lib/Enum/FileStatus.php @@ -0,0 +1,24 @@ +