@tellescope/schema 1.253.0 → 1.254.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/lib/cjs/schema.d.ts +1 -0
- package/lib/cjs/schema.d.ts.map +1 -1
- package/lib/cjs/schema.js +85 -30
- package/lib/cjs/schema.js.map +1 -1
- package/lib/esm/schema.d.ts +1 -0
- package/lib/esm/schema.d.ts.map +1 -1
- package/lib/esm/schema.js +86 -31
- package/lib/esm/schema.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/schema.ts +123 -55
package/src/schema.ts
CHANGED
|
@@ -90,6 +90,7 @@ import {
|
|
|
90
90
|
AIDecisionAutomationAction,
|
|
91
91
|
AutomationAction,
|
|
92
92
|
TimeTrackTimestamp,
|
|
93
|
+
TimeTrackReviewHistoryItem,
|
|
93
94
|
BelugaPharmacyMapping,
|
|
94
95
|
BelugaAutomationMappingEntry,
|
|
95
96
|
BelugaUpdateVisitPatientPreferenceItem,
|
|
@@ -172,6 +173,7 @@ import {
|
|
|
172
173
|
fileSizeValidator,
|
|
173
174
|
meetingStatusValidator,
|
|
174
175
|
listOfAttendeesValidator,
|
|
176
|
+
listOfVideoCallParticipantEventsValidator,
|
|
175
177
|
meetingInfoValidator,
|
|
176
178
|
listOfUserIndentitiesValidator,
|
|
177
179
|
meetingsListValidator,
|
|
@@ -287,6 +289,7 @@ import {
|
|
|
287
289
|
userCallRoutingBehaviorValidator,
|
|
288
290
|
userUIRestrictionsValidator,
|
|
289
291
|
userFieldRedactionsValidator,
|
|
292
|
+
portalSchemaRestrictionsValidator,
|
|
290
293
|
externalChatGPTMessagesValidator,
|
|
291
294
|
enduserProfileViewBlocksValidator,
|
|
292
295
|
customDashboardBlocksValidator,
|
|
@@ -460,6 +463,7 @@ export type ModelFieldInfo <T, R> = {
|
|
|
460
463
|
readonly?: boolean,
|
|
461
464
|
required?: boolean,
|
|
462
465
|
updatesDisabled?: boolean,
|
|
466
|
+
enduserUpdatesDisabled?: boolean, // enduser sessions cannot update this field; user sessions still can
|
|
463
467
|
examples?: JSONType[],
|
|
464
468
|
initializer?: Initializer<Partial<T>, R>, // should include the required fields of T, not just partial
|
|
465
469
|
dependencies?: Dependency<Partial<T>>[],
|
|
@@ -1506,13 +1510,15 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1506
1510
|
unsubscribe: {},
|
|
1507
1511
|
},
|
|
1508
1512
|
fields: {
|
|
1509
|
-
...BuiltInFields,
|
|
1513
|
+
...BuiltInFields,
|
|
1514
|
+
sharedWithOrganizations: { ...BuiltInFields.sharedWithOrganizations, enduserUpdatesDisabled: true },
|
|
1510
1515
|
recentViewers: { validator: recentViewersValidator },
|
|
1511
|
-
healthie_dietitian_id: { validator: stringValidator100 },
|
|
1516
|
+
healthie_dietitian_id: { validator: stringValidator100, enduserUpdatesDisabled: true },
|
|
1512
1517
|
mergedIds: { validator: listOfMongoIdStringValidatorOptionalOrEmptyOk, readonly: true, redactions: ['enduser'] },
|
|
1513
1518
|
externalId: {
|
|
1514
1519
|
validator: stringValidator250,
|
|
1515
1520
|
examples: ['addfed3e-ddea-415b-b52b-df820c944dbb'],
|
|
1521
|
+
enduserUpdatesDisabled: true,
|
|
1516
1522
|
},
|
|
1517
1523
|
email: {
|
|
1518
1524
|
validator: emailValidatorEmptyOkay,
|
|
@@ -1566,9 +1572,10 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1566
1572
|
validator: stringValidator250,
|
|
1567
1573
|
redactions: ['enduser'],
|
|
1568
1574
|
},
|
|
1569
|
-
journeys: {
|
|
1575
|
+
journeys: {
|
|
1570
1576
|
validator: journeysValidator,
|
|
1571
1577
|
redactions: ['enduser'],
|
|
1578
|
+
enduserUpdatesDisabled: true, // endusers may still use the add_to_journey / remove_from_journey custom actions
|
|
1572
1579
|
dependencies: [
|
|
1573
1580
|
{
|
|
1574
1581
|
dependsOn: ['journeys'],
|
|
@@ -1584,13 +1591,15 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1584
1591
|
]
|
|
1585
1592
|
},
|
|
1586
1593
|
scheduledJourneys: { validator: scheduledJourneysValidator },
|
|
1587
|
-
tags: {
|
|
1594
|
+
tags: {
|
|
1588
1595
|
redactions: ['enduser'],
|
|
1589
1596
|
validator: listOfStringsValidatorUniqueOptionalOrEmptyOkay,
|
|
1597
|
+
enduserUpdatesDisabled: true,
|
|
1590
1598
|
},
|
|
1591
|
-
accessTags: {
|
|
1599
|
+
accessTags: {
|
|
1592
1600
|
redactions: ['enduser'],
|
|
1593
1601
|
validator: listOfStringsValidatorEmptyOk,
|
|
1602
|
+
enduserUpdatesDisabled: true,
|
|
1594
1603
|
},
|
|
1595
1604
|
unredactedTags: {
|
|
1596
1605
|
validator: listOfStringsValidatorEmptyOk,
|
|
@@ -1598,6 +1607,7 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1598
1607
|
fields: {
|
|
1599
1608
|
redactions: ['enduser'],
|
|
1600
1609
|
validator: fieldsValidator,
|
|
1610
|
+
enduserUpdatesDisabled: true, // intake forms write fields server-side; direct enduser PATCH is not a supported path
|
|
1601
1611
|
},
|
|
1602
1612
|
unredactedFields: {
|
|
1603
1613
|
validator: fieldsValidator,
|
|
@@ -1606,17 +1616,20 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1606
1616
|
redactions: ['enduser'],
|
|
1607
1617
|
validator: preferenceValidator,
|
|
1608
1618
|
},
|
|
1609
|
-
assignedTo: {
|
|
1619
|
+
assignedTo: {
|
|
1610
1620
|
redactions: ['enduser'],
|
|
1611
1621
|
validator: listOfUniqueStringsValidatorEmptyOk,
|
|
1622
|
+
enduserUpdatesDisabled: true,
|
|
1612
1623
|
},
|
|
1613
|
-
primaryAssignee: {
|
|
1624
|
+
primaryAssignee: {
|
|
1614
1625
|
validator: mongoIdStringValidator,
|
|
1615
1626
|
redactions: ['enduser'],
|
|
1627
|
+
enduserUpdatesDisabled: true,
|
|
1616
1628
|
},
|
|
1617
|
-
unread: {
|
|
1629
|
+
unread: {
|
|
1618
1630
|
redactions: ['enduser'],
|
|
1619
1631
|
validator: booleanValidator,
|
|
1632
|
+
enduserUpdatesDisabled: true,
|
|
1620
1633
|
},
|
|
1621
1634
|
lastActive: {
|
|
1622
1635
|
validator: dateValidator,
|
|
@@ -1651,7 +1664,7 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1651
1664
|
pronouns: { validator: stringValidator100, redactions: ['enduser'] },
|
|
1652
1665
|
height: { validator: genericUnitWithQuantityValidator, redactions: ['enduser'] },
|
|
1653
1666
|
weight: { validator: genericUnitWithQuantityValidator, redactions: ['enduser'] },
|
|
1654
|
-
source: { validator: stringValidator1000Optional },
|
|
1667
|
+
source: { validator: stringValidator1000Optional, enduserUpdatesDisabled: true },
|
|
1655
1668
|
addressLineOne: { validator: stringValidator5000EmptyOkay, redactions: ['enduser'] },
|
|
1656
1669
|
addressLineTwo: { validator: stringValidator5000EmptyOkay, redactions: ['enduser'] },
|
|
1657
1670
|
city: { validator: stringValidator5000EmptyOkay, redactions: ['enduser'] },
|
|
@@ -1663,7 +1676,7 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1663
1676
|
displayName: { validator: stringValidator250 }, // intentionally not redacted for other endusers
|
|
1664
1677
|
unsubscribedFromPortalChatNotifications: { validator: booleanValidator },
|
|
1665
1678
|
triggeredEvents: { validator: objectAnyFieldsValidator(numberValidator) },
|
|
1666
|
-
customTypeId: { validator: mongoIdStringValidator },
|
|
1679
|
+
customTypeId: { validator: mongoIdStringValidator, enduserUpdatesDisabled: true },
|
|
1667
1680
|
language: { validator: languageValidator },
|
|
1668
1681
|
relationships: {
|
|
1669
1682
|
validator: listValidatorOptionalOrEmptyOk(objectValidator<EnduserRelationship>({
|
|
@@ -1673,10 +1686,10 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1673
1686
|
},
|
|
1674
1687
|
markedReadAt: { validator: dateOptionalOrEmptyStringValidator },
|
|
1675
1688
|
markedUnreadAt: { validator: dateOptionalOrEmptyStringValidator },
|
|
1676
|
-
note: { validator: stringValidator25000EmptyOkay, redactions: ['enduser'] },
|
|
1689
|
+
note: { validator: stringValidator25000EmptyOkay, redactions: ['enduser'], enduserUpdatesDisabled: true },
|
|
1677
1690
|
noteIsFlagged: { validator: booleanValidator },
|
|
1678
|
-
insurance: { validator: insuranceOptionalValidator, redactions: ['enduser'] },
|
|
1679
|
-
insuranceSecondary: { validator: insuranceOptionalValidator, redactions: ['enduser'] },
|
|
1691
|
+
insurance: { validator: insuranceOptionalValidator, redactions: ['enduser'], enduserUpdatesDisabled: true }, // patient insurance entry is supported via intake forms (server-side write)
|
|
1692
|
+
insuranceSecondary: { validator: insuranceOptionalValidator, redactions: ['enduser'], enduserUpdatesDisabled: true },
|
|
1680
1693
|
bookingNotes: {
|
|
1681
1694
|
validator: listValidatorOptionalOrEmptyOk(objectValidator<{ bookingPageId: string, note: string }>({
|
|
1682
1695
|
bookingPageId: mongoIdStringRequired,
|
|
@@ -1694,24 +1707,25 @@ export const schema: SchemaV1 = build_schema({
|
|
|
1694
1707
|
})),
|
|
1695
1708
|
redactions: ['enduser'],
|
|
1696
1709
|
},
|
|
1697
|
-
references: { validator: listOfRelatedRecordsValidator, redactions: ['enduser'] },
|
|
1698
|
-
athenaDepartmentId: { validator: stringValidator100, redactions: ['enduser'] },
|
|
1699
|
-
athenaPracticeId: { validator: stringValidator100, redactions: ['enduser'] },
|
|
1700
|
-
salesforceId: { validator: stringValidator100, redactions: ['enduser'] },
|
|
1710
|
+
references: { validator: listOfRelatedRecordsValidator, redactions: ['enduser'], enduserUpdatesDisabled: true },
|
|
1711
|
+
athenaDepartmentId: { validator: stringValidator100, redactions: ['enduser'], enduserUpdatesDisabled: true },
|
|
1712
|
+
athenaPracticeId: { validator: stringValidator100, redactions: ['enduser'], enduserUpdatesDisabled: true },
|
|
1713
|
+
salesforceId: { validator: stringValidator100, redactions: ['enduser'], enduserUpdatesDisabled: true },
|
|
1701
1714
|
vitalTriggersDisabled: { validator: booleanValidator },
|
|
1702
1715
|
defaultFromPhone: { validator: phoneValidator, redactions: ['enduser'] },
|
|
1703
1716
|
defaultFromEmail: { validator: emailValidator, redactions: ['enduser'] },
|
|
1704
1717
|
useDefaultFromEmailInAutomations: { validator: booleanValidator },
|
|
1705
1718
|
useDefaultFromPhoneInAutomations: { validator: booleanValidator },
|
|
1706
|
-
stripeCustomerId: { validator: stringValidator100, redactions: ['enduser'] },
|
|
1707
|
-
stripeKey: { validator: stringValidator250, redactions: ['enduser'] },
|
|
1719
|
+
stripeCustomerId: { validator: stringValidator100, redactions: ['enduser'], enduserUpdatesDisabled: true },
|
|
1720
|
+
stripeKey: { validator: stringValidator250, redactions: ['enduser'], enduserUpdatesDisabled: true },
|
|
1708
1721
|
diagnoses: {
|
|
1709
1722
|
validator: listValidatorOptionalOrEmptyOk(enduserDiagnosisValidator),
|
|
1710
|
-
redactions: ['enduser']
|
|
1723
|
+
redactions: ['enduser'],
|
|
1724
|
+
enduserUpdatesDisabled: true,
|
|
1711
1725
|
},
|
|
1712
1726
|
unsubscribedFromPhones: { validator: listOfStringsValidatorUniqueOptionalOrEmptyOkay, redactions: ['enduser'] },
|
|
1713
|
-
lockedFromPortal: { validator: booleanValidator },
|
|
1714
|
-
eligibleForAutoMerge: { validator: booleanValidator },
|
|
1727
|
+
lockedFromPortal: { validator: booleanValidator, enduserUpdatesDisabled: true },
|
|
1728
|
+
eligibleForAutoMerge: { validator: booleanValidator, enduserUpdatesDisabled: true },
|
|
1715
1729
|
preferredPharmacy: { validator: pharmacyValidator, redactions: ['enduser'] },
|
|
1716
1730
|
// recentMessagePreview: {
|
|
1717
1731
|
// validator: stringValidator,
|
|
@@ -2633,6 +2647,7 @@ export const schema: SchemaV1 = build_schema({
|
|
|
2633
2647
|
info: {},
|
|
2634
2648
|
fields: {
|
|
2635
2649
|
...BuiltInFields,
|
|
2650
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
2636
2651
|
archivedAt: { validator: dateOptionalOrEmptyStringValidator },
|
|
2637
2652
|
title: {
|
|
2638
2653
|
validator: stringValidator100,
|
|
@@ -3475,7 +3490,9 @@ export const schema: SchemaV1 = build_schema({
|
|
|
3475
3490
|
{
|
|
3476
3491
|
explanation: "Only admin users can update tags when accessTags is enabled",
|
|
3477
3492
|
evaluate: ({ _id }, _, session, method, { updates } ) => {
|
|
3478
|
-
|
|
3493
|
+
// editing a user's tags is a privilege-escalation vector whenever tags gate visibility:
|
|
3494
|
+
// enduser access tags (eat) OR resource access tags (erat). Skip only when neither is enabled.
|
|
3495
|
+
if (session.type === 'user' && !session.eat && !(session as UserSession)?.erat) return // neither access-tags feature enabled
|
|
3479
3496
|
if ((session as UserSession)?.roles?.includes('Admin')) return
|
|
3480
3497
|
if (method === 'create') return
|
|
3481
3498
|
if (!updates?.tags) return
|
|
@@ -4171,7 +4188,8 @@ export const schema: SchemaV1 = build_schema({
|
|
|
4171
4188
|
},
|
|
4172
4189
|
},
|
|
4173
4190
|
fields: {
|
|
4174
|
-
...BuiltInFields,
|
|
4191
|
+
...BuiltInFields,
|
|
4192
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
4175
4193
|
archivedAt: { validator: dateOptionalOrEmptyStringValidator },
|
|
4176
4194
|
mmsAttachmentURLs: { validator: listOfUniqueStringsValidatorEmptyOk },
|
|
4177
4195
|
title: {
|
|
@@ -4219,7 +4237,8 @@ export const schema: SchemaV1 = build_schema({
|
|
|
4219
4237
|
defaultActions: { read: {}, readMany: {}, update: {}, delete: {} },
|
|
4220
4238
|
enduserActions: { prepare_file_upload: {}, confirm_file_upload: {}, file_download_URL: {}, read: {}, readMany: {}, delete: {}, update: { } /* allow to hide from client side */ },
|
|
4221
4239
|
fields: {
|
|
4222
|
-
...BuiltInFields,
|
|
4240
|
+
...BuiltInFields,
|
|
4241
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
4223
4242
|
source: { validator: stringValidator100 },
|
|
4224
4243
|
tags: { validator: listOfStringsValidatorUniqueOptionalOrEmptyOkay },
|
|
4225
4244
|
name: {
|
|
@@ -4237,6 +4256,9 @@ export const schema: SchemaV1 = build_schema({
|
|
|
4237
4256
|
enduserId: { // deleted as side effect of enduser delete
|
|
4238
4257
|
validator: mongoIdStringValidator,
|
|
4239
4258
|
},
|
|
4259
|
+
formResponseId: { // link to the form response a file was uploaded for (used for Beluga sync)
|
|
4260
|
+
validator: mongoIdStringValidator,
|
|
4261
|
+
},
|
|
4240
4262
|
secureName: {
|
|
4241
4263
|
validator: stringValidator250,
|
|
4242
4264
|
readonly: true,
|
|
@@ -4485,7 +4507,7 @@ export const schema: SchemaV1 = build_schema({
|
|
|
4485
4507
|
},
|
|
4486
4508
|
enduserActions: { create: {}, read: {}, readMany: {} },
|
|
4487
4509
|
fields: {
|
|
4488
|
-
...BuiltInFields,
|
|
4510
|
+
...BuiltInFields,
|
|
4489
4511
|
title: {
|
|
4490
4512
|
validator: stringValidator1000,
|
|
4491
4513
|
required: true,
|
|
@@ -4810,6 +4832,7 @@ export const schema: SchemaV1 = build_schema({
|
|
|
4810
4832
|
},
|
|
4811
4833
|
fields: {
|
|
4812
4834
|
...BuiltInFields,
|
|
4835
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
4813
4836
|
showByUserTags: { validator: listOfStringsValidatorOptionalOrEmptyOk },
|
|
4814
4837
|
belugaVisitType: { validator: stringValidator },
|
|
4815
4838
|
belugaVerificationId: { validator: stringValidator },
|
|
@@ -5025,8 +5048,8 @@ export const schema: SchemaV1 = build_schema({
|
|
|
5025
5048
|
fields: {
|
|
5026
5049
|
...BuiltInFields,
|
|
5027
5050
|
discussionRoomId: { validator: mongoIdStringValidator },
|
|
5028
|
-
hiddenFromTimeline: { validator: booleanValidator },
|
|
5029
|
-
lockedAt: { validator: dateValidator },
|
|
5051
|
+
hiddenFromTimeline: { validator: booleanValidator, enduserUpdatesDisabled: true },
|
|
5052
|
+
lockedAt: { validator: dateValidator, enduserUpdatesDisabled: true },
|
|
5030
5053
|
formId: {
|
|
5031
5054
|
validator: stringValidator100, // allow other external id types here too, not just mongoid
|
|
5032
5055
|
required: true,
|
|
@@ -5059,42 +5082,43 @@ export const schema: SchemaV1 = build_schema({
|
|
|
5059
5082
|
copiedFrom: { validator: mongoIdStringOptional },
|
|
5060
5083
|
copiedFromEnduserId: { validator: mongoIdStringOptional },
|
|
5061
5084
|
publicSubmit: { validator: booleanValidator },
|
|
5062
|
-
submittedBy: { validator: stringValidator250 },
|
|
5063
|
-
submittedByIsPlaceholder: { validator: booleanValidator },
|
|
5064
|
-
markedAsSubmitted: { validator: booleanValidator },
|
|
5085
|
+
submittedBy: { validator: stringValidator250, enduserUpdatesDisabled: true },
|
|
5086
|
+
submittedByIsPlaceholder: { validator: booleanValidator, enduserUpdatesDisabled: true },
|
|
5087
|
+
markedAsSubmitted: { validator: booleanValidator, enduserUpdatesDisabled: true }, // endusers submit via the submit_form_response custom action
|
|
5065
5088
|
accessCode: { validator: stringValidator250 },
|
|
5066
|
-
userEmail: { validator: emailValidator },
|
|
5067
|
-
submittedAt: { validator: dateValidator },
|
|
5068
|
-
formTitle: { validator: stringValidator250 },
|
|
5089
|
+
userEmail: { validator: emailValidator, enduserUpdatesDisabled: true },
|
|
5090
|
+
submittedAt: { validator: dateValidator, enduserUpdatesDisabled: true },
|
|
5091
|
+
formTitle: { validator: stringValidator250, enduserUpdatesDisabled: true },
|
|
5069
5092
|
responses: { validator: formResponsesValidator },
|
|
5070
5093
|
draftSavedAt: { validator: dateValidator },
|
|
5071
5094
|
draftSavedBy: { validator: mongoIdStringValidator },
|
|
5072
5095
|
hideFromEnduserPortal: { validator: booleanValidator },
|
|
5073
5096
|
sharedVia: { validator: communicationsChannelValidator },
|
|
5074
|
-
isInternalNote: { validator: booleanValidator },
|
|
5075
|
-
pinnedAt: { validator: dateOptionalOrEmptyStringValidator },
|
|
5097
|
+
isInternalNote: { validator: booleanValidator, enduserUpdatesDisabled: true },
|
|
5098
|
+
pinnedAt: { validator: dateOptionalOrEmptyStringValidator, enduserUpdatesDisabled: true },
|
|
5076
5099
|
publicIdentifier: { validator: stringValidator250 },
|
|
5077
5100
|
source: { validator: stringValidator250 },
|
|
5078
5101
|
externalId: { validator: stringValidator250 },
|
|
5079
5102
|
rootResponseId: { validator: mongoIdStringValidator },
|
|
5080
5103
|
parentResponseId: { validator: mongoIdStringValidator },
|
|
5081
|
-
tags: { validator: listOfStringsValidatorOptionalOrEmptyOk },
|
|
5104
|
+
tags: { validator: listOfStringsValidatorOptionalOrEmptyOk, enduserUpdatesDisabled: true },
|
|
5082
5105
|
carePlanId: { validator: mongoIdStringValidator },
|
|
5083
5106
|
context: { validator: stringValidator1000 },
|
|
5084
|
-
logoURL: { validator: stringValidator5000 },
|
|
5085
|
-
logoHeight: { validator: numberValidator },
|
|
5107
|
+
logoURL: { validator: stringValidator5000, enduserUpdatesDisabled: true },
|
|
5108
|
+
logoHeight: { validator: numberValidator, enduserUpdatesDisabled: true },
|
|
5086
5109
|
calendarEventId: { validator: mongoIdStringValidator },
|
|
5087
5110
|
references: { validator: listOfRelatedRecordsValidator, readonly: true },
|
|
5088
5111
|
groupId: { validator: mongoIdStringValidator },
|
|
5089
5112
|
groupInstance: { validator: stringValidator100 },
|
|
5090
5113
|
groupPosition: { validator: nonNegNumberValidator },
|
|
5091
5114
|
hideAfterUnsubmittedInMS: { validator: numberValidator },
|
|
5092
|
-
addenda: {
|
|
5093
|
-
validator: listValidatorOptionalOrEmptyOk(objectValidator<Addendum>({
|
|
5115
|
+
addenda: {
|
|
5116
|
+
validator: listValidatorOptionalOrEmptyOk(objectValidator<Addendum>({
|
|
5094
5117
|
text: stringValidator25000EmptyOkay,
|
|
5095
5118
|
timestamp: dateValidator,
|
|
5096
5119
|
userId: mongoIdStringRequired,
|
|
5097
|
-
}))
|
|
5120
|
+
})),
|
|
5121
|
+
enduserUpdatesDisabled: true,
|
|
5098
5122
|
},
|
|
5099
5123
|
followups: {
|
|
5100
5124
|
validator: listValidatorOptionalOrEmptyOk(objectValidator<FormResponseFollowup>({
|
|
@@ -5115,9 +5139,9 @@ export const schema: SchemaV1 = build_schema({
|
|
|
5115
5139
|
}))
|
|
5116
5140
|
},
|
|
5117
5141
|
startedViaPinnedForm: { validator: booleanValidator },
|
|
5118
|
-
enduserAISummary: { validator: stringValidator25000 },
|
|
5119
|
-
procedureCodes: { validator: procedureCodesValidator },
|
|
5120
|
-
diagnosisCodes: { validator: diagnosisCodesValidator },
|
|
5142
|
+
enduserAISummary: { validator: stringValidator25000, enduserUpdatesDisabled: true },
|
|
5143
|
+
procedureCodes: { validator: procedureCodesValidator, enduserUpdatesDisabled: true },
|
|
5144
|
+
diagnosisCodes: { validator: diagnosisCodesValidator, enduserUpdatesDisabled: true },
|
|
5121
5145
|
},
|
|
5122
5146
|
defaultActions: DEFAULT_OPERATIONS,
|
|
5123
5147
|
enduserActions: {
|
|
@@ -5930,6 +5954,7 @@ export const schema: SchemaV1 = build_schema({
|
|
|
5930
5954
|
meetingId: { validator: mongoIdStringValidator, readonly: true },
|
|
5931
5955
|
bookingPageId: { validator: mongoIdStringValidator }, // allows rescheduling via booking page
|
|
5932
5956
|
meetingStatus: { validator: meetingStatusValidator },
|
|
5957
|
+
videoCallAttendance: { validator: listOfVideoCallParticipantEventsValidator, readonly: true },
|
|
5933
5958
|
attachments: { validator: listOfGenericAttachmentsValidator },
|
|
5934
5959
|
cancelledAt: { validator: dateOptionalOrEmptyStringValidator },
|
|
5935
5960
|
rescheduledAt: { validator: dateOptionalOrEmptyStringValidator },
|
|
@@ -6064,7 +6089,8 @@ export const schema: SchemaV1 = build_schema({
|
|
|
6064
6089
|
customActions: {},
|
|
6065
6090
|
enduserActions: { read: {}, readMany: {} },
|
|
6066
6091
|
fields: {
|
|
6067
|
-
...BuiltInFields,
|
|
6092
|
+
...BuiltInFields,
|
|
6093
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
6068
6094
|
dontSyncToElation: { validator: booleanValidator },
|
|
6069
6095
|
sendIcsEmail: { validator: booleanValidator },
|
|
6070
6096
|
createAndBookAthenaSlot: { validator: booleanValidator },
|
|
@@ -6592,7 +6618,8 @@ export const schema: SchemaV1 = build_schema({
|
|
|
6592
6618
|
search: {},
|
|
6593
6619
|
},
|
|
6594
6620
|
fields: {
|
|
6595
|
-
...BuiltInFields,
|
|
6621
|
+
...BuiltInFields,
|
|
6622
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
6596
6623
|
slug: { validator: stringValidator250 },
|
|
6597
6624
|
title: {
|
|
6598
6625
|
validator: stringValidator1000,
|
|
@@ -7199,7 +7226,7 @@ export const schema: SchemaV1 = build_schema({
|
|
|
7199
7226
|
type: stringValidatorOptional,
|
|
7200
7227
|
}),
|
|
7201
7228
|
},
|
|
7202
|
-
onboardingStatus: { validator:
|
|
7229
|
+
onboardingStatus: { validator: userPortalSettingsValidator }, // key-value store, same shape as User.portalSettings; read/write for org admins (not super-admin restricted)
|
|
7203
7230
|
creditCount: { validator: numberValidator, readonly: true },
|
|
7204
7231
|
stripeKeyDetails: {
|
|
7205
7232
|
validator: listValidatorOptionalOrEmptyOk(objectValidator<StripeKeyDetail>({
|
|
@@ -7608,6 +7635,12 @@ export const schema: SchemaV1 = build_schema({
|
|
|
7608
7635
|
},
|
|
7609
7636
|
uiRestrictions: { validator: userUIRestrictionsValidator },
|
|
7610
7637
|
fieldRedactions: { validator: userFieldRedactionsValidator },
|
|
7638
|
+
portalSchemaRestrictions: {
|
|
7639
|
+
validator: portalSchemaRestrictionsValidator,
|
|
7640
|
+
initializer: () => ({ disableEditContent: true, disableEditTheming: true, disableEditSnippets: true }),
|
|
7641
|
+
},
|
|
7642
|
+
color: { validator: stringValidator1000 },
|
|
7643
|
+
description: { validator: stringValidator1000Optional },
|
|
7611
7644
|
}
|
|
7612
7645
|
},
|
|
7613
7646
|
appointment_booking_pages: {
|
|
@@ -7651,7 +7684,8 @@ export const schema: SchemaV1 = build_schema({
|
|
|
7651
7684
|
read: {}, readMany: {}, validate_access_token: {},
|
|
7652
7685
|
},
|
|
7653
7686
|
fields: {
|
|
7654
|
-
...BuiltInFields,
|
|
7687
|
+
...BuiltInFields,
|
|
7688
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
7655
7689
|
dontRestrictRescheduleToOriginalHost: { validator: booleanValidator },
|
|
7656
7690
|
gtmTag: { validator: stringValidator100EscapeHTML },
|
|
7657
7691
|
archivedAt: { validator: dateOptionalOrEmptyStringValidator },
|
|
@@ -8488,7 +8522,8 @@ If a voicemail is left, it is indicated by recordingURI, transcription, or recor
|
|
|
8488
8522
|
},
|
|
8489
8523
|
enduserActions: {},
|
|
8490
8524
|
fields: {
|
|
8491
|
-
...BuiltInFields,
|
|
8525
|
+
...BuiltInFields,
|
|
8526
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
8492
8527
|
title: {
|
|
8493
8528
|
validator: stringValidator100,
|
|
8494
8529
|
required: true,
|
|
@@ -8843,7 +8878,8 @@ If a voicemail is left, it is indicated by recordingURI, transcription, or recor
|
|
|
8843
8878
|
customActions: {},
|
|
8844
8879
|
enduserActions: {},
|
|
8845
8880
|
fields: {
|
|
8846
|
-
...BuiltInFields,
|
|
8881
|
+
...BuiltInFields,
|
|
8882
|
+
accessTags: { redactions: ['enduser'], validator: listOfStringsValidatorEmptyOk },
|
|
8847
8883
|
title: {
|
|
8848
8884
|
validator: stringValidator,
|
|
8849
8885
|
required: true,
|
|
@@ -9025,14 +9061,33 @@ If a voicemail is left, it is indicated by recordingURI, transcription, or recor
|
|
|
9025
9061
|
}
|
|
9026
9062
|
},
|
|
9027
9063
|
{
|
|
9028
|
-
explanation: "Locked time tracks only allow review field updates",
|
|
9029
|
-
evaluate: (_v, _deps,
|
|
9064
|
+
explanation: "Locked time tracks only allow review field updates, or owner resubmission of rejected entries",
|
|
9065
|
+
evaluate: (_v, _deps, session, method, { original, updates }) => {
|
|
9030
9066
|
if (method !== 'update') return
|
|
9031
9067
|
const orig = original as any as TimeTrack | undefined
|
|
9032
9068
|
if (!orig?.lockedAt) return
|
|
9069
|
+
|
|
9070
|
+
const u = updates as any as Partial<TimeTrack> | undefined
|
|
9033
9071
|
const reviewFields = ['reviewedAt', 'reviewedByUserId', 'reviewApproved', 'reviewNote']
|
|
9034
9072
|
const nonReviewFields = Object.keys(updates || {}).filter(k => !reviewFields.includes(k))
|
|
9035
|
-
if (nonReviewFields.length
|
|
9073
|
+
if (nonReviewFields.length === 0) return // pure review update — unchanged behavior
|
|
9074
|
+
|
|
9075
|
+
const isRejected = !!orig.reviewedAt && orig.reviewApproved === false
|
|
9076
|
+
const resubmitFields = [
|
|
9077
|
+
...reviewFields,
|
|
9078
|
+
'correctedAt', 'correctedByUserId', 'correctionNote',
|
|
9079
|
+
'originalTotalDurationInMS', 'totalDurationInMS',
|
|
9080
|
+
'lockedAt', 'lockedByUserId',
|
|
9081
|
+
]
|
|
9082
|
+
const disallowed = Object.keys(updates || {}).filter(k => !resubmitFields.includes(k))
|
|
9083
|
+
|
|
9084
|
+
if (isRejected && session.id === orig.userId && disallowed.length === 0) {
|
|
9085
|
+
if (u?.reviewedAt !== '') return "Resubmitting a rejected time track requires clearing reviewedAt (set to '')"
|
|
9086
|
+
if (u?.reviewApproved === true) return "Cannot approve your own time track during resubmission"
|
|
9087
|
+
return // valid resubmit — entry returns to Pending
|
|
9088
|
+
}
|
|
9089
|
+
|
|
9090
|
+
return `Time track is locked. Only review fields (${reviewFields.join(', ')}) can be updated.`
|
|
9036
9091
|
}
|
|
9037
9092
|
},
|
|
9038
9093
|
{
|
|
@@ -9117,6 +9172,19 @@ If a voicemail is left, it is indicated by recordingURI, transcription, or recor
|
|
|
9117
9172
|
reviewNote: { validator: stringValidator1000Optional },
|
|
9118
9173
|
lockedAt: { validator: dateValidatorOptional },
|
|
9119
9174
|
lockedByUserId: { validator: mongoIdStringOptional },
|
|
9175
|
+
// server-appended on resubmission of a rejected entry (see routing.ts update handler)
|
|
9176
|
+
// note: reviewApproved remains false after resubmit (booleans can't be cleared to '') — status logic must key off reviewedAt
|
|
9177
|
+
reviewHistory: {
|
|
9178
|
+
validator: listValidatorOptionalOrEmptyOk(objectValidator<TimeTrackReviewHistoryItem>({
|
|
9179
|
+
reviewedAt: dateValidator,
|
|
9180
|
+
reviewedByUserId: mongoIdStringOptional,
|
|
9181
|
+
reviewApproved: booleanValidatorOptional,
|
|
9182
|
+
reviewNote: stringValidator1000Optional,
|
|
9183
|
+
resubmittedAt: dateValidatorOptional,
|
|
9184
|
+
resubmittedByUserId: mongoIdStringOptional,
|
|
9185
|
+
})),
|
|
9186
|
+
readonly: true, // server-appended only — clients can read, never write
|
|
9187
|
+
},
|
|
9120
9188
|
},
|
|
9121
9189
|
},
|
|
9122
9190
|
ticket_queues: {
|
|
@@ -9729,7 +9797,7 @@ If a voicemail is left, it is indicated by recordingURI, transcription, or recor
|
|
|
9729
9797
|
fields: {
|
|
9730
9798
|
...BuiltInFields,
|
|
9731
9799
|
integration: { validator: stringValidator, readonly: true, examples: ['Canvas'] },
|
|
9732
|
-
status: { validator: exactMatchValidator(['Success', 'Error']), readonly: true, examples: ['Error'] },
|
|
9800
|
+
status: { validator: exactMatchValidator(['Success', 'Error', 'Info']), readonly: true, examples: ['Error'] },
|
|
9733
9801
|
type: { validator: stringValidator, readonly: true, examples: ['Patient Create'] },
|
|
9734
9802
|
payload: { validator: stringValidator, readonly: true, examples: ['{}'] },
|
|
9735
9803
|
response: { validator: stringValidator, readonly: true, examples: ['{}'] },
|