@agent-native/core 0.124.0 → 0.124.2
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +25 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/assets/branding/favicon-base64.ts +5 -0
- package/corpus/core/src/cli/templates-meta.ts +1 -0
- package/corpus/core/src/server/email.ts +2 -5
- package/corpus/templates/analytics/server/lib/dashboard-report-render.ts +6 -3
- package/corpus/templates/analytics/server/lib/report-chart-svg.ts +18 -5
- package/corpus/templates/crm/actions/_crm-list-utils.ts +178 -0
- package/corpus/templates/crm/actions/add-crm-record-to-list.ts +23 -2
- package/corpus/templates/crm/actions/create-crm-list.ts +229 -43
- package/corpus/templates/crm/actions/create-crm-record.ts +13 -5
- package/corpus/templates/crm/actions/update-crm-list-entry.ts +1 -1
- package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +22 -2
- package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +143 -32
- package/corpus/templates/crm/app/components/crm/board/CrmBoard.tsx +190 -75
- package/corpus/templates/crm/app/components/crm/grid/CrmGrid.tsx +267 -115
- package/corpus/templates/crm/app/components/crm/grid/GridCell.tsx +265 -131
- package/corpus/templates/crm/app/components/crm/record/AttributePanel.tsx +79 -100
- package/corpus/templates/crm/app/components/crm/record/RecordHeader.tsx +12 -8
- package/corpus/templates/crm/app/components/crm/record/RecordLists.tsx +27 -31
- package/corpus/templates/crm/app/components/crm/record/RecordTabs.tsx +16 -13
- package/corpus/templates/crm/app/components/crm/record/attribute-row.tsx +108 -0
- package/corpus/templates/crm/app/components/crm/record/field-editors.tsx +201 -9
- package/corpus/templates/crm/app/components/crm/record/panel-resize.ts +61 -0
- package/corpus/templates/crm/app/components/crm/record/record-data.ts +5 -4
- package/corpus/templates/crm/app/components/crm/shared/README-tokens.md +103 -0
- package/corpus/templates/crm/app/components/crm/shared/RecordReferencePicker.tsx +117 -0
- package/corpus/templates/crm/app/components/crm/shared/attribute-value.ts +84 -0
- package/corpus/templates/crm/app/components/crm/shared/ui-tokens.ts +89 -0
- package/corpus/templates/crm/app/global.css +170 -0
- package/corpus/templates/crm/app/i18n/en-US.ts +1 -0
- package/corpus/templates/crm/changelog/2026-07-26-a-half-typed-number-or-date-no-longer-saves-as-empty-the-fie.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-a-new-pipeline-board-now-opens-with-stage-columns-a-summabl.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-record-reference-fields-like-account-can-now-be-linked-from-.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-26-retyping-a-record-field-now-replaces-the-old-value-instead-o.md +6 -0
- package/dist/assets/branding/favicon-base64.d.ts +2 -0
- package/dist/assets/branding/favicon-base64.d.ts.map +1 -0
- package/dist/assets/branding/favicon-base64.js +5 -0
- package/dist/assets/branding/favicon-base64.js.map +1 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +1 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/email.js +2 -2
- package/dist/server/email.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/branding/favicon-base64.ts +5 -0
- package/src/cli/templates-meta.ts +1 -0
- package/src/server/email.ts +2 -5
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.124.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7568c67: Fix system email sending failing on serverless (ENOENT reading the branding
|
|
8
|
+
favicon). The inline email logo is now bundled as a base64 TS module instead of
|
|
9
|
+
read from disk at send time, so verification/invite/reset emails work in
|
|
10
|
+
production where raw assets aren't traced into the deploy bundle.
|
|
11
|
+
|
|
12
|
+
## 0.124.1
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 661ee71: Register the CRM template in the CLI template catalog.
|
|
17
|
+
|
|
18
|
+
`crm` is added to `TEMPLATES` as a **hidden** entry (dev port 8107,
|
|
19
|
+
`defaultMode: "dev"`), so `agent-native new` can scaffold it by name while it
|
|
20
|
+
stays out of the public catalog until it is explicitly unhidden. The mirrored
|
|
21
|
+
list in `@agent-native/shared-app-config` is updated to match.
|
|
22
|
+
|
|
23
|
+
Two cross-template specs are widened to cover it: the UI-primitives sync check
|
|
24
|
+
now includes `crm`, and the page-chat handoff check reads CRM's layout from
|
|
25
|
+
`app/components/layout/CrmLayout.tsx` and expects `requireActiveHandoff: false`,
|
|
26
|
+
since CRM's full-page chat lives on its own `/ask` route.
|
|
27
|
+
|
|
3
28
|
## 0.124.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.124.
|
|
3
|
+
"version": "0.124.2",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @generated by scripts/build-branding-assets.mjs from favicon.png — do not edit by hand.
|
|
2
|
+
// Base64 of the canonical branding PNG, inlined so it survives serverless
|
|
3
|
+
// bundling (no runtime filesystem read).
|
|
4
|
+
export const FAVICON_PNG_BASE64 =
|
|
5
|
+
"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";
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
* so the reset-password flow still works end-to-end for local development.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
14
|
-
|
|
13
|
+
import { FAVICON_PNG_BASE64 } from "../assets/branding/favicon-base64.js";
|
|
15
14
|
import { resolveSecret } from "./credential-provider.js";
|
|
16
15
|
import { AGENT_NATIVE_EMAIL_LOGO_CONTENT_ID } from "./email-template.js";
|
|
17
16
|
|
|
@@ -42,9 +41,7 @@ export interface SendEmailArgs {
|
|
|
42
41
|
let cachedAgentNativeLogo: Buffer | undefined;
|
|
43
42
|
|
|
44
43
|
function getAgentNativeLogoAttachment(): EmailAttachment {
|
|
45
|
-
cachedAgentNativeLogo ??=
|
|
46
|
-
new URL("../../src/assets/branding/favicon.png", import.meta.url),
|
|
47
|
-
);
|
|
44
|
+
cachedAgentNativeLogo ??= Buffer.from(FAVICON_PNG_BASE64, "base64");
|
|
48
45
|
return {
|
|
49
46
|
filename: "agent-native-logo.png",
|
|
50
47
|
content: cachedAgentNativeLogo,
|
|
@@ -931,14 +931,17 @@ async function renderChartBlock(args: {
|
|
|
931
931
|
}
|
|
932
932
|
const subtitle = subtitleParts.join(" · ");
|
|
933
933
|
|
|
934
|
-
|
|
934
|
+
// The card heading directly above already names the panel; repeating it here
|
|
935
|
+
// would read twice in a client that blocks images.
|
|
936
|
+
const alt = `${chartType} chart of ${input.series
|
|
935
937
|
.map((series) => series.label)
|
|
936
938
|
.join(", ")}`;
|
|
937
939
|
|
|
938
940
|
try {
|
|
941
|
+
// Title and description stay in the surrounding HTML card: text there is
|
|
942
|
+
// selectable, wraps instead of truncating, and cannot be duplicated by the
|
|
943
|
+
// image beneath it.
|
|
939
944
|
const svg = renderReportChartSvg({
|
|
940
|
-
title: panel.title,
|
|
941
|
-
...(subtitle ? { subtitle } : {}),
|
|
942
945
|
labels: input.labels,
|
|
943
946
|
series: input.series,
|
|
944
947
|
type: chartType,
|
|
@@ -218,17 +218,26 @@ function renderChartHeader({
|
|
|
218
218
|
? wrapToWidth(subtitle, 13, maxWidth, 2)
|
|
219
219
|
: [subtitle];
|
|
220
220
|
|
|
221
|
+
// Email cards already render the title and description as HTML, so the report
|
|
222
|
+
// path passes neither and the header collapses to nothing. Legacy callers
|
|
223
|
+
// always supply a title, so their output is unchanged.
|
|
224
|
+
const collapsed = fit && !titleText && subtitleLines.length === 0;
|
|
225
|
+
|
|
221
226
|
return {
|
|
222
|
-
titleMarkup:
|
|
227
|
+
titleMarkup: collapsed
|
|
228
|
+
? ""
|
|
229
|
+
: `<text x="${HEADER_INSET}" y="${TITLE_BASELINE}" font-family="${fontFamily}" font-size="22" font-weight="700" fill="${theme.titleColor}">${escapeXml(titleText)}</text>`,
|
|
223
230
|
subtitleMarkup: subtitleLines
|
|
224
231
|
.map(
|
|
225
232
|
(line, index) =>
|
|
226
233
|
`<text x="${HEADER_INSET}" y="${SUBTITLE_BASELINE + index * SUBTITLE_LINE_HEIGHT}" font-family="${fontFamily}" font-size="13" fill="${theme.tickColor}">${escapeXml(line)}</text>`,
|
|
227
234
|
)
|
|
228
235
|
.join(""),
|
|
229
|
-
headerBottom:
|
|
230
|
-
?
|
|
231
|
-
:
|
|
236
|
+
headerBottom: collapsed
|
|
237
|
+
? 0
|
|
238
|
+
: subtitleLines.length
|
|
239
|
+
? SUBTITLE_BASELINE + (subtitleLines.length - 1) * SUBTITLE_LINE_HEIGHT
|
|
240
|
+
: TITLE_BASELINE,
|
|
232
241
|
};
|
|
233
242
|
}
|
|
234
243
|
|
|
@@ -428,7 +437,11 @@ function renderCartesianChartSvg({
|
|
|
428
437
|
fontFamily,
|
|
429
438
|
fit,
|
|
430
439
|
});
|
|
431
|
-
const legendTop =
|
|
440
|
+
const legendTop = !header.headerBottom
|
|
441
|
+
? 18
|
|
442
|
+
: subtitle
|
|
443
|
+
? header.headerBottom + 4
|
|
444
|
+
: 42;
|
|
432
445
|
// A static image has no tooltip to reveal which scale a series belongs to.
|
|
433
446
|
const legendSeries = dualAxis
|
|
434
447
|
? series.map((entry) =>
|
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
ATTRIBUTE_TYPE_SPECS,
|
|
49
49
|
storageColumnFor,
|
|
50
50
|
type CrmAttributeStorageColumn,
|
|
51
|
+
type CrmAttributeType,
|
|
51
52
|
} from "../shared/crm-attributes.js";
|
|
52
53
|
import type {
|
|
53
54
|
CrmActorType,
|
|
@@ -335,6 +336,183 @@ export function indexAttributes(
|
|
|
335
336
|
return new Map(attributes.map((attribute) => [attribute.apiSlug, attribute]));
|
|
336
337
|
}
|
|
337
338
|
|
|
339
|
+
// ---------------------------------------------------------------------------
|
|
340
|
+
// Seeding a list from its parent object, and the one-time copy that gives a
|
|
341
|
+
// new entry its first values.
|
|
342
|
+
//
|
|
343
|
+
// A list attribute is the list's OWN field: it is seeded from a record
|
|
344
|
+
// attribute and each entry's first value is copied from the record once, at
|
|
345
|
+
// insert. Nothing re-reads the record afterwards and nothing writes back — that
|
|
346
|
+
// separation is what lets a pipeline run over a HubSpot or Salesforce mirror
|
|
347
|
+
// without a provider write.
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
|
|
350
|
+
/** A parent-object attribute a list can seed from. Single-valued only: a
|
|
351
|
+
* list's stage, amount, and date are single by construction, and a multi
|
|
352
|
+
* source would not fit the seeded attribute's storage column. */
|
|
353
|
+
export interface CrmObjectAttribute {
|
|
354
|
+
id: string;
|
|
355
|
+
apiSlug: string;
|
|
356
|
+
label: string;
|
|
357
|
+
attributeType: CrmAttributeType;
|
|
358
|
+
/** Raw `config_json`, copied verbatim so a currency keeps its code. */
|
|
359
|
+
configJson: string;
|
|
360
|
+
position: number;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export async function loadCrmObjectAttributes(
|
|
364
|
+
db: CrmDb,
|
|
365
|
+
connectionId: string,
|
|
366
|
+
objectType: string,
|
|
367
|
+
): Promise<CrmObjectAttribute[]> {
|
|
368
|
+
const rows = await db
|
|
369
|
+
.select({
|
|
370
|
+
id: schema.crmFieldPolicies.id,
|
|
371
|
+
apiSlug: schema.crmFieldPolicies.apiSlug,
|
|
372
|
+
fieldName: schema.crmFieldPolicies.fieldName,
|
|
373
|
+
label: schema.crmFieldPolicies.label,
|
|
374
|
+
attributeType: schema.crmFieldPolicies.attributeType,
|
|
375
|
+
configJson: schema.crmFieldPolicies.configJson,
|
|
376
|
+
position: schema.crmFieldPolicies.position,
|
|
377
|
+
})
|
|
378
|
+
.from(schema.crmFieldPolicies)
|
|
379
|
+
.where(
|
|
380
|
+
and(
|
|
381
|
+
eq(schema.crmFieldPolicies.target, "object"),
|
|
382
|
+
eq(schema.crmFieldPolicies.objectType, objectType),
|
|
383
|
+
eq(schema.crmFieldPolicies.connectionId, connectionId),
|
|
384
|
+
eq(schema.crmFieldPolicies.archived, false),
|
|
385
|
+
eq(schema.crmFieldPolicies.multi, false),
|
|
386
|
+
accessFilter(schema.crmFieldPolicies, schema.crmFieldPolicyShares),
|
|
387
|
+
),
|
|
388
|
+
)
|
|
389
|
+
.limit(MAX_LIST_ATTRIBUTES);
|
|
390
|
+
|
|
391
|
+
return rows
|
|
392
|
+
.map((row) => ({
|
|
393
|
+
id: row.id,
|
|
394
|
+
// `api_slug` is null on rows written by the adapters, which predate the
|
|
395
|
+
// typed surface; `field_name` is what their values are keyed by.
|
|
396
|
+
apiSlug: row.apiSlug ?? row.fieldName,
|
|
397
|
+
label: row.label,
|
|
398
|
+
attributeType: row.attributeType,
|
|
399
|
+
configJson: row.configJson,
|
|
400
|
+
position: row.position,
|
|
401
|
+
}))
|
|
402
|
+
.sort(
|
|
403
|
+
(a, b) => a.position - b.position || a.apiSlug.localeCompare(b.apiSlug),
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/** What one attribute's initial value did, per entry. `applied: false` is
|
|
408
|
+
* reported rather than dropped: "the record had no value" and "the record's
|
|
409
|
+
* value does not fit this list" are different facts about an empty card. */
|
|
410
|
+
export interface CrmEntryInitialValue {
|
|
411
|
+
attribute: string;
|
|
412
|
+
/** The record attribute the value was read from. */
|
|
413
|
+
from: string;
|
|
414
|
+
applied: boolean;
|
|
415
|
+
reason?: string;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* The values a BRAND-NEW entry starts with, copied once from the record's own
|
|
420
|
+
* attributes that share the list attribute's slug and type.
|
|
421
|
+
*
|
|
422
|
+
* This is a snapshot at insert, not a binding. Nothing reads the record again,
|
|
423
|
+
* and `update-crm-list-entry` never writes it back, so an entry and its record
|
|
424
|
+
* diverge from here on — deliberately, because the record may be provider-owned
|
|
425
|
+
* and a pipeline must never need a provider write.
|
|
426
|
+
*/
|
|
427
|
+
export async function initialCrmEntryValues(input: {
|
|
428
|
+
db: CrmDb;
|
|
429
|
+
connectionId: string;
|
|
430
|
+
record: { id: string; objectType: string };
|
|
431
|
+
attributes: Map<string, CrmListAttribute>;
|
|
432
|
+
/** Slugs the caller set explicitly. Neither copied nor reported: a value the
|
|
433
|
+
* caller chose was not initialized from anything. */
|
|
434
|
+
supplied?: ReadonlySet<string>;
|
|
435
|
+
}): Promise<{
|
|
436
|
+
values: Record<string, CrmValue>;
|
|
437
|
+
initialValues: CrmEntryInitialValue[];
|
|
438
|
+
}> {
|
|
439
|
+
if (input.attributes.size === 0) return { values: {}, initialValues: [] };
|
|
440
|
+
|
|
441
|
+
const sources = (
|
|
442
|
+
await loadCrmObjectAttributes(
|
|
443
|
+
input.db,
|
|
444
|
+
input.connectionId,
|
|
445
|
+
input.record.objectType,
|
|
446
|
+
)
|
|
447
|
+
).filter((source) => {
|
|
448
|
+
if (input.supplied?.has(source.apiSlug)) return false;
|
|
449
|
+
const attribute = input.attributes.get(source.apiSlug);
|
|
450
|
+
// Same slug is not enough: a text `amount` on the object must not be copied
|
|
451
|
+
// into a currency `amount` on the list.
|
|
452
|
+
return (
|
|
453
|
+
!!attribute &&
|
|
454
|
+
!attribute.multi &&
|
|
455
|
+
attribute.attributeType === source.attributeType
|
|
456
|
+
);
|
|
457
|
+
});
|
|
458
|
+
if (sources.length === 0) return { values: {}, initialValues: [] };
|
|
459
|
+
|
|
460
|
+
const rows = await input.db
|
|
461
|
+
.select({
|
|
462
|
+
fieldName: schema.crmRecordFields.fieldName,
|
|
463
|
+
stringValue: schema.crmRecordFields.stringValue,
|
|
464
|
+
numberValue: schema.crmRecordFields.numberValue,
|
|
465
|
+
booleanValue: schema.crmRecordFields.booleanValue,
|
|
466
|
+
jsonValue: schema.crmRecordFields.jsonValue,
|
|
467
|
+
})
|
|
468
|
+
.from(schema.crmRecordFields)
|
|
469
|
+
.where(
|
|
470
|
+
and(
|
|
471
|
+
eq(schema.crmRecordFields.recordId, input.record.id),
|
|
472
|
+
// `entry_id IS NULL` is the record-vs-entry discriminator: another
|
|
473
|
+
// entry's value must never seed this one.
|
|
474
|
+
isNull(schema.crmRecordFields.entryId),
|
|
475
|
+
isNull(schema.crmRecordFields.activeUntil),
|
|
476
|
+
inArray(
|
|
477
|
+
schema.crmRecordFields.fieldName,
|
|
478
|
+
sources.map((source) => source.apiSlug),
|
|
479
|
+
),
|
|
480
|
+
accessFilter(schema.crmRecordFields, schema.crmRecordFieldShares),
|
|
481
|
+
),
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
const values: Record<string, CrmValue> = {};
|
|
485
|
+
const initialValues: CrmEntryInitialValue[] = [];
|
|
486
|
+
for (const row of rows) {
|
|
487
|
+
const attribute = input.attributes.get(row.fieldName);
|
|
488
|
+
if (!attribute) continue;
|
|
489
|
+
const value = decodeCrmAttributeValue(attribute, row);
|
|
490
|
+
// Nothing to copy is not a failure and is not reported as one.
|
|
491
|
+
if (value === null) continue;
|
|
492
|
+
if (ATTRIBUTE_TYPE_SPECS[attribute.attributeType].usesOptions) {
|
|
493
|
+
const enterable = attribute.options.some(
|
|
494
|
+
(option) => !option.archived && option.value === value,
|
|
495
|
+
);
|
|
496
|
+
if (!enterable) {
|
|
497
|
+
initialValues.push({
|
|
498
|
+
attribute: attribute.apiSlug,
|
|
499
|
+
from: row.fieldName,
|
|
500
|
+
applied: false,
|
|
501
|
+
reason: `The record's "${String(value)}" is not a live option of this list's "${attribute.label}". Add the option, or set the entry's value explicitly.`,
|
|
502
|
+
});
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
values[attribute.apiSlug] = value;
|
|
507
|
+
initialValues.push({
|
|
508
|
+
attribute: attribute.apiSlug,
|
|
509
|
+
from: row.fieldName,
|
|
510
|
+
applied: true,
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
return { values, initialValues };
|
|
514
|
+
}
|
|
515
|
+
|
|
338
516
|
// ---------------------------------------------------------------------------
|
|
339
517
|
// Entry attribute values
|
|
340
518
|
// ---------------------------------------------------------------------------
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
CrmListError,
|
|
14
14
|
crmActorFrom,
|
|
15
15
|
indexAttributes,
|
|
16
|
+
initialCrmEntryValues,
|
|
16
17
|
loadCrmListAttributes,
|
|
17
18
|
requireCrmList,
|
|
18
19
|
writeCrmListEntryValues,
|
|
@@ -31,7 +32,7 @@ export const listEntryValuesSchema = z
|
|
|
31
32
|
|
|
32
33
|
export default defineAction({
|
|
33
34
|
description:
|
|
34
|
-
"Add a record to a CRM list as a new entry, with optional starting values for the list's own entry attributes. A record may hold more than one entry in the same list — two open deals for one company are two entries — so this never de-duplicates; it returns existingEntryIds for the caller to decide. The record's objectType must match the list's parentObjectType. The entry is local-authoritative even when the record mirrors HubSpot or Salesforce.",
|
|
35
|
+
"Add a record to a CRM list as a new entry, with optional starting values for the list's own entry attributes. Any list attribute you do not supply is INITIALIZED from the record's own attribute of the same slug and type — a one-time copy at insert, reported in initialValues, so a new board is populated. It is a copy and not a link: the entry never re-reads the record and editing the entry never writes the record. A record may hold more than one entry in the same list — two open deals for one company are two entries — so this never de-duplicates; it returns existingEntryIds for the caller to decide. The record's objectType must match the list's parentObjectType. The entry is local-authoritative even when the record mirrors HubSpot or Salesforce.",
|
|
35
36
|
schema: z.object({
|
|
36
37
|
listId: z.string().trim().min(1).max(128),
|
|
37
38
|
recordId: z.string().trim().min(1).max(128),
|
|
@@ -68,6 +69,7 @@ export default defineAction({
|
|
|
68
69
|
id: schema.crmRecords.id,
|
|
69
70
|
objectType: schema.crmRecords.objectType,
|
|
70
71
|
displayName: schema.crmRecords.displayName,
|
|
72
|
+
connectionId: schema.crmRecords.connectionId,
|
|
71
73
|
})
|
|
72
74
|
.from(schema.crmRecords)
|
|
73
75
|
.where(
|
|
@@ -118,6 +120,18 @@ export default defineAction({
|
|
|
118
120
|
.orderBy(desc(schema.crmListEntries.position))
|
|
119
121
|
.limit(1);
|
|
120
122
|
|
|
123
|
+
// The entry's first values, copied once from the record. A value the caller
|
|
124
|
+
// supplied is left alone — including an explicit null, which is the caller
|
|
125
|
+
// saying "start this one empty".
|
|
126
|
+
const initial = await initialCrmEntryValues({
|
|
127
|
+
db,
|
|
128
|
+
connectionId: record.connectionId,
|
|
129
|
+
record,
|
|
130
|
+
attributes,
|
|
131
|
+
supplied: new Set(Object.keys(args.values ?? {})),
|
|
132
|
+
});
|
|
133
|
+
const values = { ...initial.values, ...(args.values ?? {}) };
|
|
134
|
+
|
|
121
135
|
const entryId = crypto.randomUUID();
|
|
122
136
|
const actor = crmActorFrom(ctx);
|
|
123
137
|
const now = new Date().toISOString();
|
|
@@ -141,7 +155,7 @@ export default defineAction({
|
|
|
141
155
|
recordId: record.id,
|
|
142
156
|
entryId,
|
|
143
157
|
attributes,
|
|
144
|
-
values
|
|
158
|
+
values,
|
|
145
159
|
actor,
|
|
146
160
|
ownership,
|
|
147
161
|
now,
|
|
@@ -152,6 +166,13 @@ export default defineAction({
|
|
|
152
166
|
entryId,
|
|
153
167
|
listId: list.id,
|
|
154
168
|
recordId: record.id,
|
|
169
|
+
/**
|
|
170
|
+
* What the entry's values were initialized from. An `applied: false` row
|
|
171
|
+
* is a value the record held that this list cannot represent — reported,
|
|
172
|
+
* never dropped silently, because an unexplained empty card is exactly
|
|
173
|
+
* how a board looks broken.
|
|
174
|
+
*/
|
|
175
|
+
initialValues: initial.initialValues,
|
|
155
176
|
/**
|
|
156
177
|
* Entries this record already had in this list. Non-empty is normal, not
|
|
157
178
|
* an error — the caller decides whether a second entry was intended.
|