@appweaver/create-weaver-app 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -280,8 +280,9 @@ exchange succeeds.
280
280
  ### Connected accounts
281
281
 
282
282
  `ConnectedAccount` pairs a provider account with a local user: `provider`, `providerAccountId`, `scope`, `lastLoginAt`
283
- (`createdAt` holds the link date) and a relation to the auth model, indexed on `[provider, providerAccountId]`. A
284
- provider account belongs to one user only — relinking it elsewhere fails with a 403.
283
+ (`createdAt` holds the link date) and a relation to the auth model, unique on `[provider, providerAccountId]`. A
284
+ provider account belongs to one user only — relinking it elsewhere fails with a 403, also when two first sign-ins race
285
+ to create the link.
285
286
 
286
287
  The table exists when any OAuth2 provider is enabled; `SECURITY_OAUTH2_CONNECTED_ACCOUNTS_KEEP_DATABASE_TABLE=true`
287
288
  keeps it after disabling OAuth2, like `SECURITY_API_KEY_KEEP_DATABASE_TABLE` does for API keys.
@@ -328,11 +328,30 @@ await fileService.deleteFile(
328
328
 
329
329
  ### Deleting all files on resource deletion
330
330
 
331
- When a resource is deleted, files belonging to file fields configured with `onResourceDeleted: 'delete'` can be
332
- automatically cleaned up. This is handled by `deleteResourceFiles()`, which is called automatically by the framework's
333
- delete route handler.
331
+ When a resource is deleted, its stored files are cleaned up automatically, as configured per file field:
334
332
 
335
- To enable automatic file cleanup, set `onResourceDeleted: 'delete'` on the file field in your model config:
333
+ | Option | Applies to | Default |
334
+ |-------------------------|----------------------------------------------|------------|
335
+ | `onResourceDeleted` | A resource removed from the database | `'delete'` |
336
+ | `onResourceSoftDeleted` | A soft deleted resource (model `softDelete`) | `'keep'` |
337
+
338
+ Both options behave the same way:
339
+
340
+ - `'delete'` removes the file from the storage and its `File` row from the database.
341
+ - `'keep'` retains the file in the storage and its `File` row in the database, e.g. for audit, but never serves it
342
+ again: the row is soft deleted with the same `deletedAt` and `deletedById` values as its resource, and downloads
343
+ respond with 404 whatever the file access type is.
344
+
345
+ The resource service `delete` method removes them once the delete commits, whether it is called by the delete route or
346
+ directly from code, together with the files of every record deleted with it through an `onDelete: 'cascade'` relation.
347
+ The same happens to the orphans an `update` deletes through a relation with `orphanRemoval: true`.
348
+
349
+ The kept files are marked in the same transaction as the delete, while the removed ones leave the storage once it
350
+ commits. A model with `softDelete` enabled keeps the files of its deleted records by default, so a manual restore loses
351
+ nothing; set `onResourceSoftDeleted: 'delete'` on a field to remove its files on a soft delete too.
352
+
353
+ The framework never removes kept files by itself. Purging them after a retention period is up to the application, e.g.
354
+ with a scheduled job removing the `File` rows with an old `deletedAt` and their stored files.
336
355
 
337
356
  ```ts
338
357
  const config = {
@@ -343,16 +362,20 @@ const config = {
343
362
  },
344
363
  documents: {
345
364
  array: true,
346
- onResourceDeleted: 'keep' // opt out: files are kept
365
+ onResourceDeleted: 'keep' // opt out: files are retained, but no longer served
366
+ },
367
+ idScan: {
368
+ onResourceSoftDeleted: 'delete' // also removed when the resource is soft deleted
347
369
  }
348
370
  }
349
371
  };
350
372
  ```
351
373
 
352
- You can also call `deleteResourceFiles` manually if needed:
374
+ You can also call `deleteResourceFiles` manually if needed, or `deleteResourcesFiles` for many records of one model:
353
375
 
354
376
  ```ts
355
377
  await fileService.deleteResourceFiles('Post', postId);
378
+ await fileService.deleteResourcesFiles('Post', [firstId, secondId]);
356
379
  ```
357
380
 
358
381
  ### Owning resource reference
@@ -2,7 +2,8 @@
2
2
  "$schema": "./node_modules/@appweaver/common/config/schema.json",
3
3
  "config": {
4
4
  "log": {
5
- "level": "silent"
5
+ "level": "silent",
6
+ "sync": true
6
7
  },
7
8
  "database": {
8
9
  "url": "{{DATABASE_TEST_URL}}",