@adobe/spacecat-shared-data-access 3.81.0 → 4.0.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## [@adobe/spacecat-shared-data-access-v4.0.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v3.81.0...@adobe/spacecat-shared-data-access-v4.0.0) (2026-07-03)
2
+
3
+ ### ⚠ BREAKING CHANGES
4
+
5
+ * **data-access:** drop startedAt/result/error from Preflight schema (SITES-47254) (#1740)
6
+
7
+ ### Features
8
+
9
+ * **data-access:** drop startedAt/result/error from Preflight schema (SITES-47254) ([#1740](https://github.com/adobe/spacecat-shared/issues/1740)) ([5b728bb](https://github.com/adobe/spacecat-shared/commit/5b728bb623060289221e744088b9762a8acfe519)), closes [#2713](https://github.com/adobe/spacecat-shared/issues/2713) [#2713](https://github.com/adobe/spacecat-shared/issues/2713) [post-#2713](https://github.com/adobe/post-/issues/2713)
10
+
1
11
  ## [@adobe/spacecat-shared-data-access-v3.81.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v3.80.0...@adobe/spacecat-shared-data-access-v3.81.0) (2026-07-02)
2
12
 
3
13
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-data-access",
3
- "version": "3.81.0",
3
+ "version": "4.0.0",
4
4
  "description": "Shared modules of the Spacecat Services - Data Access",
5
5
  "type": "module",
6
6
  "engines": {
@@ -12,6 +12,13 @@
12
12
 
13
13
  import type { BaseCollection, BaseModel } from '../base';
14
14
 
15
+ // Note on nullable return types: `postgrest.utils.js::normalizeModelValue()`
16
+ // maps DB NULL → JS `undefined` (the key is skipped on `this.record`
17
+ // entirely), so auto-generated getters return `T | undefined` — never
18
+ // `T | null` — for nullable columns. Callers checking `=== null` on these
19
+ // will silently miss the unfinished-job branch. Existing declarations
20
+ // that read `... | null` predate this PR; the lifecycle additions below
21
+ // match the runtime contract.
15
22
  export interface AsyncJob extends BaseModel {
16
23
  getStatus(): string;
17
24
  getResultLocation(): string;
@@ -20,6 +27,8 @@ export interface AsyncJob extends BaseModel {
20
27
  getError(): { code: string; message: string; details?: object } | null;
21
28
  getMetadata(): object | null;
22
29
  getRecordExpiressAt(): number;
30
+ getStartedAt(): string | undefined;
31
+ getEndedAt(): string | undefined;
23
32
  setStatus(status: string): void;
24
33
  setResultLocation(location: string): void;
25
34
  setResultType(type: string): void;
@@ -27,6 +36,8 @@ export interface AsyncJob extends BaseModel {
27
36
  setError(error: { code: string; message: string; details?: object }): void;
28
37
  setMetadata(metadata: object): void;
29
38
  setExpiresAt(expiresAt: number): void;
39
+ setStartedAt(startedAt: string): void;
40
+ setEndedAt(endedAt: string): void;
30
41
  }
31
42
 
32
43
  export interface AsyncJobCollection extends BaseCollection<AsyncJob> {
@@ -12,6 +12,7 @@
12
12
 
13
13
  import type { AsyncJob, BaseCollection, BaseModel, Site } from '../index.js';
14
14
 
15
+ // SITES-47254: startedAt/result/error live on AsyncJob — fetch via getAsyncJob().
15
16
  export interface Preflight extends BaseModel {
16
17
  getSiteId(): string;
17
18
  getSite(): Promise<Site>;
@@ -20,18 +21,14 @@ export interface Preflight extends BaseModel {
20
21
  getUrl(): string;
21
22
  getStatus(): string;
22
23
  getCreatedBy(): { email: string; displayName?: string };
23
- getStartedAt(): string | null;
24
- getEndedAt(): string | null;
25
- getResult(): object | null;
26
- getError(): { code: string; message: string } | null;
24
+ // `string | undefined` (not `| null`) because normalizeModelValue maps
25
+ // DB NULL → undefined on read — see AsyncJob/index.d.ts header.
26
+ getEndedAt(): string | undefined;
27
27
 
28
28
  setUrl(url: string): Preflight;
29
29
  setStatus(status: 'IN_PROGRESS' | 'COMPLETED' | 'FAILED' | 'CANCELLED'): Preflight;
30
30
  setCreatedBy(createdBy: { email: string; displayName?: string }): Preflight;
31
- setStartedAt(startedAt: string): Preflight;
32
31
  setEndedAt(endedAt: string): Preflight;
33
- setResult(result: object): Preflight;
34
- setError(error: { code: string; message: string }): Preflight;
35
32
  }
36
33
 
37
34
  export interface PreflightCollection extends BaseCollection<Preflight> {
@@ -17,6 +17,11 @@ import SchemaBuilder from '../base/schema.builder.js';
17
17
  import Preflight from './preflight.model.js';
18
18
  import PreflightCollection from './preflight.collection.js';
19
19
 
20
+ // SITES-47254: `startedAt`, `result`, and `error` live only on AsyncJob now —
21
+ // the underlying preflights table no longer carries them. Consumers fetch the
22
+ // joined AsyncJob (e.g., `await preflight.getAsyncJob()`) for lifecycle
23
+ // internals; `status` and `endedAt` remain here as a denormalized cache the
24
+ // projector keeps in sync.
20
25
  const schema = new SchemaBuilder(Preflight, PreflightCollection)
21
26
  .addReference('belongs_to', 'Site', [], { required: true })
22
27
  .addReference('belongs_to', 'AsyncJob', [], { required: true })
@@ -30,34 +35,22 @@ const schema = new SchemaBuilder(Preflight, PreflightCollection)
30
35
  required: true,
31
36
  default: Preflight.Status.IN_PROGRESS,
32
37
  })
33
- // `createdBy` and `error` use type 'any' (matching neighbor `result`) because
34
- // ElectroDB's `map` type requires a `properties` schema for every sub-key,
35
- // and the validate function below already enforces the precise shape — a
36
- // duplicate `properties` declaration adds nothing. Declaring `type: 'map'`
37
- // here without `properties` was the original definition and throws
38
- // `InvalidAttributeDefinition` at Service construction, blocking any
39
- // downstream consumer that builds a v1 `new Service(EntityRegistry.getEntities())`
40
- // (e.g. spacecat-api-service `fixes.test.js`).
38
+ // `createdBy` uses type 'any' because ElectroDB's `map` type requires a
39
+ // `properties` schema for every sub-key, and the validate function below
40
+ // already enforces the precise shape — a duplicate `properties` declaration
41
+ // adds nothing. Declaring `type: 'map'` here without `properties` was the
42
+ // original definition and throws `InvalidAttributeDefinition` at Service
43
+ // construction, blocking any downstream consumer that builds a v1
44
+ // `new Service(EntityRegistry.getEntities())` (e.g. spacecat-api-service
45
+ // `fixes.test.js`).
41
46
  .addAttribute('createdBy', {
42
47
  type: 'any',
43
48
  required: true,
44
49
  validate: (value) => isObject(value) && typeof value.email === 'string' && value.email.length > 0,
45
50
  })
46
- .addAttribute('startedAt', {
47
- type: 'string',
48
- validate: (value) => !value || isIsoDate(value),
49
- })
50
51
  .addAttribute('endedAt', {
51
52
  type: 'string',
52
53
  validate: (value) => !value || isIsoDate(value),
53
- })
54
- .addAttribute('result', {
55
- type: 'any',
56
- validate: (value) => !value || isObject(value),
57
- })
58
- .addAttribute('error', {
59
- type: 'any',
60
- validate: (value) => !value || (isObject(value) && typeof value.code === 'string' && value.code.length > 0 && typeof value.message === 'string' && value.message.length > 0),
61
54
  });
62
55
 
63
56
  export default schema.build();