@happyvertical/smrt-content 0.44.0 → 0.44.1
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/agents/content-list.md +61 -5
- package/dist/chunks/{content-corrections-BxfA3tW1.js → content-corrections-B4mPd_th.js} +6 -3
- package/dist/chunks/content-corrections-B4mPd_th.js.map +1 -0
- package/dist/chunks/{content-query-B4cHfrig.js → content-query-D1bLBzMT.js} +6 -6
- package/dist/chunks/{content-query-B4cHfrig.js.map → content-query-D1bLBzMT.js.map} +1 -1
- package/dist/chunks/{content-reviews-BWrYEQc6.js → content-reviews-lBoqJY7Y.js} +6 -3
- package/dist/chunks/content-reviews-lBoqJY7Y.js.map +1 -0
- package/dist/chunks/{content-versions-OEYQVrUf.js → content-versions-B0OUI1ut.js} +6 -3
- package/dist/chunks/content-versions-B0OUI1ut.js.map +1 -0
- package/dist/chunks/{contents-BrGxWH3s.js → contents-CRG2Snrb.js} +2 -2
- package/dist/chunks/{contents-BrGxWH3s.js.map → contents-CRG2Snrb.js.map} +1 -1
- package/dist/content-contribution.d.ts +1 -1
- package/dist/content-contribution.d.ts.map +1 -1
- package/dist/index.js +12 -9
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +33 -6
- package/dist/server/content-list-actions.d.ts +10 -3
- package/dist/server/content-list-actions.d.ts.map +1 -1
- package/dist/server/content-list-lifecycle.d.ts +20 -0
- package/dist/server/content-list-lifecycle.d.ts.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +189 -25
- package/dist/server.js.map +1 -1
- package/dist/smrt-knowledge.json +17 -5
- package/dist/svelte/components/ContentList.svelte +193 -22
- package/dist/svelte/components/ContentList.svelte.d.ts +5 -0
- package/dist/svelte/components/ContentList.svelte.d.ts.map +1 -1
- package/dist/svelte/components/ContentListLifecyclePanel.svelte +341 -0
- package/dist/svelte/components/ContentListLifecyclePanel.svelte.d.ts +17 -0
- package/dist/svelte/components/ContentListLifecyclePanel.svelte.d.ts.map +1 -0
- package/dist/svelte/content-list-lifecycle.d.ts +132 -0
- package/dist/svelte/content-list-lifecycle.d.ts.map +1 -0
- package/dist/svelte/content-list-lifecycle.js +439 -0
- package/dist/svelte/i18n.contribution.d.ts +27 -0
- package/dist/svelte/i18n.contribution.d.ts.map +1 -1
- package/dist/svelte/i18n.contribution.js +27 -0
- package/dist/svelte/index.d.ts +1 -0
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +1 -0
- package/package.json +15 -15
- package/dist/chunks/content-corrections-BxfA3tW1.js.map +0 -1
- package/dist/chunks/content-reviews-BWrYEQc6.js.map +0 -1
- package/dist/chunks/content-versions-OEYQVrUf.js.map +0 -1
package/agents/content-list.md
CHANGED
|
@@ -1,12 +1,67 @@
|
|
|
1
1
|
<!-- Module doc for packages/content/AGENTS.md. Linked from the Modules table there. -->
|
|
2
2
|
|
|
3
|
-
# ContentList: shared adapter,
|
|
3
|
+
# ContentList: shared adapter, query state, saved views, and lifecycle
|
|
4
4
|
|
|
5
5
|
`ContentList` reads every row, column, filter, and action through one shared
|
|
6
6
|
adapter (`src/svelte/content-list-controller.ts`) over a `DataTableController`,
|
|
7
7
|
and can source those rows either from a client array or from the bounded
|
|
8
8
|
content query endpoint. This doc covers both modes end to end.
|
|
9
9
|
|
|
10
|
+
## Trash, restore, and permanent deletion (#2454)
|
|
11
|
+
|
|
12
|
+
Lifecycle controls are an opt-in server-authoritative seam. Pass a
|
|
13
|
+
`ContentListLifecycleBinding` as `lifecycle`; set `lifecycleMode="trash"` for a
|
|
14
|
+
trash view. Trash mode locks the live status predicate to `deleted`, hides the
|
|
15
|
+
ordinary status control, removes legacy edit/delete buttons, and exposes
|
|
16
|
+
restore, permanent-delete, and empty-trash actions. Omit the binding and
|
|
17
|
+
ContentList keeps its existing `onDelete` behavior.
|
|
18
|
+
|
|
19
|
+
The browser never treats rendered rows as mutation authority. It sends a
|
|
20
|
+
selection reference, canonical query for `all-matching`, expected count, and
|
|
21
|
+
server revision through `createContentListLifecycleTransport()`. Preview,
|
|
22
|
+
initial apply, and every replay use distinct per-attempt request ids. Apply and
|
|
23
|
+
replay retain the opaque confirmation and idempotency authority envelope, while
|
|
24
|
+
the result's `auditReference` continues to identify the original execution.
|
|
25
|
+
Changing the query or selection invalidates the preview; expired, stale-revision,
|
|
26
|
+
row-revision, query-fingerprint, token, or matching-count failures require a
|
|
27
|
+
new preview.
|
|
28
|
+
|
|
29
|
+
Mount `createContentListLifecycleRoute()` from
|
|
30
|
+
`@happyvertical/smrt-content/server` at the transport's default
|
|
31
|
+
`POST /api/v1/contents/lifecycle` path. The host supplies a callback that
|
|
32
|
+
authenticates each native `Request` and returns its current principal/tenant
|
|
33
|
+
action context. The route accepts only the three lifecycle action ids and
|
|
34
|
+
delegates to the same `createContentListActionAdapter()` instance used by agent
|
|
35
|
+
and bulk-workflow callers; it never owns a second authorization or mutation
|
|
36
|
+
path. Invalid JSON, missing authentication, and internal failures return
|
|
37
|
+
bounded error envelopes without exposing private error text.
|
|
38
|
+
|
|
39
|
+
Lifecycle action ids and restore input are stable:
|
|
40
|
+
|
|
41
|
+
| action | eligible server state | input / consequence |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| `move-to-trash` | not already `deleted` | soft-deletes content into trash |
|
|
44
|
+
| `restore` | `deleted` | `{ status: 'draft' \| 'review' \| 'published' }`; the server re-runs permission and publish-readiness checks |
|
|
45
|
+
| `permanent-delete` | `deleted` | irreversible deletion; the operator must type the exact server-resolved count |
|
|
46
|
+
|
|
47
|
+
Permanent deletion binds the row's `updated_at` revision into the final delete.
|
|
48
|
+
On PostgreSQL that comparison is part of the `DELETE` predicate and any cascade
|
|
49
|
+
shares its transaction; embedded adapters compare under the framework's shared
|
|
50
|
+
write queue before cascading. A writer racing preview/apply therefore produces
|
|
51
|
+
`row_revision_drifted` instead of deleting newer content.
|
|
52
|
+
|
|
53
|
+
The result details expose `count`, accepted/skipped/failed counts,
|
|
54
|
+
representative labels, canonical subtype-aware outcomes
|
|
55
|
+
(`resourceType`/`resourceId`), and `auditReference`. Applying a partial result
|
|
56
|
+
removes only accepted ids from selection, keeping skipped and failed rows
|
|
57
|
+
selected for inspection or retry. The exact query refreshes after success;
|
|
58
|
+
progress, partial exceptions, and the audit reference remain visible in a
|
|
59
|
+
polite live region. Empty trash is available only when an exact server count
|
|
60
|
+
and canonical query are present, so a page-sized guess cannot stand in for its
|
|
61
|
+
scope. `maxSelectionSize` defaults to 200; larger matching sets are announced
|
|
62
|
+
and fail closed until the operator narrows the query, matching the server's
|
|
63
|
+
bounded one-preview selection contract.
|
|
64
|
+
|
|
10
65
|
## Realtime, freshness, and background workflows (#2455)
|
|
11
66
|
|
|
12
67
|
A server-backed list consumes the complete reactive seam exposed by
|
|
@@ -965,10 +1020,11 @@ keeps the control from misstating the query; `readContentListFilter` stays
|
|
|
965
1020
|
value-only and must not drive a control. Choosing any real option replaces every
|
|
966
1021
|
filter on that column, so the operator is never stuck.
|
|
967
1022
|
|
|
968
|
-
`review` is now offered outright. `deleted` is deliberately not
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
list is a display vocabulary rather
|
|
1023
|
+
`review` is now offered outright. `deleted` is deliberately not part of the
|
|
1024
|
+
ordinary status vocabulary: the opt-in trash lifecycle locks that predicate
|
|
1025
|
+
and supplies the restore/purge affordances as one inseparable mode.
|
|
1026
|
+
`Content.type` is freeform, so its option list is a display vocabulary rather
|
|
1027
|
+
than the model's domain.
|
|
972
1028
|
|
|
973
1029
|
Everything a restore or a translation refused is reported in one dismissible
|
|
974
1030
|
notice rather than thrown — a stale link or an out-of-date saved view must still
|
|
@@ -52,8 +52,11 @@ var ContentCorrection = class extends SmrtObject {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
|
-
__decorateClass([foreignKey("Content", {
|
|
56
|
-
|
|
55
|
+
__decorateClass([foreignKey("Content", {
|
|
56
|
+
required: true,
|
|
57
|
+
onDelete: "CASCADE"
|
|
58
|
+
})], ContentCorrection.prototype, "contentId", 2);
|
|
59
|
+
__decorateClass([foreignKey("ContentVersion", { onDelete: "CASCADE" })], ContentCorrection.prototype, "contentVersionId", 2);
|
|
57
60
|
__decorateClass([crossPackageRef("@happyvertical/smrt-facts:Fact")], ContentCorrection.prototype, "factId", 2);
|
|
58
61
|
__decorateClass([crossPackageRef("@happyvertical/smrt-facts:Fact")], ContentCorrection.prototype, "replacementFactId", 2);
|
|
59
62
|
__decorateClass([tenantId({ nullable: true })], ContentCorrection.prototype, "tenantId", 2);
|
|
@@ -104,4 +107,4 @@ var ContentCorrectionCollection = class extends SmrtCollection {
|
|
|
104
107
|
//#endregion
|
|
105
108
|
export { content_corrections_exports as n, ContentCorrection as r, ContentCorrectionCollection as t };
|
|
106
109
|
|
|
107
|
-
//# sourceMappingURL=content-corrections-
|
|
110
|
+
//# sourceMappingURL=content-corrections-B4mPd_th.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-corrections-B4mPd_th.js","names":[],"sources":["../../src/content-correction.ts","../../src/content-corrections.ts"],"sourcesContent":["import type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport type {\n ContentCorrectionStatus,\n ContentCorrectionType,\n} from './content-governance';\n\nexport interface ContentCorrectionOptions extends SmrtObjectOptions {\n contentId?: string;\n contentVersionId?: string;\n factId?: string;\n replacementFactId?: string;\n correctionType?: ContentCorrectionType;\n status?: ContentCorrectionStatus;\n summary?: string;\n incorrectText?: string;\n correctedText?: string;\n publicNote?: string;\n metadata?: string | Record<string, unknown>;\n tenantId?: string | null;\n publishedAt?: Date | null;\n createdAt?: Date;\n updatedAt?: Date;\n}\n\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableName: 'content_corrections',\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get', 'create', 'update'] },\n cli: true,\n})\nexport class ContentCorrection extends SmrtObject {\n @foreignKey('Content', { required: true, onDelete: 'CASCADE' })\n contentId = '';\n\n @foreignKey('ContentVersion', { onDelete: 'CASCADE' })\n contentVersionId = '';\n\n @crossPackageRef('@happyvertical/smrt-facts:Fact')\n factId = '';\n\n @crossPackageRef('@happyvertical/smrt-facts:Fact')\n replacementFactId = '';\n correctionType: ContentCorrectionType = 'fact';\n status: ContentCorrectionStatus = 'draft';\n summary = '';\n incorrectText = '';\n correctedText = '';\n publicNote = '';\n metadata = '';\n\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n publishedAt: Date | null = null;\n createdAt = new Date();\n updatedAt = new Date();\n\n constructor(options: ContentCorrectionOptions = {}) {\n super(options);\n if (options.contentId) this.contentId = options.contentId;\n if (options.contentVersionId !== undefined)\n this.contentVersionId = options.contentVersionId;\n if (options.factId !== undefined) this.factId = options.factId;\n if (options.replacementFactId !== undefined)\n this.replacementFactId = options.replacementFactId;\n if (options.correctionType !== undefined)\n this.correctionType = options.correctionType;\n if (options.status !== undefined) this.status = options.status;\n if (options.summary !== undefined) this.summary = options.summary;\n if (options.incorrectText !== undefined)\n this.incorrectText = options.incorrectText;\n if (options.correctedText !== undefined)\n this.correctedText = options.correctedText;\n if (options.publicNote !== undefined) this.publicNote = options.publicNote;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.publishedAt !== undefined)\n this.publishedAt = options.publishedAt;\n if (options.createdAt) this.createdAt = options.createdAt;\n if (options.updatedAt) this.updatedAt = options.updatedAt;\n\n if (options.metadata !== undefined) {\n this.metadata =\n typeof options.metadata === 'string'\n ? options.metadata\n : JSON.stringify(options.metadata);\n }\n }\n\n getMetadata(): Record<string, unknown> {\n try {\n return this.metadata ? JSON.parse(this.metadata) : {};\n } catch {\n return {};\n }\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport { ContentCorrection } from './content-correction';\n\nexport class ContentCorrectionCollection extends SmrtCollection<ContentCorrection> {\n static readonly _itemClass = ContentCorrection;\n\n async listForContent(contentId: string): Promise<ContentCorrection[]> {\n return this.list({\n where: { contentId },\n orderBy: 'created_at DESC',\n });\n }\n\n async getPublishedForContent(\n contentId: string,\n ): Promise<ContentCorrection[]> {\n return this.list({\n where: { contentId, status: 'published' },\n orderBy: 'published_at DESC',\n });\n }\n\n async issue(\n options: ConstructorParameters<typeof ContentCorrection>[0],\n ): Promise<ContentCorrection> {\n if (!options) {\n return this.create({});\n }\n\n return this.create({\n ...options,\n metadata:\n typeof options.metadata === 'string'\n ? options.metadata\n : options.metadata\n ? JSON.stringify(options.metadata)\n : undefined,\n });\n }\n}\n"],"mappings":"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"}
|