@rubytech/create-maxy-code 0.1.342 → 0.1.344
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/package.json +1 -1
- package/payload/platform/config/brand.json +4 -1
- package/payload/platform/neo4j/schema.cypher +9 -5
- package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +4 -1
- package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-hostname.test.d.ts +2 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-hostname.test.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-hostname.test.js +175 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-hostname.test.js.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +33 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/admin-hostname.d.ts +15 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/admin-hostname.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/admin-hostname.js +86 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/admin-hostname.js.map +1 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +90 -1
- package/payload/platform/plugins/cloudflare/skills/calendar-site/SKILL.md +82 -0
- package/payload/platform/plugins/cloudflare/skills/calendar-site/template/functions/api/book.ts +112 -0
- package/payload/platform/plugins/cloudflare/skills/calendar-site/template/public/booking.css +100 -0
- package/payload/platform/plugins/cloudflare/skills/calendar-site/template/public/booking.js +155 -0
- package/payload/platform/plugins/cloudflare/skills/calendar-site/template/public/index.html +47 -0
- package/payload/platform/plugins/cloudflare/skills/calendar-site/template/schema.sql +18 -0
- package/payload/platform/plugins/cloudflare/skills/calendar-site/template/wrangler.toml +14 -0
- package/payload/platform/plugins/docs/PLUGIN.md +1 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +26 -0
- package/payload/platform/plugins/docs/references/calendar-booking.md +56 -0
- package/payload/platform/plugins/docs/references/internals.md +2 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +23 -0
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +19 -5
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-notify.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-notify.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-notify.test.js +45 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-notify.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js +89 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-write.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-write.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-write.test.js +118 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-write.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-classify.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-classify.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-classify.test.js +59 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-classify.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-notify.d.ts +22 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-notify.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-notify.js +31 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-notify.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +28 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +70 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/meeting-write.d.ts +35 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/meeting-write.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/meeting-write.js +123 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/meeting-write.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-classify.d.ts +23 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-classify.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-classify.js +38 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/schedule-classify.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.d.ts +21 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +280 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts +11 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +34 -2
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +2 -0
- package/payload/server/{chunk-5BG6CHGH.js → chunk-QAKVFSEJ.js} +15 -0
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/{AdminLoginScreens-Brx8CmXN.js → AdminLoginScreens-CZqsFfP0.js} +1 -1
- package/payload/server/public/assets/AdminShell-DnhBRZv5.js +1 -0
- package/payload/server/public/assets/{Checkbox-aePjWzRH.js → Checkbox-D0FwyuVg.js} +1 -1
- package/payload/server/public/assets/{OperatorConversations-BMIZQR9t.css → OperatorConversations-BG9GrxQU.css} +1 -1
- package/payload/server/public/assets/OperatorConversations-dt0q8mjv.js +9 -0
- package/payload/server/public/assets/admin-CCzmqd1F.js +1 -0
- package/payload/server/public/assets/{arc-CxLB9WCE.js → arc-DpkSQNto.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-Csj53u5T.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-D-EdJPSY.js → architectureDiagram-Q4EWVU46-Bw7Yq8O9.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CXx9RgCm.js → blockDiagram-DXYQGD6D-BBtJQFSz.js} +1 -1
- package/payload/server/public/assets/{browser-Bp5kGgyr.js → browser-kmrJq69n.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-RFBXEe0B.js → c4Diagram-AHTNJAMY-JAMgxzOr.js} +1 -1
- package/payload/server/public/assets/calendar-BWf5qrIH.js +1 -0
- package/payload/server/public/assets/channel-BUQUAUts.js +1 -0
- package/payload/server/public/assets/chat-C2e06_q0.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-DBqAFwK9.js → chunk-2KRD3SAO-eDugsc2L.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-DdnFEz6R.js → chunk-336JU56O-BXfECwdC.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-CdknReB2.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-cnw-3Gbs.js → chunk-4BX2VUAB-CByVeKCY.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-BnqJ0bDc.js → chunk-4TB4RGXK-CpY0DcUB.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-BwyHvvzo.js → chunk-55IACEB6-C3YxgyIb.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-DXA9U02I.js → chunk-5FUZZQ4R-Bc0d7j8A.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-D78bZ_8D.js → chunk-5PVQY5BW-CTUGMRIa.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-CtE_Mgv7.js → chunk-67CJDMHE-CbdPnpLd.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-CUZDaySl.js → chunk-7N4EOEYR-Cjl2kevz.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-CYQ3jO4X.js → chunk-AA7GKIK3-BgozIh5p.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-BbA_HyTR.js → chunk-BSJP7CBP-6Ufq45NW.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-D7_YqRhG.js → chunk-CIAEETIT-BhhYuMnA.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-B23LrtSw.js → chunk-EDXVE4YY-BfaJ3yDD.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-D3fTHYKN.js → chunk-ENJZ2VHE-C7-hIGVC.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-DFAA2tyh.js → chunk-FMBD7UC4-BQvvyocF.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-BF4IHvlI.js → chunk-FOC6F5B3-C6rBDOxH.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DBUGemHy.js → chunk-ICPOFSXX-BjOJvkVa.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-rMMs08Eh.js → chunk-K5T4RW27-kKowRHhn.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-BD2r8R2G.js → chunk-KGLVRYIC-bAEV_5eH.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-D4sYTTwM.js → chunk-LIHQZDEY-BLvsQAfg.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-CAs_uFzb.js → chunk-ORNJ4GCN-BzYZfPZ7.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-Fkp-2ORc.js → chunk-OYMX7WX6-CL7WRw42.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-8tHoEDE9.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-D_pxZh25.js → chunk-U2HBQHQK-BdcVGjau.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-CeVmvvRf.js → chunk-X2U36JSP-C0CL_Jin.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-iWP54fKp.js → chunk-XPW4576I-CsV7CUxH.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-CNtbWJNN.js → chunk-YZCP3GAM-Cj0_fLkR.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BmlFjU_9.js → chunk-ZZ45TVLE-DLuquyoY.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BEGZ3DLg.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DsLxnm5U.js +1 -0
- package/payload/server/public/assets/clone-uiXbH_kh.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-C7YmF1Pg.js → cose-bilkent-S5V4N54A-BU3EOLXX.js} +1 -1
- package/payload/server/public/assets/{dagre-BAmiDDtR.js → dagre-BRq8C9NU.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-Ca3ESJhc.js → dagre-KV5264BT-CoCAYhFc.js} +1 -1
- package/payload/server/public/assets/data-CZKWSjEH.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-BgT1ORf2.js → diagram-5BDNPKRD-DBy5GNaQ.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BTaUIiem.js → diagram-G4DWMVQ6-l93MsBLv.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-Bdb2g6Uo.js → diagram-MMDJMWI5-BIfXkVlL.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-CkLGC0zZ.js → diagram-TYMM5635-BuTJLBny.js} +1 -1
- package/payload/server/public/assets/{dist-Bkbhs3jw.js → dist-CtUNt3w8.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-D_sj4DMg.js → erDiagram-SMLLAGMA-BwPxWDbP.js} +1 -1
- package/payload/server/public/assets/{flatten-E2Sr0FeD.js → flatten-DtM0XAMt.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-iLERoZTe.js → flowDiagram-DWJPFMVM-BhPtHXMR.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-D60hjMBy.js → ganttDiagram-T4ZO3ILL-BlXjprdD.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-D_2KrZoP.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-Di0XM6fi.js → gitGraphDiagram-UUTBAWPF-BW36BDiu.js} +1 -1
- package/payload/server/public/assets/{graph-Bnsvbnkf.js → graph-BxErrIf_.js} +3 -3
- package/payload/server/public/assets/{graph-labels-jduMtwXb.js → graph-labels-Ch5_g_JF.js} +1 -1
- package/payload/server/public/assets/{graphlib-C8fUP7uV.js → graphlib-Bjg3Tq-k.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-BP2TNwQ4.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-D1kDtBOY.js +2 -0
- package/payload/server/public/assets/{isEmpty-CLz-UprQ.js → isEmpty-D__iH1WQ.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CwgI4B5Z.js → ishikawaDiagram-UXIWVN3A-CmB-bA_O.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CxBu-tze.js → journeyDiagram-VCZTEJTY-Bt1fJKmc.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-D2qlheA5.js → kanban-definition-6JOO6SKY-DVbksz_J.js} +1 -1
- package/payload/server/public/assets/{line-Bdod7uzQ.js → line-BX2Ugx3B.js} +1 -1
- package/payload/server/public/assets/{linear-BiVe6QzC.js → linear-Bdc-QJWI.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-xZN7hC6M.js → mermaid-parser.core-qv1e-J5x.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-D0IylAac.js → mermaid.core-C_d9YQX_.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-J_Szhwf1.js → mindmap-definition-QFDTVHPH-DwKGvF14.js} +1 -1
- package/payload/server/public/assets/operator-CdlBsCdn.js +1 -0
- package/payload/server/public/assets/{ordinal-5RtyPJVt.js → ordinal-BRQ5CzZY.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-BDg8fde8.js +1 -0
- package/payload/server/public/assets/{page-BT9hkXHm.js → page-DzsVxvM6.js} +3 -3
- package/payload/server/public/assets/pie-ZZUOXDRM-CXDyYMkZ.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CV5DxUVx.js → pieDiagram-DEJITSTG-dUvQC_4S.js} +1 -1
- package/payload/server/public/assets/{public-DvL1Zov1.js → public-BzVhn2va.js} +1 -1
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BsFMVizF.js → quadrantDiagram-34T5L4WZ-CebX_oPa.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-xen_zv8F.js +1 -0
- package/payload/server/public/assets/{reduce-B3Mw_0s1.js → reduce-CkcXOmmJ.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-C5eRRvGc.js → requirementDiagram-MS252O5E-h2euIqGj.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-CJYv5gpw.js → sankeyDiagram-XADWPNL6-DCii3fkF.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-B25563_2.js → sequenceDiagram-FGHM5R23-CQSGYmlq.js} +1 -1
- package/payload/server/public/assets/{src-BKOAoFQc.js → src-48kCpScq.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-BLyNJYOA.js → stateDiagram-FHFEXIEX-CVtU0iXH.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BywcXjtb.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-D-HgOM6Q.js → timeline-definition-GMOUNBTQ-ChvsBltI.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-2FBf_1It.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-BDdb30P-.js +1 -0
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-Cw1JElYp.js → vennDiagram-DHZGUBPP-e-EZiiba.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-BLq5MxjR.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BqMWzEko.js → wardleyDiagram-NUSXRM2D-4JaRn1s5.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DBp71TLT.js → xychartDiagram-5P7HB3ND-kxwmCNuM.js} +1 -1
- package/payload/server/public/brand/maxy-app-icon-192.png +0 -0
- package/payload/server/public/brand/maxy-app-icon-512.png +0 -0
- package/payload/server/public/brand/maxy-app-icon-maskable-512.png +0 -0
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +17 -0
- package/payload/server/public/chat.html +8 -8
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +7 -7
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/operator.html +10 -10
- package/payload/server/public/public.html +8 -8
- package/payload/server/server.js +623 -190
- package/payload/server/public/assets/AdminShell-CHZMDX2u.js +0 -1
- package/payload/server/public/assets/OperatorConversations-DpjPPIOp.js +0 -9
- package/payload/server/public/assets/admin-DIDvfti6.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-DN-MYxff.js +0 -1
- package/payload/server/public/assets/channel-y27xl53N.js +0 -1
- package/payload/server/public/assets/chat-C0IWx7FL.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-D8Iwaegm.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-qHqDpwz3.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DgVoYWhO.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-C0WNP3uN.js +0 -1
- package/payload/server/public/assets/clone-D50F_pvg.js +0 -1
- package/payload/server/public/assets/data-RsMye_06.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-D-L2yzYf.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-BQn6jndO.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-BwMdbiXg.js +0 -2
- package/payload/server/public/assets/operator-9K-TElDd.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-DmkQBx4h.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-DDnxYUBm.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-7H4k0ChM.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BSVuxZxz.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-BLXWTQtW.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-DiePDF5d.js +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-OSUWK5LN.js +0 -1
- /package/payload/server/public/assets/{_baseFor-DVaNaTfF.js → _baseFor-SRtUHe7G.js} +0 -0
- /package/payload/server/public/assets/{admin-types-CJrGd46U.js → admin-types-Dg11L4MQ.js} +0 -0
- /package/payload/server/public/assets/{array-8_H1156C.js → array-BpsnM-Py.js} +0 -0
- /package/payload/server/public/assets/{chunk-Pqm5yXtL.js → chunk-CAM3fms7.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-h10p_6j-.js → cytoscape.esm-D4Rl1H5h.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-pD7tFa1r.js → defaultLocale-C7sQPl-O.js} +0 -0
- /package/payload/server/public/assets/{init-CwJ4b81e.js → init-BydxaDEV.js} +0 -0
- /package/payload/server/public/assets/{katex-DJPjIBAI.js → katex-B0fVeDx4.js} +0 -0
- /package/payload/server/public/assets/{path-CK8wrAxY.js → path-jlWYQ2i9.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-Bf_JiD2A.js → preload-helper-uTix4PVD.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-Dwml_la6.js → rough.esm-c4PR5shF.js} +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Booking reconcile core (Task 1012). The :Meeting MERGE is keyed on the
|
|
2
|
+
// booking uid (real MERGE idempotency is a live-Neo4j property); these tests
|
|
3
|
+
// pin the contract the JS owns: correct uid/source on the write, the
|
|
4
|
+
// global-email-uniqueness branch (same-account link / cross-account skip / new
|
|
5
|
+
// stub), and the audit arithmetic.
|
|
6
|
+
import { describe, it, expect, vi } from "vitest";
|
|
7
|
+
import { reconcileOne, auditCounts, bookingUid } from "../booking-reconcile.js";
|
|
8
|
+
const booking = {
|
|
9
|
+
bookingId: "abc",
|
|
10
|
+
slotStart: "2026-06-22T09:00:00Z",
|
|
11
|
+
slotEnd: "2026-06-22T09:30:00Z",
|
|
12
|
+
name: "Jo Visitor",
|
|
13
|
+
email: "jo@example.com",
|
|
14
|
+
note: "hello",
|
|
15
|
+
};
|
|
16
|
+
// Fake session that routes each run() by the cypher it sees. The booker link
|
|
17
|
+
// is a single MERGE (p:Person {email}) whose returned `linked` is true when the
|
|
18
|
+
// resolved Person belongs to this account (a new node, or an existing
|
|
19
|
+
// same-account one) and false for a foreign-account node.
|
|
20
|
+
function makeSession(opts) {
|
|
21
|
+
const cyphers = [];
|
|
22
|
+
const params = [];
|
|
23
|
+
const run = vi.fn(async (cypher, p) => {
|
|
24
|
+
cyphers.push(cypher);
|
|
25
|
+
params.push(p);
|
|
26
|
+
if (cypher.includes("MERGE (m:Meeting")) {
|
|
27
|
+
return { records: [{ get: (k) => (k === "created" ? opts.created : "el-meeting-1") }] };
|
|
28
|
+
}
|
|
29
|
+
if (cypher.includes("MERGE (p:Person")) {
|
|
30
|
+
// undefined owner = freshly created under this account.
|
|
31
|
+
const linked = opts.personOwner === undefined || opts.personOwner === p.accountId;
|
|
32
|
+
return { records: [{ get: () => linked }] };
|
|
33
|
+
}
|
|
34
|
+
return { records: [] };
|
|
35
|
+
});
|
|
36
|
+
return { session: { run }, run, cyphers, params };
|
|
37
|
+
}
|
|
38
|
+
describe("reconcileOne", () => {
|
|
39
|
+
it("writes the booking meeting with the right uid + source and links a new booker", async () => {
|
|
40
|
+
const { session, cyphers, params } = makeSession({ created: true, personOwner: undefined });
|
|
41
|
+
const r = await reconcileOne(session, "acct-1", booking);
|
|
42
|
+
expect(r.created).toBe(true);
|
|
43
|
+
expect(r.meetingId).toBe("el-meeting-1");
|
|
44
|
+
expect(r.personLinked).toBe(true);
|
|
45
|
+
expect(r.crossAccountSkipped).toBe(false);
|
|
46
|
+
// uid + source asserted on the meeting MERGE params/cypher.
|
|
47
|
+
expect(params[0].uid).toBe(bookingUid("abc"));
|
|
48
|
+
expect(cyphers[0]).toMatch(/m\.source = 'booking'/);
|
|
49
|
+
// booker link is one atomic MERGE on the unique email, not a check-then-create.
|
|
50
|
+
expect(cyphers.some((c) => c.includes("MERGE (p:Person {email: $email})"))).toBe(true);
|
|
51
|
+
expect(cyphers.some((c) => c.includes("CREATE (p:Person"))).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
it("reports created=false on the idempotent re-run", async () => {
|
|
54
|
+
const { session } = makeSession({ created: false, personOwner: "acct-1" });
|
|
55
|
+
const r = await reconcileOne(session, "acct-1", booking);
|
|
56
|
+
expect(r.created).toBe(false);
|
|
57
|
+
});
|
|
58
|
+
it("links a same-account existing person via ATTENDED", async () => {
|
|
59
|
+
const { session, cyphers } = makeSession({ created: true, personOwner: "acct-1" });
|
|
60
|
+
const r = await reconcileOne(session, "acct-1", booking);
|
|
61
|
+
expect(r.personLinked).toBe(true);
|
|
62
|
+
expect(r.crossAccountSkipped).toBe(false);
|
|
63
|
+
expect(cyphers.some((c) => c.includes("MERGE (p)-[r:ATTENDED]->(m)"))).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
it("skips a cross-account person but still lands the meeting", async () => {
|
|
66
|
+
const { session } = makeSession({ created: true, personOwner: "other-account" });
|
|
67
|
+
const r = await reconcileOne(session, "acct-1", booking);
|
|
68
|
+
expect(r.created).toBe(true);
|
|
69
|
+
expect(r.personLinked).toBe(false);
|
|
70
|
+
expect(r.crossAccountSkipped).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe("auditCounts", () => {
|
|
74
|
+
it("counts pending (D1 ahead) and orphans (graph ahead)", async () => {
|
|
75
|
+
const run = vi.fn(async () => ({
|
|
76
|
+
records: [{ get: () => ["booking-a", "booking-b"] }],
|
|
77
|
+
}));
|
|
78
|
+
const counts = await auditCounts({ run }, "acct-1", ["a", "c"]);
|
|
79
|
+
// 'c' accepted in D1 but no meeting -> pending 1; 'booking-b' meeting with no D1 row -> orphan 1.
|
|
80
|
+
expect(counts.pendingUnreconciled).toBe(1);
|
|
81
|
+
expect(counts.orphanMeetings).toBe(1);
|
|
82
|
+
});
|
|
83
|
+
it("is clean when D1 and graph agree", async () => {
|
|
84
|
+
const run = vi.fn(async () => ({ records: [{ get: () => ["booking-a", "booking-b"] }] }));
|
|
85
|
+
const counts = await auditCounts({ run }, "acct-1", ["a", "b"]);
|
|
86
|
+
expect(counts).toEqual({ pendingUnreconciled: 0, orphanMeetings: 0 });
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=booking-reconcile.test.js.map
|
package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"booking-reconcile.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/booking-reconcile.test.ts"],"names":[],"mappings":"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"}
|
package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-write.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meeting-write.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/meeting-write.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// Task 1023. Real MERGE idempotency is a live-Neo4j property; these tests pin
|
|
2
|
+
// the contract the JS owns: a deterministic (accountId, uid) content-hash key,
|
|
3
|
+
// the :Meeting MERGE shape, the PART_OF provenance link, and the attendee branch
|
|
4
|
+
// (same-account email link / cross-account skip / resolved nodeId / name-only).
|
|
5
|
+
import { describe, it, expect, vi } from "vitest";
|
|
6
|
+
import { writeMeeting, meetingUid } from "../meeting-write.js";
|
|
7
|
+
const base = {
|
|
8
|
+
accountId: "acct-1",
|
|
9
|
+
name: "Discovery call",
|
|
10
|
+
startDate: "2026-06-22T14:00:00Z",
|
|
11
|
+
endDate: "2026-06-22T14:30:00Z",
|
|
12
|
+
createdBy: { agent: "personal-assistant", session: "sess-1", tool: "schedule-event" },
|
|
13
|
+
};
|
|
14
|
+
// Fake session that routes each run() by the cypher it sees, capturing cyphers +
|
|
15
|
+
// params. `created` controls the meeting MERGE; `personOwner` controls the
|
|
16
|
+
// same-account/foreign branch for an email attendee; `nodeIdLinks` controls
|
|
17
|
+
// whether a nodeId attendee resolved under this account.
|
|
18
|
+
function makeSession(opts) {
|
|
19
|
+
const cyphers = [];
|
|
20
|
+
const params = [];
|
|
21
|
+
const run = vi.fn(async (cypher, p) => {
|
|
22
|
+
cyphers.push(cypher);
|
|
23
|
+
params.push(p);
|
|
24
|
+
if (cypher.includes("MERGE (m:Meeting")) {
|
|
25
|
+
return { records: [{ get: (k) => (k === "created" ? opts.created ?? true : "el-meeting-1") }] };
|
|
26
|
+
}
|
|
27
|
+
if (cypher.includes("MERGE (p:Person {email:")) {
|
|
28
|
+
const linked = opts.personOwner === undefined || opts.personOwner === p.accountId;
|
|
29
|
+
return { records: [{ get: () => linked }] };
|
|
30
|
+
}
|
|
31
|
+
if (cypher.includes("MATCH (p:Person) WHERE elementId(p)")) {
|
|
32
|
+
// The real query's same-account MATCH yields a row only when the Person
|
|
33
|
+
// resolves under this account; a foreign/missing nodeId returns zero rows.
|
|
34
|
+
return { records: opts.nodeIdLinks ? [{ get: () => true }] : [] };
|
|
35
|
+
}
|
|
36
|
+
return { records: [] };
|
|
37
|
+
});
|
|
38
|
+
return { session: { run }, run, cyphers, params };
|
|
39
|
+
}
|
|
40
|
+
describe("meetingUid", () => {
|
|
41
|
+
it("is deterministic and normalizes title casing/whitespace", () => {
|
|
42
|
+
const a = meetingUid("acct-1", "Discovery Call", "2026-06-22T14:00:00Z");
|
|
43
|
+
const b = meetingUid("acct-1", " discovery call ", "2026-06-22T14:00:00Z");
|
|
44
|
+
expect(a).toBe(b);
|
|
45
|
+
expect(a).toMatch(/^sched-[0-9a-f]{32}$/);
|
|
46
|
+
});
|
|
47
|
+
it("differs by account, title, and start", () => {
|
|
48
|
+
const u = meetingUid("acct-1", "Discovery call", "2026-06-22T14:00:00Z");
|
|
49
|
+
expect(u).not.toBe(meetingUid("acct-2", "Discovery call", "2026-06-22T14:00:00Z"));
|
|
50
|
+
expect(u).not.toBe(meetingUid("acct-1", "Other", "2026-06-22T14:00:00Z"));
|
|
51
|
+
expect(u).not.toBe(meetingUid("acct-1", "Discovery call", "2026-06-22T15:00:00Z"));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe("writeMeeting", () => {
|
|
55
|
+
it("MERGEs the meeting on (accountId, uid) with the schedule-event source", async () => {
|
|
56
|
+
const { session, cyphers, params } = makeSession({ created: true });
|
|
57
|
+
const r = await writeMeeting(session, base);
|
|
58
|
+
expect(r.created).toBe(true);
|
|
59
|
+
expect(r.meetingId).toBe("el-meeting-1");
|
|
60
|
+
expect(r.uid).toBe(meetingUid(base.accountId, base.name, base.startDate));
|
|
61
|
+
expect(params[0].uid).toBe(r.uid);
|
|
62
|
+
expect(params[0].accountId).toBe("acct-1");
|
|
63
|
+
expect(cyphers[0]).toMatch(/MERGE \(m:Meeting \{accountId: \$accountId, uid: \$uid\}\)/);
|
|
64
|
+
expect(cyphers[0]).toMatch(/m\.source = 'schedule-event'/);
|
|
65
|
+
});
|
|
66
|
+
it("links PART_OF to the session Conversation when a sessionKey is given", async () => {
|
|
67
|
+
const { session, cyphers } = makeSession({ created: true });
|
|
68
|
+
await writeMeeting(session, { ...base, sessionKey: "sess-1" });
|
|
69
|
+
expect(cyphers.some((c) => c.includes("MERGE (m)-[r:PART_OF]->(c)"))).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
it("writes no PART_OF when there is no sessionKey", async () => {
|
|
72
|
+
const { session, cyphers } = makeSession({ created: true });
|
|
73
|
+
await writeMeeting(session, base);
|
|
74
|
+
expect(cyphers.some((c) => c.includes("PART_OF"))).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
it("links a same-account email counterparty via ATTENDED", async () => {
|
|
77
|
+
const { session, cyphers, params } = makeSession({ created: true, personOwner: "acct-1" });
|
|
78
|
+
const r = await writeMeeting(session, { ...base, attendees: [{ email: "Josh@Goff.com", name: "Josh" }] });
|
|
79
|
+
expect(r.attendeesLinked).toBe(1);
|
|
80
|
+
expect(r.crossAccountSkipped).toBe(0);
|
|
81
|
+
expect(cyphers.some((c) => c.includes("MERGE (p)-[r:ATTENDED]->(m)"))).toBe(true);
|
|
82
|
+
// email is lowercased before the MERGE.
|
|
83
|
+
const personCall = params.find((p) => p.email !== undefined);
|
|
84
|
+
expect(personCall?.email).toBe("josh@goff.com");
|
|
85
|
+
});
|
|
86
|
+
it("skips a cross-account email counterparty but still lands the meeting", async () => {
|
|
87
|
+
const { session } = makeSession({ created: true, personOwner: "other-account" });
|
|
88
|
+
const r = await writeMeeting(session, { ...base, attendees: [{ email: "foreign@x.com" }] });
|
|
89
|
+
expect(r.created).toBe(true);
|
|
90
|
+
expect(r.attendeesLinked).toBe(0);
|
|
91
|
+
expect(r.crossAccountSkipped).toBe(1);
|
|
92
|
+
});
|
|
93
|
+
it("links a resolved same-account nodeId counterparty", async () => {
|
|
94
|
+
const { session } = makeSession({ created: true, nodeIdLinks: true });
|
|
95
|
+
const r = await writeMeeting(session, { ...base, attendees: [{ nodeId: "el-person-9" }] });
|
|
96
|
+
expect(r.attendeesLinked).toBe(1);
|
|
97
|
+
expect(r.crossAccountSkipped).toBe(0);
|
|
98
|
+
});
|
|
99
|
+
it("skips a nodeId that does not resolve under this account", async () => {
|
|
100
|
+
const { session } = makeSession({ created: true, nodeIdLinks: false });
|
|
101
|
+
const r = await writeMeeting(session, { ...base, attendees: [{ nodeId: "el-foreign" }] });
|
|
102
|
+
expect(r.attendeesLinked).toBe(0);
|
|
103
|
+
expect(r.crossAccountSkipped).toBe(1);
|
|
104
|
+
});
|
|
105
|
+
it("writes no attendee link for a name-only counterparty", async () => {
|
|
106
|
+
const { session, cyphers } = makeSession({ created: true });
|
|
107
|
+
const r = await writeMeeting(session, { ...base, attendees: [{ name: "No Email" }] });
|
|
108
|
+
expect(r.attendeesLinked).toBe(0);
|
|
109
|
+
expect(r.crossAccountSkipped).toBe(0);
|
|
110
|
+
expect(cyphers.some((c) => c.includes("ATTENDED"))).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
it("reports created=false on the idempotent re-run", async () => {
|
|
113
|
+
const { session } = makeSession({ created: false });
|
|
114
|
+
const r = await writeMeeting(session, base);
|
|
115
|
+
expect(r.created).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=meeting-write.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meeting-write.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/meeting-write.test.ts"],"names":[],"mappings":"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"}
|
package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-classify.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-classify.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/schedule-classify.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Task 1023. The discriminator is the load-bearing decision: it picks :Meeting
|
|
2
|
+
// vs :Event from the schedule-event params. These pins lock each branch and the
|
|
3
|
+
// top-down precedence (a trigger always wins, a name-only attendee never does).
|
|
4
|
+
import { describe, it, expect } from "vitest";
|
|
5
|
+
import { classifyScheduleWrite } from "../schedule-classify.js";
|
|
6
|
+
describe("classifyScheduleWrite", () => {
|
|
7
|
+
it("recurrence makes it an Event (recurring trigger), even with an attendee + endDate", () => {
|
|
8
|
+
expect(classifyScheduleWrite({
|
|
9
|
+
recurrence: "0 8 * * 1-5",
|
|
10
|
+
endDate: "2026-06-22T09:00:00Z",
|
|
11
|
+
attendees: [{ email: "a@b.com" }],
|
|
12
|
+
})).toEqual({ label: "Event", reason: "recurrence" });
|
|
13
|
+
});
|
|
14
|
+
it("an action makes it an Event (dispatcher), even with an attendee", () => {
|
|
15
|
+
expect(classifyScheduleWrite({
|
|
16
|
+
action: { plugin: "memory", tool: "memory-search" },
|
|
17
|
+
attendees: [{ email: "a@b.com" }],
|
|
18
|
+
})).toEqual({ label: "Event", reason: "action" });
|
|
19
|
+
});
|
|
20
|
+
it("a counterparty with an email makes it a Meeting", () => {
|
|
21
|
+
expect(classifyScheduleWrite({ attendees: [{ email: "josh@goff.com", name: "Josh" }] })).toEqual({
|
|
22
|
+
label: "Meeting",
|
|
23
|
+
reason: "counterparty",
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
it("a counterparty with a resolved nodeId makes it a Meeting", () => {
|
|
27
|
+
expect(classifyScheduleWrite({ attendees: [{ nodeId: "el-person-1" }] })).toEqual({
|
|
28
|
+
label: "Meeting",
|
|
29
|
+
reason: "counterparty",
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
it("a bounded slot (endDate) with no counterparty is a Meeting", () => {
|
|
33
|
+
expect(classifyScheduleWrite({ endDate: "2026-06-22T10:00:00Z" })).toEqual({
|
|
34
|
+
label: "Meeting",
|
|
35
|
+
reason: "bounded",
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
it("a one-time reminder (no end, no counterparty) stays an Event", () => {
|
|
39
|
+
expect(classifyScheduleWrite({})).toEqual({ label: "Event", reason: "reminder" });
|
|
40
|
+
});
|
|
41
|
+
it("a name-only attendee does not, by itself, make it a Meeting", () => {
|
|
42
|
+
// No email and no nodeId — not resolvable to a :Person, so it falls through
|
|
43
|
+
// to the reminder branch rather than the counterparty branch.
|
|
44
|
+
expect(classifyScheduleWrite({ attendees: [{ name: "Some Person" }] })).toEqual({
|
|
45
|
+
label: "Event",
|
|
46
|
+
reason: "reminder",
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it("a name-only attendee on a bounded slot is a Meeting via the bounded branch", () => {
|
|
50
|
+
expect(classifyScheduleWrite({ endDate: "2026-06-22T10:00:00Z", attendees: [{ name: "Some Person" }] })).toEqual({ label: "Meeting", reason: "bounded" });
|
|
51
|
+
});
|
|
52
|
+
it("treats whitespace-only attendee keys as absent", () => {
|
|
53
|
+
expect(classifyScheduleWrite({ attendees: [{ email: " ", nodeId: " " }] })).toEqual({
|
|
54
|
+
label: "Event",
|
|
55
|
+
reason: "reminder",
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=schedule-classify.test.js.map
|
package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/schedule-classify.test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-classify.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/schedule-classify.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BookingRow } from "./booking-reconcile.js";
|
|
2
|
+
export interface NotifyDeps {
|
|
3
|
+
/** Admin destination address; email is skipped when absent. */
|
|
4
|
+
adminEmail?: string;
|
|
5
|
+
sendEmail?: (msg: {
|
|
6
|
+
to: string;
|
|
7
|
+
subject: string;
|
|
8
|
+
body: string;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
/** Admin WhatsApp thread; set ONLY when a thread already exists (reply-only). */
|
|
11
|
+
adminWhatsapp?: string;
|
|
12
|
+
sendWhatsapp?: (msg: {
|
|
13
|
+
to: string;
|
|
14
|
+
text: string;
|
|
15
|
+
}) => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export interface NotifyResult {
|
|
18
|
+
channel: "email" | "whatsapp";
|
|
19
|
+
dispatched: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function notifyBooking(deps: NotifyDeps, booking: BookingRow): Promise<NotifyResult[]>;
|
|
22
|
+
//# sourceMappingURL=booking-notify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"booking-notify.d.ts","sourceRoot":"","sources":["../../src/lib/booking-notify.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;CACrB;AAOD,wBAAsB,aAAa,CACjC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CA0BzB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function summary(booking) {
|
|
2
|
+
return `${booking.name} (${booking.email}) booked ${booking.slotStart}.` +
|
|
3
|
+
(booking.note ? ` Note: ${booking.note}` : "");
|
|
4
|
+
}
|
|
5
|
+
export async function notifyBooking(deps, booking) {
|
|
6
|
+
const results = [];
|
|
7
|
+
if (deps.adminEmail && deps.sendEmail) {
|
|
8
|
+
try {
|
|
9
|
+
await deps.sendEmail({
|
|
10
|
+
to: deps.adminEmail,
|
|
11
|
+
subject: `New booking: ${booking.name}`,
|
|
12
|
+
body: summary(booking),
|
|
13
|
+
});
|
|
14
|
+
results.push({ channel: "email", dispatched: true });
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
results.push({ channel: "email", dispatched: false });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (deps.adminWhatsapp && deps.sendWhatsapp) {
|
|
21
|
+
try {
|
|
22
|
+
await deps.sendWhatsapp({ to: deps.adminWhatsapp, text: summary(booking) });
|
|
23
|
+
results.push({ channel: "whatsapp", dispatched: true });
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
results.push({ channel: "whatsapp", dispatched: false });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return results;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=booking-notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"booking-notify.js","sourceRoot":"","sources":["../../src/lib/booking-notify.ts"],"names":[],"mappings":"AAwBA,SAAS,OAAO,CAAC,OAAmB;IAClC,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,KAAK,YAAY,OAAO,CAAC,SAAS,GAAG;QACtE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAgB,EAChB,OAAmB;IAEnB,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC;gBACnB,EAAE,EAAE,IAAI,CAAC,UAAU;gBACnB,OAAO,EAAE,gBAAgB,OAAO,CAAC,IAAI,EAAE;gBACvC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC;aACvB,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Session } from "neo4j-driver";
|
|
2
|
+
export interface BookingRow {
|
|
3
|
+
bookingId: string;
|
|
4
|
+
slotStart: string;
|
|
5
|
+
slotEnd: string;
|
|
6
|
+
name: string;
|
|
7
|
+
email: string;
|
|
8
|
+
note?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ReconcileResult {
|
|
11
|
+
created: boolean;
|
|
12
|
+
meetingId: string;
|
|
13
|
+
personLinked: boolean;
|
|
14
|
+
crossAccountSkipped: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function bookingUid(bookingId: string): string;
|
|
17
|
+
export declare function reconcileOne(session: Session, accountId: string, booking: BookingRow): Promise<ReconcileResult>;
|
|
18
|
+
export interface AuditCounts {
|
|
19
|
+
pendingUnreconciled: number;
|
|
20
|
+
orphanMeetings: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Compare D1's accepted booking ids against the account's booking :Meeting set.
|
|
24
|
+
* pendingUnreconciled — accepted in D1 but no :Meeting yet (reconcile lagging).
|
|
25
|
+
* orphanMeetings — a booking :Meeting with no backing D1 row.
|
|
26
|
+
*/
|
|
27
|
+
export declare function auditCounts(session: Session, accountId: string, d1AcceptedIds: string[]): Promise<AuditCounts>;
|
|
28
|
+
//# sourceMappingURL=booking-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"booking-reconcile.d.ts","sourceRoot":"","sources":["../../src/lib/booking-reconcile.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,eAAe,CAAC,CA4D1B;AAED,MAAM,WAAW,WAAW;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,WAAW,CAAC,CAWtB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export function bookingUid(bookingId) {
|
|
2
|
+
return `booking-${bookingId}`;
|
|
3
|
+
}
|
|
4
|
+
export async function reconcileOne(session, accountId, booking) {
|
|
5
|
+
const uid = bookingUid(booking.bookingId);
|
|
6
|
+
const meetingRes = await session.run(`MERGE (m:Meeting {accountId: $accountId, uid: $uid})
|
|
7
|
+
ON CREATE SET m.title = $title,
|
|
8
|
+
m.startsAt = datetime($slotStart),
|
|
9
|
+
m.endsAt = datetime($slotEnd),
|
|
10
|
+
m.scope = 'booking',
|
|
11
|
+
m.source = 'booking',
|
|
12
|
+
m.bookerEmail = $email,
|
|
13
|
+
m.note = $note,
|
|
14
|
+
m.isAllDay = false,
|
|
15
|
+
m.createdAt = datetime(),
|
|
16
|
+
m.updatedAt = datetime(),
|
|
17
|
+
m.createdByAgent = 'booking-reconcile',
|
|
18
|
+
m.createdBySource = 'booking-reconcile',
|
|
19
|
+
m._created = true
|
|
20
|
+
ON MATCH SET m.updatedAt = datetime(),
|
|
21
|
+
m._created = false
|
|
22
|
+
WITH m, m._created AS created
|
|
23
|
+
REMOVE m._created
|
|
24
|
+
RETURN created, elementId(m) AS meetingId`, {
|
|
25
|
+
accountId,
|
|
26
|
+
uid,
|
|
27
|
+
title: `Booking: ${booking.name}`,
|
|
28
|
+
slotStart: booking.slotStart,
|
|
29
|
+
slotEnd: booking.slotEnd,
|
|
30
|
+
email: booking.email,
|
|
31
|
+
note: booking.note ?? "",
|
|
32
|
+
});
|
|
33
|
+
const created = meetingRes.records[0].get("created");
|
|
34
|
+
const meetingId = meetingRes.records[0].get("meetingId");
|
|
35
|
+
// Resolve the booker in one atomic statement that respects the global
|
|
36
|
+
// Person.email uniqueness constraint. MERGE on email matches any existing
|
|
37
|
+
// Person (without relabeling it — ON CREATE fires only on a fresh node) or
|
|
38
|
+
// creates one under this account. The ATTENDED link is written only when the
|
|
39
|
+
// resolved Person belongs to this account, so a foreign-account person is
|
|
40
|
+
// neither linked nor modified, and there is no check-then-create race that
|
|
41
|
+
// could throw the unique constraint and wedge the row.
|
|
42
|
+
const personRes = await session.run(`MATCH (m:Meeting) WHERE elementId(m) = $meetingId
|
|
43
|
+
MERGE (p:Person {email: $email})
|
|
44
|
+
ON CREATE SET p.accountId = $accountId,
|
|
45
|
+
p.displayName = $name,
|
|
46
|
+
p.scope = 'booking',
|
|
47
|
+
p.source = 'booking-reconcile',
|
|
48
|
+
p.createdAt = datetime()
|
|
49
|
+
FOREACH (_ IN CASE WHEN p.accountId = $accountId THEN [1] ELSE [] END |
|
|
50
|
+
MERGE (p)-[r:ATTENDED]->(m)
|
|
51
|
+
ON CREATE SET r.role = 'booker', r.createdAt = datetime(), r.createdBySource = 'booking-reconcile')
|
|
52
|
+
RETURN p.accountId = $accountId AS linked`, { meetingId, email: booking.email, accountId, name: booking.name });
|
|
53
|
+
const linked = personRes.records[0]?.get("linked") === true;
|
|
54
|
+
return { created, meetingId, personLinked: linked, crossAccountSkipped: !linked };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Compare D1's accepted booking ids against the account's booking :Meeting set.
|
|
58
|
+
* pendingUnreconciled — accepted in D1 but no :Meeting yet (reconcile lagging).
|
|
59
|
+
* orphanMeetings — a booking :Meeting with no backing D1 row.
|
|
60
|
+
*/
|
|
61
|
+
export async function auditCounts(session, accountId, d1AcceptedIds) {
|
|
62
|
+
const res = await session.run(`MATCH (m:Meeting {accountId: $accountId, source: 'booking'}) RETURN collect(m.uid) AS uids`, { accountId });
|
|
63
|
+
const uids = res.records[0]?.get("uids") ?? [];
|
|
64
|
+
const uidSet = new Set(uids);
|
|
65
|
+
const idSet = new Set(d1AcceptedIds);
|
|
66
|
+
const pendingUnreconciled = d1AcceptedIds.filter((id) => !uidSet.has(bookingUid(id))).length;
|
|
67
|
+
const orphanMeetings = uids.filter((uid) => !idSet.has(uid.replace(/^booking-/, ""))).length;
|
|
68
|
+
return { pendingUnreconciled, orphanMeetings };
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=booking-reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"booking-reconcile.js","sourceRoot":"","sources":["../../src/lib/booking-reconcile.ts"],"names":[],"mappings":"AA2BA,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,WAAW,SAAS,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAgB,EAChB,SAAiB,EACjB,OAAmB;IAEnB,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAE1C,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC;;;;;;;;;;;;;;;;;;+CAkB2C,EAC3C;QACE,SAAS;QACT,GAAG;QACH,KAAK,EAAE,YAAY,OAAO,CAAC,IAAI,EAAE;QACjC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;KACzB,CACF,CAAC;IACF,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAY,CAAC;IAChE,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAW,CAAC;IAEnE,sEAAsE;IACtE,0EAA0E;IAC1E,2EAA2E;IAC3E,6EAA6E;IAC7E,0EAA0E;IAC1E,2EAA2E;IAC3E,uDAAuD;IACvD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC;;;;;;;;;;+CAU2C,EAC3C,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CACnE,CAAC;IACF,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAE5D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,CAAC;AACpF,CAAC;AAOD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAgB,EAChB,SAAiB,EACjB,aAAuB;IAEvB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAC3B,4FAA4F,EAC5F,EAAE,SAAS,EAAE,CACd,CAAC;IACF,MAAM,IAAI,GAAa,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACzD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IACrC,MAAM,mBAAmB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7F,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7F,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Session } from "neo4j-driver";
|
|
2
|
+
import type { ScheduleAttendee } from "./schedule-classify.js";
|
|
3
|
+
export interface WriteMeetingParams {
|
|
4
|
+
accountId: string;
|
|
5
|
+
name: string;
|
|
6
|
+
startDate: string;
|
|
7
|
+
endDate?: string;
|
|
8
|
+
location?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
timezone?: string;
|
|
11
|
+
attendees?: ScheduleAttendee[];
|
|
12
|
+
sessionKey?: string;
|
|
13
|
+
createdBy: {
|
|
14
|
+
agent: string;
|
|
15
|
+
session: string;
|
|
16
|
+
tool: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface WriteMeetingResult {
|
|
20
|
+
meetingId: string;
|
|
21
|
+
uid: string;
|
|
22
|
+
created: boolean;
|
|
23
|
+
attendeesLinked: number;
|
|
24
|
+
crossAccountSkipped: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Deterministic uid for a conversationally-booked meeting. ICS uses the VEVENT
|
|
28
|
+
* UID and booking uses 'booking-<id>'; a conversational meeting has no external
|
|
29
|
+
* id, so the natural key is a content hash of the account, the normalized title,
|
|
30
|
+
* and the start. Re-running the identical request yields the same uid and the
|
|
31
|
+
* MERGE matches the existing node.
|
|
32
|
+
*/
|
|
33
|
+
export declare function meetingUid(accountId: string, name: string, startDate: string): string;
|
|
34
|
+
export declare function writeMeeting(session: Session, params: WriteMeetingParams): Promise<WriteMeetingResult>;
|
|
35
|
+
//# sourceMappingURL=meeting-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meeting-write.d.ts","sourceRoot":"","sources":["../../src/lib/meeting-write.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGrF;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAgH7B"}
|