@nbt-dev/nbt 0.0.1 → 0.0.4
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/LICENSE +177 -21
- package/README.md +16 -13
- package/TRADEMARKS.md +49 -0
- package/dist/nbt.js +398 -19
- package/package.json +5 -4
- package/stdlib/auth/README.md +83 -0
- package/stdlib/auth/migrations/20260424144652_initial/migration.nbt +48 -0
- package/stdlib/auth/migrations/20260424144652_initial/schema_snapshot.nbt +58 -0
- package/stdlib/auth/migrations/20260521191014_update_user/migration.nbt +3 -0
- package/stdlib/auth/migrations/20260521191014_update_user/schema_snapshot.nbt +59 -0
- package/stdlib/auth/schema.nbt +142 -0
- package/stdlib/calendar/adapters/gohighlevel/tests/fixtures/v2_calendar_pilot.json +12 -0
- package/stdlib/calendar/adapters/gohighlevel/tests/fixtures/webhooks/appointment_changed.json +70 -0
- package/stdlib/calendar/adapters/gohighlevel/tests/fixtures/webhooks/appointment_created.json +72 -0
- package/stdlib/calendar/migrations/20260501210107_initial/migration.nbt +60 -0
- package/stdlib/calendar/migrations/20260501210107_initial/schema_snapshot.nbt +66 -0
- package/stdlib/calendar/migrations/20260513151050_schema_update/migration.nbt +17 -0
- package/stdlib/calendar/migrations/20260513151050_schema_update/schema_snapshot.nbt +83 -0
- package/stdlib/calendar/schema.nbt +86 -0
- package/stdlib/chat/migrations/20260429222411_initial/migration.nbt +59 -0
- package/stdlib/chat/migrations/20260429222411_initial/schema_snapshot.nbt +71 -0
- package/stdlib/chat/migrations/20260430185225_add_messagereaction/migration.nbt +9 -0
- package/stdlib/chat/migrations/20260430185225_add_messagereaction/schema_snapshot.nbt +78 -0
- package/stdlib/chat/migrations/20260518191152_update_message/migration.nbt +3 -0
- package/stdlib/chat/migrations/20260518191152_update_message/schema_snapshot.nbt +81 -0
- package/stdlib/chat/schema.nbt +130 -0
- package/stdlib/crm/adapters/gohighlevel/README.md +85 -0
- package/stdlib/crm/adapters/gohighlevel/tests/README.md +159 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_138fields.json +222 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_140fields.json +219 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_alt.json +212 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_changed.json +102 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_created.json +95 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_full.json +213 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_sparse.json +161 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_update_a.json +197 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/contact_update_b.json +197 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/opportunity_changed.json +85 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/opportunity_created.json +85 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_contact_pilot.json +43 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_contact_with_price_closed.json +7 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_contact_with_price_open.json +7 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_event_appointment_delete.json +1 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_event_calendar_update.json +1 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_event_contact_create.json +1 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_event_opp_status_update.json +1 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_opportunity_pilot.json +16 -0
- package/stdlib/crm/adapters/gohighlevel/tests/fixtures/webhooks/v2_pipelines_pilot.json +137 -0
- package/stdlib/crm/migrations/20260501210107_initial/migration.nbt +63 -0
- package/stdlib/crm/migrations/20260501210107_initial/schema_snapshot.nbt +73 -0
- package/stdlib/crm/migrations/20260513151050_schema_update/migration.nbt +13 -0
- package/stdlib/crm/migrations/20260513151050_schema_update/schema_snapshot.nbt +86 -0
- package/stdlib/crm/schema.nbt +148 -0
- package/stdlib/design/migrations/20260501210107_initial/migration.nbt +19 -0
- package/stdlib/design/migrations/20260501210107_initial/schema_snapshot.nbt +21 -0
- package/stdlib/design/migrations/20260610130000_design_system/migration.nbt +50 -0
- package/stdlib/design/migrations/20260610130000_design_system/schema_snapshot.nbt +80 -0
- package/stdlib/design/schema.nbt +140 -0
- package/stdlib/dns/migrations/20260501210107_initial/migration.nbt +32 -0
- package/stdlib/dns/migrations/20260501210107_initial/schema_snapshot.nbt +36 -0
- package/stdlib/dns/schema.nbt +68 -0
- package/stdlib/email/migrations/20260427235207_initial/migration.nbt +75 -0
- package/stdlib/email/migrations/20260427235207_initial/schema_snapshot.nbt +87 -0
- package/stdlib/email/schema.nbt +145 -0
- package/stdlib/ingest/README.md +29 -0
- package/stdlib/ingest/migrations/20260424144652_initial/migration.nbt +18 -0
- package/stdlib/ingest/migrations/20260424144652_initial/schema_snapshot.nbt +20 -0
- package/stdlib/ingest/migrations/20260429203747_schema_update/migration.nbt +3 -0
- package/stdlib/ingest/migrations/20260429203747_schema_update/schema_snapshot.nbt +21 -0
- package/stdlib/ingest/schema.nbt +37 -0
- package/stdlib/notifications/README.md +118 -0
- package/stdlib/notifications/migrations/20260430204408_initial/migration.nbt +42 -0
- package/stdlib/notifications/migrations/20260430204408_initial/schema_snapshot.nbt +46 -0
- package/stdlib/notifications/schema.nbt +67 -0
- package/stdlib/phone/migrations/20260605205722_initial/migration.nbt +50 -0
- package/stdlib/phone/migrations/20260605205722_initial/schema_snapshot.nbt +56 -0
- package/stdlib/phone/schema.nbt +95 -0
- package/stdlib/registry/migrations/20260602181932_initial/migration.nbt +8 -0
- package/stdlib/registry/migrations/20260602181932_initial/schema_snapshot.nbt +8 -0
- package/stdlib/registry/schema.nbt +20 -0
- package/stdlib/workflows/schema.nbt +44 -0
- package/vendor/linux-x64/cartridges/auth/migrations/20260424144652_initial/migration.nbt +48 -0
- package/vendor/linux-x64/cartridges/auth/migrations/20260424144652_initial/schema_snapshot.nbt +58 -0
- package/vendor/linux-x64/cartridges/auth/migrations/20260521191014_update_user/migration.nbt +3 -0
- package/vendor/linux-x64/cartridges/auth/migrations/20260521191014_update_user/schema_snapshot.nbt +59 -0
- package/vendor/linux-x64/cartridges/auth/schema.nbt +142 -0
- package/vendor/linux-x64/cartridges/calendar/migrations/20260501210107_initial/migration.nbt +60 -0
- package/vendor/linux-x64/cartridges/calendar/migrations/20260501210107_initial/schema_snapshot.nbt +66 -0
- package/vendor/linux-x64/cartridges/calendar/migrations/20260513151050_schema_update/migration.nbt +17 -0
- package/vendor/linux-x64/cartridges/calendar/migrations/20260513151050_schema_update/schema_snapshot.nbt +83 -0
- package/vendor/linux-x64/cartridges/calendar/schema.nbt +86 -0
- package/vendor/linux-x64/cartridges/chat/migrations/20260429222411_initial/migration.nbt +59 -0
- package/vendor/linux-x64/cartridges/chat/migrations/20260429222411_initial/schema_snapshot.nbt +71 -0
- package/vendor/linux-x64/cartridges/chat/migrations/20260430185225_add_messagereaction/migration.nbt +9 -0
- package/vendor/linux-x64/cartridges/chat/migrations/20260430185225_add_messagereaction/schema_snapshot.nbt +78 -0
- package/vendor/linux-x64/cartridges/chat/migrations/20260518191152_update_message/migration.nbt +3 -0
- package/vendor/linux-x64/cartridges/chat/migrations/20260518191152_update_message/schema_snapshot.nbt +81 -0
- package/vendor/linux-x64/cartridges/chat/schema.nbt +130 -0
- package/vendor/linux-x64/cartridges/crm/migrations/20260501210107_initial/migration.nbt +63 -0
- package/vendor/linux-x64/cartridges/crm/migrations/20260501210107_initial/schema_snapshot.nbt +73 -0
- package/vendor/linux-x64/cartridges/crm/migrations/20260513151050_schema_update/migration.nbt +13 -0
- package/vendor/linux-x64/cartridges/crm/migrations/20260513151050_schema_update/schema_snapshot.nbt +86 -0
- package/vendor/linux-x64/cartridges/crm/schema.nbt +148 -0
- package/vendor/linux-x64/cartridges/design/migrations/20260501210107_initial/migration.nbt +19 -0
- package/vendor/linux-x64/cartridges/design/migrations/20260501210107_initial/schema_snapshot.nbt +21 -0
- package/vendor/linux-x64/cartridges/design/migrations/20260610130000_design_system/migration.nbt +50 -0
- package/vendor/linux-x64/cartridges/design/migrations/20260610130000_design_system/schema_snapshot.nbt +80 -0
- package/vendor/linux-x64/cartridges/design/schema.nbt +140 -0
- package/vendor/linux-x64/cartridges/dns/migrations/20260501210107_initial/migration.nbt +32 -0
- package/vendor/linux-x64/cartridges/dns/migrations/20260501210107_initial/schema_snapshot.nbt +36 -0
- package/vendor/linux-x64/cartridges/dns/schema.nbt +68 -0
- package/vendor/linux-x64/cartridges/email/migrations/20260427235207_initial/migration.nbt +75 -0
- package/vendor/linux-x64/cartridges/email/migrations/20260427235207_initial/schema_snapshot.nbt +87 -0
- package/vendor/linux-x64/cartridges/email/schema.nbt +145 -0
- package/vendor/linux-x64/cartridges/ingest/migrations/20260424144652_initial/migration.nbt +18 -0
- package/vendor/linux-x64/cartridges/ingest/migrations/20260424144652_initial/schema_snapshot.nbt +20 -0
- package/vendor/linux-x64/cartridges/ingest/migrations/20260429203747_schema_update/migration.nbt +3 -0
- package/vendor/linux-x64/cartridges/ingest/migrations/20260429203747_schema_update/schema_snapshot.nbt +21 -0
- package/vendor/linux-x64/cartridges/ingest/schema.nbt +37 -0
- package/vendor/linux-x64/cartridges/notifications/migrations/20260430204408_initial/migration.nbt +42 -0
- package/vendor/linux-x64/cartridges/notifications/migrations/20260430204408_initial/schema_snapshot.nbt +46 -0
- package/vendor/linux-x64/cartridges/notifications/schema.nbt +67 -0
- package/vendor/linux-x64/cartridges/phone/migrations/20260605205722_initial/migration.nbt +50 -0
- package/vendor/linux-x64/cartridges/phone/migrations/20260605205722_initial/schema_snapshot.nbt +56 -0
- package/vendor/linux-x64/cartridges/phone/schema.nbt +95 -0
- package/vendor/linux-x64/cartridges/registry/migrations/20260602181932_initial/migration.nbt +8 -0
- package/vendor/linux-x64/cartridges/registry/migrations/20260602181932_initial/schema_snapshot.nbt +8 -0
- package/vendor/linux-x64/cartridges/registry/schema.nbt +20 -0
- package/vendor/linux-x64/cartridges/workflows/schema.nbt +44 -0
- package/vendor/linux-x64/console +0 -0
- package/vendor/linux-x64/nbt +0 -0
- package/contracts/audit/.dist/contract.json +0 -56
- package/contracts/auth/.dist/contract.json +0 -252
- package/contracts/calendar/.dist/contract.json +0 -141
- package/contracts/chat/.dist/contract.json +0 -229
- package/contracts/crm/.dist/contract.json +0 -239
- package/contracts/design/.dist/contract.json +0 -85
- package/contracts/dns/.dist/contract.json +0 -123
- package/contracts/email/.dist/contract.json +0 -267
- package/contracts/embed/.dist/contract.json +0 -137
- package/contracts/ingest/.dist/contract.json +0 -86
- package/contracts/notifications/.dist/contract.json +0 -133
- package/contracts/phone/.dist/contract.json +0 -168
- package/contracts/registry/.dist/contract.json +0 -49
- package/contracts/workflows/.dist/contract.json +0 -106
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
entity User {
|
|
2
|
+
name: string
|
|
3
|
+
username?: string
|
|
4
|
+
email?: string
|
|
5
|
+
emailVerified: bool
|
|
6
|
+
externalId?: string
|
|
7
|
+
capsVersion: u32
|
|
8
|
+
@@index([email])
|
|
9
|
+
@@index([externalId])
|
|
10
|
+
@@unique([email])
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
entity UserRole {
|
|
14
|
+
userId: string
|
|
15
|
+
cart: string
|
|
16
|
+
role: string
|
|
17
|
+
@@index([userId])
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
entity Session {
|
|
21
|
+
userId: string
|
|
22
|
+
token: string
|
|
23
|
+
expiresAt: DateTime
|
|
24
|
+
ipAddress?: string
|
|
25
|
+
userAgent?: string
|
|
26
|
+
@@index([token])
|
|
27
|
+
@@index([userId])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
entity Account {
|
|
31
|
+
userId: string
|
|
32
|
+
providerId: string
|
|
33
|
+
password: string
|
|
34
|
+
accessToken: string
|
|
35
|
+
refreshToken: string
|
|
36
|
+
idToken: string
|
|
37
|
+
accessTokenExpiresAt: DateTime
|
|
38
|
+
refreshTokenExpiresAt: DateTime
|
|
39
|
+
scope: string
|
|
40
|
+
@@index([userId])
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
entity Verification {
|
|
44
|
+
identifier: string
|
|
45
|
+
value: string
|
|
46
|
+
expiresAt: DateTime
|
|
47
|
+
@@index([identifier])
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
entity ApiKey {
|
|
51
|
+
name: string
|
|
52
|
+
projectId: string
|
|
53
|
+
start: string
|
|
54
|
+
prefix: string
|
|
55
|
+
key: string
|
|
56
|
+
permissions: string
|
|
57
|
+
roles: string
|
|
58
|
+
}
|
|
59
|
+
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import crypto from "crypto"
|
|
2
|
+
|
|
3
|
+
# Auth policy for the hand-written routes in native/runtime.jai (formerly the
|
|
4
|
+
# @public actions + the `authenticate` middleware block). These keep the
|
|
5
|
+
# daemon's public-route + middleware manifest correct: public routes bypass the
|
|
6
|
+
# /api/* auth gate; @middleware tells the proxy this cart exports the global
|
|
7
|
+
# authenticate gate (registered at /_middleware/authenticate). The @authn
|
|
8
|
+
# (service) sync/role routes carry NO directive — they require auth, gated
|
|
9
|
+
# inline in the handler.
|
|
10
|
+
@public_route "/api/auth/user/signup"
|
|
11
|
+
@public_route "/api/auth/user/signin"
|
|
12
|
+
@public_route "/api/auth/session/signout"
|
|
13
|
+
@public_route "/api/auth/session/current"
|
|
14
|
+
@public_route "/api/auth/user/forgot_password"
|
|
15
|
+
@public_route "/api/auth/user/reset_password"
|
|
16
|
+
@public_route "/api/auth/user/verify_email"
|
|
17
|
+
@middleware "authenticate"
|
|
18
|
+
|
|
19
|
+
export entity User {
|
|
20
|
+
id: ulid
|
|
21
|
+
createdAt: DateTime @default(now())
|
|
22
|
+
updatedAt: DateTime @updatedAt
|
|
23
|
+
name: string
|
|
24
|
+
username?: string
|
|
25
|
+
email?: string
|
|
26
|
+
emailVerified: bool
|
|
27
|
+
externalId?: string
|
|
28
|
+
capsVersion: u32 # what is this?
|
|
29
|
+
|
|
30
|
+
@@index([email])
|
|
31
|
+
@@index([externalId])
|
|
32
|
+
@@unique([email])
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Per-cartridge role assignments. Role names refer to entries in the owning
|
|
36
|
+
# cartridge's `roles { }` block — this cartridge does not validate them.
|
|
37
|
+
entity UserRole {
|
|
38
|
+
id: ulid
|
|
39
|
+
createdAt: DateTime @default(now())
|
|
40
|
+
updatedAt: DateTime @updatedAt
|
|
41
|
+
userId: string
|
|
42
|
+
cart: string
|
|
43
|
+
role: string
|
|
44
|
+
|
|
45
|
+
@@index([userId])
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
entity Session {
|
|
49
|
+
id: ulid
|
|
50
|
+
createdAt: DateTime @default(now())
|
|
51
|
+
updatedAt: DateTime @updatedAt
|
|
52
|
+
userId: string
|
|
53
|
+
token: string
|
|
54
|
+
expiresAt: DateTime
|
|
55
|
+
ipAddress?: string
|
|
56
|
+
userAgent?: string
|
|
57
|
+
|
|
58
|
+
@@index([token])
|
|
59
|
+
@@index([userId])
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
entity Account {
|
|
63
|
+
id: ulid
|
|
64
|
+
createdAt: DateTime @default(now())
|
|
65
|
+
updatedAt: DateTime @updatedAt
|
|
66
|
+
userId: string
|
|
67
|
+
providerId: string
|
|
68
|
+
password: string
|
|
69
|
+
accessToken: string
|
|
70
|
+
refreshToken: string
|
|
71
|
+
idToken: string
|
|
72
|
+
accessTokenExpiresAt: DateTime
|
|
73
|
+
refreshTokenExpiresAt: DateTime
|
|
74
|
+
scope: string
|
|
75
|
+
|
|
76
|
+
@@index([userId])
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
entity Verification {
|
|
80
|
+
id: ulid
|
|
81
|
+
createdAt: DateTime @default(now())
|
|
82
|
+
updatedAt: DateTime @updatedAt
|
|
83
|
+
identifier: string
|
|
84
|
+
value: string
|
|
85
|
+
expiresAt: DateTime
|
|
86
|
+
|
|
87
|
+
@@index([identifier])
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
entity ApiKey {
|
|
91
|
+
id: ulid
|
|
92
|
+
createdAt: DateTime @default(now())
|
|
93
|
+
updatedAt: DateTime @updatedAt
|
|
94
|
+
name: string
|
|
95
|
+
projectId: string
|
|
96
|
+
start: string
|
|
97
|
+
prefix: string
|
|
98
|
+
key: string
|
|
99
|
+
permissions: string
|
|
100
|
+
roles: string
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# Console-operator SSH public keys. The console daemon authenticates SSH
|
|
104
|
+
# connections by looking up rows here via modules/auth_lookup/ (in-process,
|
|
105
|
+
# direct storage read — auth cart liveness is not required).
|
|
106
|
+
entity SshKey {
|
|
107
|
+
id: ulid
|
|
108
|
+
createdAt: DateTime @default(now())
|
|
109
|
+
updatedAt: DateTime @updatedAt
|
|
110
|
+
userId: string
|
|
111
|
+
label: string
|
|
112
|
+
blob: string
|
|
113
|
+
|
|
114
|
+
@@index([userId])
|
|
115
|
+
@@unique([blob])
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
jai {
|
|
119
|
+
find_synced_user :: (requestedId: string, email: string) -> (User, bool) {
|
|
120
|
+
if requestedId.count > 0 {
|
|
121
|
+
by_id, by_id_ok := get_user(requestedId);
|
|
122
|
+
if by_id_ok return by_id, true;
|
|
123
|
+
|
|
124
|
+
by_external := find_users_by_externalId(requestedId);
|
|
125
|
+
if by_external.count > 0 {
|
|
126
|
+
u, ok := get_user(by_external[0].id);
|
|
127
|
+
if ok return u, true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if email.count > 0 {
|
|
132
|
+
by_email := find_users_by_email(email);
|
|
133
|
+
if by_email.count > 0 {
|
|
134
|
+
u, ok := get_user(by_email[0].id);
|
|
135
|
+
if ok return u, true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
empty: User;
|
|
140
|
+
return empty, false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"createdAt": "2026-01-20T18:23:25.182Z",
|
|
3
|
+
"description": "<p style=\"margin:0px;color:#10182899\">Quick call with our local specialist to see if solar makes sense for you</p>",
|
|
4
|
+
"id": "zKW5Rx1wttNPLBXIYRh5",
|
|
5
|
+
"isActive": true,
|
|
6
|
+
"name": "Solar Discovery Call (ME FB BR)",
|
|
7
|
+
"slotDuration": 15,
|
|
8
|
+
"slotInterval": 15,
|
|
9
|
+
"source": "ghl",
|
|
10
|
+
"timezone": "America/Toronto",
|
|
11
|
+
"updatedAt": "2026-04-30T14:15:34.287Z"
|
|
12
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"workflow": {"id": "f1d4c9b2-3a76-4ed8-bb12-9c4f0e5d7a01", "name": "Appointment Changed Sync"},
|
|
3
|
+
"type": "AppointmentUpdate",
|
|
4
|
+
"customData": {"org": "mlp", "project": "default", "type": "Appointment"},
|
|
5
|
+
"location": {
|
|
6
|
+
"id": "loc_test",
|
|
7
|
+
"name": "MyLocalPro Test",
|
|
8
|
+
"address": "22 Old Village Rd Sturbridge MA 01566",
|
|
9
|
+
"city": "Sturbridge",
|
|
10
|
+
"country": "US",
|
|
11
|
+
"fullAddress": "22 Old Village Rd Sturbridge MA 01566, Sturbridge MA 01566",
|
|
12
|
+
"postalCode": "01566",
|
|
13
|
+
"state": "MA"
|
|
14
|
+
},
|
|
15
|
+
"contact_id": "ctc_alice_001",
|
|
16
|
+
"first_name": "Alice",
|
|
17
|
+
"last_name": "Anderson-Smith",
|
|
18
|
+
"full_name": "Alice Anderson-Smith",
|
|
19
|
+
"email": "alice.smith@example.com",
|
|
20
|
+
"phone": "+15551234567",
|
|
21
|
+
"address1": "456 Updated Ave",
|
|
22
|
+
"full_address": "456 Updated Ave, Toronto ON M5V 2A2",
|
|
23
|
+
"city": "Toronto",
|
|
24
|
+
"state": "ON",
|
|
25
|
+
"country": "CA",
|
|
26
|
+
"postal_code": "M5V 2A2",
|
|
27
|
+
"timezone": "America/Toronto",
|
|
28
|
+
"tags": "solar,residential,rescheduled",
|
|
29
|
+
"contact_source": "Solar Survey MLP Skynet",
|
|
30
|
+
"contact_type": "lead",
|
|
31
|
+
"attributionSource": {},
|
|
32
|
+
"contact": {
|
|
33
|
+
"attributionSource": {
|
|
34
|
+
"campaign": "spring-solar",
|
|
35
|
+
"sessionSource": "Website"
|
|
36
|
+
},
|
|
37
|
+
"lastAttributionSource": {}
|
|
38
|
+
},
|
|
39
|
+
"calendar": {
|
|
40
|
+
"appointmentId": "apt_001",
|
|
41
|
+
"id": "cal_solar_consult",
|
|
42
|
+
"calendarName": "Solar Consultation",
|
|
43
|
+
"title": "Initial Solar Consult — Alice Anderson",
|
|
44
|
+
"address": "456 Updated Ave, Toronto, ON",
|
|
45
|
+
"notes": "Rescheduled per customer request; closer reassigned.",
|
|
46
|
+
"startTime": "2026-05-15T10:00:00",
|
|
47
|
+
"endTime": "2026-05-15T11:00:00",
|
|
48
|
+
"appoinmentStatus": "showed",
|
|
49
|
+
"appointmentStatus": "confirmed",
|
|
50
|
+
"selectedTimezone": "America/Toronto",
|
|
51
|
+
"assignedUserId": "usr_002"
|
|
52
|
+
},
|
|
53
|
+
"Setter": "Diana Davis",
|
|
54
|
+
"Setter Name": "Diana Davis",
|
|
55
|
+
"Closer": "Charlie Chen",
|
|
56
|
+
"Appointment Outcome": "showed",
|
|
57
|
+
"Appointment Time": "2026-05-15T10:00:00",
|
|
58
|
+
"Appointment Type": "Discovery Call",
|
|
59
|
+
"Average Electric Bill": "245",
|
|
60
|
+
"Shade?": "minimal",
|
|
61
|
+
"Utility": "Toronto Hydro",
|
|
62
|
+
"Total Contract Price": "",
|
|
63
|
+
"Date Sold": "",
|
|
64
|
+
"triggerData": {},
|
|
65
|
+
"user": {
|
|
66
|
+
"email": "charlie@example.com",
|
|
67
|
+
"firstName": "Charlie",
|
|
68
|
+
"lastName": "Chen"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"workflow": {"id": "f1d4c9b2-3a76-4ed8-bb12-9c4f0e5d7a01", "name": "Appointment Created Sync"},
|
|
3
|
+
"type": "AppointmentCreate",
|
|
4
|
+
"customData": {"org": "mlp", "project": "default", "type": "Appointment"},
|
|
5
|
+
"location": {
|
|
6
|
+
"id": "loc_test",
|
|
7
|
+
"name": "MyLocalPro Test",
|
|
8
|
+
"address": "22 Old Village Rd Sturbridge MA 01566",
|
|
9
|
+
"city": "Sturbridge",
|
|
10
|
+
"country": "US",
|
|
11
|
+
"fullAddress": "22 Old Village Rd Sturbridge MA 01566, Sturbridge MA 01566",
|
|
12
|
+
"postalCode": "01566",
|
|
13
|
+
"state": "MA"
|
|
14
|
+
},
|
|
15
|
+
"contact_id": "ctc_alice_001",
|
|
16
|
+
"first_name": "Alice",
|
|
17
|
+
"last_name": "Anderson",
|
|
18
|
+
"full_name": "Alice Anderson",
|
|
19
|
+
"email": "alice@example.com",
|
|
20
|
+
"phone": "+15551234567",
|
|
21
|
+
"address1": "123 Main St",
|
|
22
|
+
"full_address": "123 Main St, Toronto ON M5V 1A1",
|
|
23
|
+
"city": "Toronto",
|
|
24
|
+
"state": "ON",
|
|
25
|
+
"country": "CA",
|
|
26
|
+
"postal_code": "M5V 1A1",
|
|
27
|
+
"timezone": "America/Toronto",
|
|
28
|
+
"tags": "solar,residential",
|
|
29
|
+
"contact_source": "Solar Survey MLP Skynet",
|
|
30
|
+
"contact_type": "lead",
|
|
31
|
+
"attributionSource": {},
|
|
32
|
+
"contact": {
|
|
33
|
+
"attributionSource": {
|
|
34
|
+
"campaign": "spring-solar",
|
|
35
|
+
"medium": "cpc",
|
|
36
|
+
"sessionSource": "Website"
|
|
37
|
+
},
|
|
38
|
+
"lastAttributionSource": {}
|
|
39
|
+
},
|
|
40
|
+
"calendar": {
|
|
41
|
+
"appointmentId": "apt_001",
|
|
42
|
+
"id": "cal_solar_consult",
|
|
43
|
+
"calendarName": "Solar Consultation",
|
|
44
|
+
"title": "Initial Solar Consult — Alice Anderson",
|
|
45
|
+
"address": "123 Main St, Toronto, ON",
|
|
46
|
+
"notes": "Customer interested in 8kW system; financing questions.",
|
|
47
|
+
"startTime": "2026-05-12T14:00:00-04:00",
|
|
48
|
+
"endTime": "2026-05-12T15:00:00-04:00",
|
|
49
|
+
"appoinmentStatus": "confirmed",
|
|
50
|
+
"selectedTimezone": "America/Toronto",
|
|
51
|
+
"assignedUserId": "usr_001"
|
|
52
|
+
},
|
|
53
|
+
"Setter": "Diana Davis",
|
|
54
|
+
"Setter Name": "Diana Davis",
|
|
55
|
+
"Closer": "Bob Brown",
|
|
56
|
+
"Appointment Outcome": "",
|
|
57
|
+
"Appointment Time": "2026-05-12T14:00:00-04:00",
|
|
58
|
+
"Appointment Type": "Discovery Call",
|
|
59
|
+
"Average Electric Bill": "245",
|
|
60
|
+
"Shade?": "minimal",
|
|
61
|
+
"Utility": "Toronto Hydro",
|
|
62
|
+
"Total Contract Price": "",
|
|
63
|
+
"Date Sold": "",
|
|
64
|
+
"created_by": "Diana Davis",
|
|
65
|
+
"created_by_user_id": "usr_003",
|
|
66
|
+
"triggerData": {},
|
|
67
|
+
"user": {
|
|
68
|
+
"email": "diana@example.com",
|
|
69
|
+
"firstName": "Diana",
|
|
70
|
+
"lastName": "Davis"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
migration initial {
|
|
2
|
+
add_entity Calendar
|
|
3
|
+
add_field Calendar name string default("")
|
|
4
|
+
add_field Calendar description string default("")
|
|
5
|
+
add_field Calendar timezone string default("")
|
|
6
|
+
add_field Calendar slotDuration u32 default(0)
|
|
7
|
+
add_field Calendar slotInterval u32 default(0)
|
|
8
|
+
add_field Calendar isActive bool default(false)
|
|
9
|
+
add_field Calendar source string default("")
|
|
10
|
+
add_entity Appointment
|
|
11
|
+
add_field Appointment calendar Calendar default(0)
|
|
12
|
+
add_field Appointment contact Contact default(0)
|
|
13
|
+
add_field Appointment title string default("")
|
|
14
|
+
add_field Appointment address string default("")
|
|
15
|
+
add_field Appointment notes string default("")
|
|
16
|
+
add_field Appointment startTime DateTime default(0)
|
|
17
|
+
add_field Appointment endTime DateTime default(0)
|
|
18
|
+
add_field Appointment timezone string default("")
|
|
19
|
+
add_field Appointment status string default("")
|
|
20
|
+
add_field Appointment source string default("")
|
|
21
|
+
add_field Appointment assignedUser User default(0)
|
|
22
|
+
add_field Appointment isRescheduled bool default(false)
|
|
23
|
+
add_field Appointment originalStartTime DateTime default(0)
|
|
24
|
+
add_field Appointment originalEndTime DateTime default(0)
|
|
25
|
+
add_index Appointment [contactId]
|
|
26
|
+
add_index Appointment [calendarId]
|
|
27
|
+
add_entity Contact
|
|
28
|
+
add_field Contact firstName string default("")
|
|
29
|
+
add_field Contact lastName string default("")
|
|
30
|
+
add_field Contact fullName string default("")
|
|
31
|
+
add_field Contact phone string default("")
|
|
32
|
+
add_field Contact mobile string default("")
|
|
33
|
+
add_field Contact email string default("")
|
|
34
|
+
add_field Contact address string default("")
|
|
35
|
+
add_field Contact fullAddress string default("")
|
|
36
|
+
add_field Contact postalCode string default("")
|
|
37
|
+
add_field Contact city string default("")
|
|
38
|
+
add_field Contact stateOrProvince string default("")
|
|
39
|
+
add_field Contact country string default("")
|
|
40
|
+
add_field Contact timezone string default("")
|
|
41
|
+
add_field Contact lat float default(0)
|
|
42
|
+
add_field Contact lon float default(0)
|
|
43
|
+
add_field Contact company string default("")
|
|
44
|
+
add_field Contact website string default("")
|
|
45
|
+
add_field Contact title string default("")
|
|
46
|
+
add_field Contact industry string default("")
|
|
47
|
+
add_field Contact source string default("")
|
|
48
|
+
add_field Contact notes string default("")
|
|
49
|
+
add_field Contact data document default(0)
|
|
50
|
+
add_field Contact customData document default(0)
|
|
51
|
+
add_entity User
|
|
52
|
+
add_field User name string default("")
|
|
53
|
+
add_field User username string default("")
|
|
54
|
+
add_field User email string default("")
|
|
55
|
+
add_field User emailVerified bool default(false)
|
|
56
|
+
add_field User externalId string default("")
|
|
57
|
+
add_field User capsVersion u32 default(0)
|
|
58
|
+
add_index User [email]
|
|
59
|
+
add_index User [externalId]
|
|
60
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
entity Calendar {
|
|
2
|
+
name: string
|
|
3
|
+
description?: string
|
|
4
|
+
timezone?: string
|
|
5
|
+
slotDuration?: u32
|
|
6
|
+
slotInterval?: u32
|
|
7
|
+
isActive: bool
|
|
8
|
+
source?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
entity Appointment {
|
|
12
|
+
calendar: Calendar
|
|
13
|
+
contact: Contact
|
|
14
|
+
title?: string
|
|
15
|
+
address?: string
|
|
16
|
+
notes?: string
|
|
17
|
+
startTime: DateTime
|
|
18
|
+
endTime: DateTime
|
|
19
|
+
timezone?: string
|
|
20
|
+
status: string
|
|
21
|
+
source?: string
|
|
22
|
+
assignedUser?: User
|
|
23
|
+
isRescheduled: bool
|
|
24
|
+
originalStartTime?: DateTime
|
|
25
|
+
originalEndTime?: DateTime
|
|
26
|
+
@@index([contactId])
|
|
27
|
+
@@index([calendarId])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
entity Contact {
|
|
31
|
+
firstName?: string
|
|
32
|
+
lastName?: string
|
|
33
|
+
fullName?: string
|
|
34
|
+
phone?: string
|
|
35
|
+
mobile?: string
|
|
36
|
+
email?: string
|
|
37
|
+
address?: string
|
|
38
|
+
fullAddress?: string
|
|
39
|
+
postalCode?: string
|
|
40
|
+
city?: string
|
|
41
|
+
stateOrProvince?: string
|
|
42
|
+
country?: string
|
|
43
|
+
timezone?: string
|
|
44
|
+
lat?: float
|
|
45
|
+
lon?: float
|
|
46
|
+
company?: string
|
|
47
|
+
website?: string
|
|
48
|
+
title?: string
|
|
49
|
+
industry?: string
|
|
50
|
+
source?: string
|
|
51
|
+
notes?: string
|
|
52
|
+
data: document
|
|
53
|
+
customData: document
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
entity User {
|
|
57
|
+
name: string
|
|
58
|
+
username?: string
|
|
59
|
+
email?: string
|
|
60
|
+
emailVerified: bool
|
|
61
|
+
externalId?: string
|
|
62
|
+
capsVersion: u32
|
|
63
|
+
@@index([email])
|
|
64
|
+
@@index([externalId])
|
|
65
|
+
}
|
|
66
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
migration schema_update {
|
|
2
|
+
add_field Appointment state string default("")
|
|
3
|
+
add_field Appointment outcomeClass string default("")
|
|
4
|
+
add_field Appointment embedText string default("")
|
|
5
|
+
add_index Appointment [state]
|
|
6
|
+
add_index Appointment [outcomeClass]
|
|
7
|
+
add_entity AppointmentParticipant
|
|
8
|
+
add_field AppointmentParticipant appointment Appointment default(0)
|
|
9
|
+
add_field AppointmentParticipant user User default(0)
|
|
10
|
+
add_field AppointmentParticipant role string default("")
|
|
11
|
+
add_field AppointmentParticipant assignedAt DateTime default(0)
|
|
12
|
+
add_field AppointmentParticipant assignedBy User default(0)
|
|
13
|
+
add_field AppointmentParticipant notes string default("")
|
|
14
|
+
add_index AppointmentParticipant [appointmentId]
|
|
15
|
+
add_index AppointmentParticipant [userId, role]
|
|
16
|
+
add_unique AppointmentParticipant [appointmentId, role, userId]
|
|
17
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
entity Calendar {
|
|
2
|
+
name: string
|
|
3
|
+
description?: string
|
|
4
|
+
timezone?: string
|
|
5
|
+
slotDuration?: u32
|
|
6
|
+
slotInterval?: u32
|
|
7
|
+
isActive: bool
|
|
8
|
+
source?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
entity Appointment {
|
|
12
|
+
calendar: Calendar
|
|
13
|
+
contact: Contact
|
|
14
|
+
title?: string
|
|
15
|
+
address?: string
|
|
16
|
+
notes?: string
|
|
17
|
+
startTime: DateTime
|
|
18
|
+
endTime: DateTime
|
|
19
|
+
timezone?: string
|
|
20
|
+
status: string
|
|
21
|
+
source?: string
|
|
22
|
+
assignedUser?: User
|
|
23
|
+
isRescheduled: bool
|
|
24
|
+
originalStartTime?: DateTime
|
|
25
|
+
originalEndTime?: DateTime
|
|
26
|
+
state?: string
|
|
27
|
+
outcomeClass?: string
|
|
28
|
+
embedText?: string
|
|
29
|
+
@@index([contactId])
|
|
30
|
+
@@index([calendarId])
|
|
31
|
+
@@index([state])
|
|
32
|
+
@@index([outcomeClass])
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
entity AppointmentParticipant {
|
|
36
|
+
appointment: Appointment
|
|
37
|
+
user: User
|
|
38
|
+
role: string
|
|
39
|
+
assignedAt: DateTime
|
|
40
|
+
assignedBy?: User
|
|
41
|
+
notes?: string
|
|
42
|
+
@@unique([appointmentId, role, userId])
|
|
43
|
+
@@index([appointmentId])
|
|
44
|
+
@@index([userId, role])
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
entity Contact {
|
|
48
|
+
firstName?: string
|
|
49
|
+
lastName?: string
|
|
50
|
+
fullName?: string
|
|
51
|
+
phone?: string
|
|
52
|
+
mobile?: string
|
|
53
|
+
email?: string
|
|
54
|
+
address?: string
|
|
55
|
+
fullAddress?: string
|
|
56
|
+
postalCode?: string
|
|
57
|
+
city?: string
|
|
58
|
+
stateOrProvince?: string
|
|
59
|
+
country?: string
|
|
60
|
+
timezone?: string
|
|
61
|
+
lat?: float
|
|
62
|
+
lon?: float
|
|
63
|
+
company?: string
|
|
64
|
+
website?: string
|
|
65
|
+
title?: string
|
|
66
|
+
industry?: string
|
|
67
|
+
source?: string
|
|
68
|
+
notes?: string
|
|
69
|
+
data: document
|
|
70
|
+
customData: document
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
entity User {
|
|
74
|
+
name: string
|
|
75
|
+
username?: string
|
|
76
|
+
email?: string
|
|
77
|
+
emailVerified: bool
|
|
78
|
+
externalId?: string
|
|
79
|
+
capsVersion: u32
|
|
80
|
+
@@index([email])
|
|
81
|
+
@@index([externalId])
|
|
82
|
+
}
|
|
83
|
+
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {Contact} from "crm";
|
|
2
|
+
import {User} from "auth";
|
|
3
|
+
|
|
4
|
+
entity Calendar {
|
|
5
|
+
id: ulid
|
|
6
|
+
createdAt: DateTime @default(now())
|
|
7
|
+
updatedAt: DateTime @updatedAt
|
|
8
|
+
name: string
|
|
9
|
+
description?: string
|
|
10
|
+
timezone?: string
|
|
11
|
+
slotDuration?: u32
|
|
12
|
+
slotInterval?: u32
|
|
13
|
+
isActive: bool
|
|
14
|
+
source?: string
|
|
15
|
+
appointments: Appointment[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export entity Appointment {
|
|
19
|
+
id: ulid
|
|
20
|
+
createdAt: DateTime @default(now())
|
|
21
|
+
updatedAt: DateTime @updatedAt
|
|
22
|
+
calendar: Calendar
|
|
23
|
+
contact: Contact @relation(onDelete: Restrict)
|
|
24
|
+
title?: string
|
|
25
|
+
address?: string
|
|
26
|
+
notes?: string
|
|
27
|
+
startTime: DateTime
|
|
28
|
+
endTime: DateTime
|
|
29
|
+
timezone?: string
|
|
30
|
+
status: string
|
|
31
|
+
source?: string
|
|
32
|
+
assignedUser?: User @relation(onDelete: SetNull)
|
|
33
|
+
isRescheduled: bool
|
|
34
|
+
originalStartTime?: DateTime
|
|
35
|
+
originalEndTime?: DateTime
|
|
36
|
+
|
|
37
|
+
# Geographic state (e.g. "CA", "TX") parsed from `address` at ingest. Indexed
|
|
38
|
+
# so customers can filter assignment candidates by state cheaply.
|
|
39
|
+
state?: string
|
|
40
|
+
|
|
41
|
+
# Generic outcome label for similarity-weighted aggregation. Customer fills
|
|
42
|
+
# via their domain's lifecycle hook ("won" for MyLocalPro, "positive" for
|
|
43
|
+
# therapy). Indexed for `Appointment.find_by_outcomeClass("won")` lookups.
|
|
44
|
+
outcomeClass?: string
|
|
45
|
+
|
|
46
|
+
# Rendered embedding-template text. Persisted alongside the Appointment so
|
|
47
|
+
# similarity search can score (target_text, candidate_text) pairs without
|
|
48
|
+
# re-rendering the customer's @embed template on every query. Populated at
|
|
49
|
+
# ingest by the customer's @embed binding
|
|
50
|
+
# (D09.10c). Generic surface — every customer composing similarity search
|
|
51
|
+
# over Appointments needs it; the *content* of the text is customer policy.
|
|
52
|
+
embedText?: string
|
|
53
|
+
|
|
54
|
+
participants: AppointmentParticipant[]
|
|
55
|
+
|
|
56
|
+
# contact + calendar are FK fields — indexed automatically.
|
|
57
|
+
@@index([state])
|
|
58
|
+
@@index([outcomeClass])
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Many-to-many linkage between Appointment and User with a client-defined
|
|
62
|
+
# role label. Lets a deployment encode any participant taxonomy without
|
|
63
|
+
# adding new columns to Appointment:
|
|
64
|
+
#
|
|
65
|
+
# MyLocalPro: role = "setter" | "closer" | "shadower"
|
|
66
|
+
# Therapy: role = "therapist" | "supervisor"
|
|
67
|
+
# Field service: role = "primary" | "backup" | "trainee"
|
|
68
|
+
#
|
|
69
|
+
# `Appointment.assignedUser` stays as the conventional "primary owner"
|
|
70
|
+
# pointer (single value, indexed) for clients that don't need multi-role.
|
|
71
|
+
# AppointmentParticipant is additive — clients pick the row when they
|
|
72
|
+
# want richer linkage.
|
|
73
|
+
export entity AppointmentParticipant {
|
|
74
|
+
id: ulid
|
|
75
|
+
createdAt: DateTime @default(now())
|
|
76
|
+
updatedAt: DateTime @updatedAt
|
|
77
|
+
appointment: Appointment @relation(onDelete: Cascade)
|
|
78
|
+
user: User @relation(onDelete: Cascade)
|
|
79
|
+
role: string # client-defined (e.g. "setter", "closer")
|
|
80
|
+
assignedAt: DateTime @default(now())
|
|
81
|
+
assignedBy?: User @relation(onDelete: SetNull) # who recorded this assignment (for audit)
|
|
82
|
+
notes?: string
|
|
83
|
+
|
|
84
|
+
@@unique([appointment, role, user])
|
|
85
|
+
@@index([user, role])
|
|
86
|
+
}
|