Skip to content

Commit 5ada404

Browse files
committed
feat: implement atomic envelope creation with rollback
Envelope creation now ensures atomicity: - Generate envelope UUID and folderName before creating nodes - Create nodes with correct settings containing folderName - Rollback all changes (nodes, files, envelope) on any error Added dedicated rollback methods: - rollbackEnvelopeCreation: orchestrates complete rollback - rollbackCreatedNodes: removes filesystem nodes - rollbackCreatedFiles: removes file entities from database - rollbackEnvelope: removes envelope entity from database This prevents partial envelope creation and ensures data consistency. Signed-off-by: Vitor Mattos <[email protected]>
1 parent fcfbe65 commit 5ada404

1 file changed

Lines changed: 86 additions & 20 deletions

File tree

lib/Service/RequestSignatureService.php

Lines changed: 86 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,93 @@ public function saveEnvelope(array $data): array {
7979
$userManager = $data['userManager'] ?? null;
8080
$userId = $userManager instanceof IUser ? $userManager->getUID() : null;
8181

82-
$envelope = $this->envelopeService->createEnvelope($envelopeName, $userId);
82+
$envelope = null;
83+
$files = [];
84+
$createdNodes = [];
8385

84-
$envelopeFolderName = 'envelope-' . $envelope->getUuid();
85-
$envelopeSettings = array_merge($data['settings'] ?? [], [
86-
'folderName' => $envelopeFolderName,
87-
]);
86+
try {
87+
$envelope = $this->envelopeService->createEnvelope($envelopeName, $userId);
88+
89+
$envelopeFolderName = 'envelope-' . $envelope->getUuid();
90+
$envelopeSettings = array_merge($data['settings'] ?? [], [
91+
'folderName' => $envelopeFolderName,
92+
]);
93+
94+
foreach ($data['files'] as $fileData) {
95+
if (isset($fileData['uploadedFile'])) {
96+
$node = $this->getNodeFromUploadedFile([
97+
'userManager' => $userManager,
98+
'name' => $fileData['name'],
99+
'uploadedFile' => $fileData['uploadedFile'],
100+
'settings' => $envelopeSettings,
101+
]);
102+
$fileData['node'] = $node;
103+
$createdNodes[] = $node;
104+
}
105+
$fileEntity = $this->createFileForEnvelope(
106+
$fileData,
107+
$userManager,
108+
$envelopeSettings
109+
);
110+
$this->envelopeService->addFileToEnvelope($envelope->getId(), $fileEntity);
111+
$files[] = $fileEntity;
112+
}
88113

89-
$files = [];
90-
foreach ($data['files'] as $fileData) {
91-
$fileEntity = $this->createFileForEnvelope(
92-
$fileData,
93-
$userManager,
94-
$envelopeSettings
95-
);
96-
$this->envelopeService->addFileToEnvelope($envelope->getId(), $fileEntity);
97-
$files[] = $fileEntity;
98-
}
99-
100-
return [
101-
'envelope' => $envelope,
102-
'files' => $files,
103-
];
114+
return [
115+
'envelope' => $envelope,
116+
'files' => $files,
117+
];
118+
} catch (\Throwable $e) {
119+
$this->rollbackEnvelopeCreation($envelope, $files, $createdNodes);
120+
throw $e;
121+
}
122+
}
123+
124+
private function rollbackEnvelopeCreation(?FileEntity $envelope, array $files, array $createdNodes): void {
125+
$this->rollbackCreatedNodes($createdNodes);
126+
$this->rollbackCreatedFiles($files);
127+
$this->rollbackEnvelope($envelope);
128+
}
129+
130+
private function rollbackCreatedNodes(array $nodes): void {
131+
foreach ($nodes as $node) {
132+
try {
133+
$node->delete();
134+
} catch (\Throwable $deleteError) {
135+
$this->logger->error('Failed to rollback created node in envelope', [
136+
'nodeId' => $node->getId(),
137+
'error' => $deleteError->getMessage(),
138+
]);
139+
}
140+
}
141+
}
142+
143+
private function rollbackCreatedFiles(array $files): void {
144+
foreach ($files as $file) {
145+
try {
146+
$this->fileMapper->delete($file);
147+
} catch (\Throwable $deleteError) {
148+
$this->logger->error('Failed to rollback created file entity in envelope', [
149+
'fileId' => $file->getId(),
150+
'error' => $deleteError->getMessage(),
151+
]);
152+
}
153+
}
154+
}
155+
156+
private function rollbackEnvelope(?FileEntity $envelope): void {
157+
if ($envelope === null) {
158+
return;
159+
}
160+
161+
try {
162+
$this->fileMapper->delete($envelope);
163+
} catch (\Throwable $deleteError) {
164+
$this->logger->error('Failed to rollback created envelope', [
165+
'envelopeId' => $envelope->getId(),
166+
'error' => $deleteError->getMessage(),
167+
]);
168+
}
104169
}
105170

106171
private function createFileForEnvelope(array $fileData, ?IUser $userManager, array $settings): FileEntity {
@@ -116,6 +181,7 @@ private function createFileForEnvelope(array $fileData, ?IUser $userManager, arr
116181
'name' => $fileName,
117182
'userManager' => $userManager,
118183
'status' => FileEntity::STATUS_DRAFT,
184+
'settings' => $settings,
119185
]);
120186
}
121187

0 commit comments

Comments
 (0)