@things-factory/ai-assistant 10.1.207 → 10.1.210
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/client/components/assistant-chat.ts +238 -9
- package/client/components/assistant-dock.ts +9 -4
- package/client/components/assistant-invite.ts +138 -0
- package/client/components/assistant-session-manager.ts +53 -12
- package/client/components/proposal-request.test.ts +10 -0
- package/client/components/roster-identity.test.ts +2 -12
- package/client/components/roster-identity.ts +0 -6
- package/client/setup-assistant-dock.ts +1 -0
- package/client/utils/assistant-session-actions.ts +3 -1
- package/client/utils/assistant-session-admin.ts +9 -2
- package/client/utils/assistant-session-controller.ts +1 -1
- package/client/utils/assistant-typing.test.ts +33 -0
- package/client/utils/assistant-typing.ts +53 -0
- package/dist-client/components/assistant-chat.d.ts +28 -0
- package/dist-client/components/assistant-chat.js +259 -8
- package/dist-client/components/assistant-chat.js.map +1 -1
- package/dist-client/components/assistant-dock.js +12 -4
- package/dist-client/components/assistant-dock.js.map +1 -1
- package/dist-client/components/assistant-invite.d.ts +39 -0
- package/dist-client/components/assistant-invite.js +150 -0
- package/dist-client/components/assistant-invite.js.map +1 -0
- package/dist-client/components/assistant-session-manager.d.ts +5 -1
- package/dist-client/components/assistant-session-manager.js +40 -10
- package/dist-client/components/assistant-session-manager.js.map +1 -1
- package/dist-client/components/proposal-request.test.js +8 -0
- package/dist-client/components/proposal-request.test.js.map +1 -1
- package/dist-client/components/roster-identity.d.ts +0 -2
- package/dist-client/components/roster-identity.js +0 -7
- package/dist-client/components/roster-identity.js.map +1 -1
- package/dist-client/components/roster-identity.test.js +2 -13
- package/dist-client/components/roster-identity.test.js.map +1 -1
- package/dist-client/setup-assistant-dock.js +1 -0
- package/dist-client/setup-assistant-dock.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/assistant-session-actions.d.ts +1 -0
- package/dist-client/utils/assistant-session-actions.js +3 -1
- package/dist-client/utils/assistant-session-actions.js.map +1 -1
- package/dist-client/utils/assistant-session-admin.d.ts +5 -2
- package/dist-client/utils/assistant-session-admin.js +3 -0
- package/dist-client/utils/assistant-session-admin.js.map +1 -1
- package/dist-client/utils/assistant-session-controller.d.ts +1 -1
- package/dist-client/utils/assistant-session-controller.js.map +1 -1
- package/dist-client/utils/assistant-typing.d.ts +20 -0
- package/dist-client/utils/assistant-typing.js +48 -0
- package/dist-client/utils/assistant-typing.js.map +1 -0
- package/dist-client/utils/assistant-typing.test.d.ts +1 -0
- package/dist-client/utils/assistant-typing.test.js +30 -0
- package/dist-client/utils/assistant-typing.test.js.map +1 -0
- package/dist-server/service/assistant-chat-resolver.js +5 -12
- package/dist-server/service/assistant-chat-resolver.js.map +1 -1
- package/dist-server/service/assistant-mode/index.d.ts +1 -1
- package/dist-server/service/assistant-mode/index.js +4 -1
- package/dist-server/service/assistant-mode/index.js.map +1 -1
- package/dist-server/service/assistant-mode/mode-categories.js +9 -2
- package/dist-server/service/assistant-mode/mode-categories.js.map +1 -1
- package/dist-server/service/assistant-mode/screen-rules.d.ts +19 -0
- package/dist-server/service/assistant-mode/screen-rules.js +40 -6
- package/dist-server/service/assistant-mode/screen-rules.js.map +1 -1
- package/dist-server/service/chat-message/chat-message-room.js +3 -1
- package/dist-server/service/chat-message/chat-message-room.js.map +1 -1
- package/dist-server/service/chat-message/chat-typing-subscription.d.ts +10 -0
- package/dist-server/service/chat-message/chat-typing-subscription.js +68 -0
- package/dist-server/service/chat-message/chat-typing-subscription.js.map +1 -0
- package/dist-server/service/chat-message/chat-typing.d.ts +28 -0
- package/dist-server/service/chat-message/chat-typing.js +40 -0
- package/dist-server/service/chat-message/chat-typing.js.map +1 -0
- package/dist-server/service/chat-session/attachment-tool-result.d.ts +1 -0
- package/dist-server/service/chat-session/attachment-tool-result.js +6 -0
- package/dist-server/service/chat-session/attachment-tool-result.js.map +1 -1
- package/dist-server/service/chat-session/attachment-tools.js +2 -2
- package/dist-server/service/chat-session/attachment-tools.js.map +1 -1
- package/dist-server/service/chat-session/chat-session.d.ts +2 -1
- package/dist-server/service/chat-session/chat-session.js +1 -1
- package/dist-server/service/chat-session/chat-session.js.map +1 -1
- package/dist-server/service/chat-session/session-activity-broadcast.d.ts +12 -0
- package/dist-server/service/chat-session/session-activity-broadcast.js +15 -0
- package/dist-server/service/chat-session/session-activity-broadcast.js.map +1 -1
- package/dist-server/service/chat-session/session-activity-publish.d.ts +2 -0
- package/dist-server/service/chat-session/session-activity-publish.js +5 -2
- package/dist-server/service/chat-session/session-activity-publish.js.map +1 -1
- package/dist-server/service/chat-session/session-visibility.d.ts +17 -2
- package/dist-server/service/chat-session/session-visibility.js +28 -3
- package/dist-server/service/chat-session/session-visibility.js.map +1 -1
- package/dist-server/service/chat-session/session-write-gate.d.ts +1 -1
- package/dist-server/service/chat-session/session-write-gate.js +1 -1
- package/dist-server/service/chat-session/session-write-gate.js.map +1 -1
- package/dist-server/service/chat-session-participant/index.d.ts +1 -0
- package/dist-server/service/chat-session-participant/index.js +4 -1
- package/dist-server/service/chat-session-participant/index.js.map +1 -1
- package/dist-server/service/chat-session-participant/invite-notification.d.ts +16 -1
- package/dist-server/service/chat-session-participant/invite-notification.js +34 -5
- package/dist-server/service/chat-session-participant/invite-notification.js.map +1 -1
- package/dist-server/service/chat-session-participant/mention-invite.d.ts +30 -4
- package/dist-server/service/chat-session-participant/mention-invite.js +78 -31
- package/dist-server/service/chat-session-participant/mention-invite.js.map +1 -1
- package/dist-server/service/chat-session-participant/read-roster.js +5 -2
- package/dist-server/service/chat-session-participant/read-roster.js.map +1 -1
- package/dist-server/service/chat-session-resolver.d.ts +27 -0
- package/dist-server/service/chat-session-resolver.js +226 -25
- package/dist-server/service/chat-session-resolver.js.map +1 -1
- package/dist-server/service/data-entry/entry-target.d.ts +19 -0
- package/dist-server/service/data-entry/entry-target.js +20 -5
- package/dist-server/service/data-entry/entry-target.js.map +1 -1
- package/dist-server/service/data-entry/entry-tools.js +2 -2
- package/dist-server/service/data-entry/entry-tools.js.map +1 -1
- package/dist-server/service/data-entry/entry-update.d.ts +2 -1
- package/dist-server/service/data-entry/entry-update.js +5 -3
- package/dist-server/service/data-entry/entry-update.js.map +1 -1
- package/dist-server/service/data-read/list-read.d.ts +10 -0
- package/dist-server/service/data-read/list-read.js +12 -0
- package/dist-server/service/data-read/list-read.js.map +1 -1
- package/dist-server/service/data-read/read-target.d.ts +7 -0
- package/dist-server/service/data-read/read-target.js +2 -2
- package/dist-server/service/data-read/read-target.js.map +1 -1
- package/dist-server/service/data-read/read-tools.js +1 -1
- package/dist-server/service/data-read/read-tools.js.map +1 -1
- package/dist-server/service/index.d.ts +4 -2
- package/dist-server/service/index.js +9 -1
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/testing/conversation-script.d.ts +1 -1
- package/dist-server/service/testing/conversation-script.js.map +1 -1
- package/dist-server/service/testing/mode-conformance.js +4 -0
- package/dist-server/service/testing/mode-conformance.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/server/explicit-graphql-types.test.ts +1 -1
- package/server/service/assistant-chat-resolver.ts +7 -12
- package/server/service/assistant-mode/index.ts +1 -1
- package/server/service/assistant-mode/mode-categories.ts +11 -3
- package/server/service/assistant-mode/mode-front.test.ts +53 -1
- package/server/service/assistant-mode/resolve.test.ts +2 -1
- package/server/service/assistant-mode/screen-rules.test.ts +41 -3
- package/server/service/assistant-mode/screen-rules.ts +44 -5
- package/server/service/chat-message/chat-message-room.test.ts +7 -2
- package/server/service/chat-message/chat-message-room.ts +3 -1
- package/server/service/chat-message/chat-typing-subscription.ts +52 -0
- package/server/service/chat-message/chat-typing.test.ts +45 -0
- package/server/service/chat-message/chat-typing.ts +48 -0
- package/server/service/chat-message/fold-history-window.test.ts +1 -1
- package/server/service/chat-session/attachment-tool-result.test.ts +9 -1
- package/server/service/chat-session/attachment-tool-result.ts +7 -0
- package/server/service/chat-session/attachment-tools.ts +3 -3
- package/server/service/chat-session/chat-session.ts +3 -2
- package/server/service/chat-session/group-room.test.ts +233 -0
- package/server/service/chat-session/session-activity-broadcast.ts +20 -0
- package/server/service/chat-session/session-activity-publish.ts +6 -1
- package/server/service/chat-session/session-activity-receivers.test.ts +26 -0
- package/server/service/chat-session/session-visibility.test.ts +32 -1
- package/server/service/chat-session/session-visibility.ts +33 -4
- package/server/service/chat-session/session-write-gate.test.ts +7 -1
- package/server/service/chat-session/session-write-gate.ts +2 -2
- package/server/service/chat-session-participant/index.ts +2 -0
- package/server/service/chat-session-participant/invite-notification.test.ts +36 -1
- package/server/service/chat-session-participant/invite-notification.ts +43 -5
- package/server/service/chat-session-participant/mention-invite.test.ts +49 -1
- package/server/service/chat-session-participant/mention-invite.ts +82 -28
- package/server/service/chat-session-participant/read-roster.test.ts +13 -4
- package/server/service/chat-session-participant/read-roster.ts +6 -3
- package/server/service/chat-session-resolver.ts +204 -27
- package/server/service/data-entry/data-entry-update.test.ts +19 -0
- package/server/service/data-entry/data-entry.test.ts +65 -1
- package/server/service/data-entry/entry-target.ts +36 -5
- package/server/service/data-entry/entry-tools.ts +2 -2
- package/server/service/data-entry/entry-update.ts +6 -3
- package/server/service/data-read/list-missing.test.ts +49 -0
- package/server/service/data-read/list-read.ts +18 -0
- package/server/service/data-read/read-target.ts +10 -3
- package/server/service/data-read/read-tools.ts +1 -1
- package/server/service/data-read/record-keys.test.ts +36 -0
- package/server/service/index.ts +6 -1
- package/server/service/testing/conversation-script.ts +1 -1
- package/server/service/testing/mode-conformance.ts +2 -0
- package/test/assistant-dock.test.ts +5 -1
- package/test/assistant-session-manager.test.ts +4 -2
- package/test/open-doors.test.ts +10 -5
- package/translations/en.json +29 -4
- package/translations/es.json +29 -4
- package/translations/ja.json +29 -4
- package/translations/ko.json +30 -5
- package/translations/ms.json +29 -4
- package/translations/zh.json +29 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-update.js","sourceRoot":"","sources":["../../../server/service/data-entry/entry-update.ts"],"names":[],"mappings":";;;AA8CA,4CAGC;AAOD,8CA0BC;AAGD,kCAKC;AAGD,gCAiCC;AAUD,wCAqCC;AAKD,kCAuBC;AAMD,0CAQC;AAMD,4CASC;AAtOD;;;;;;;;;;GAUG;AACH,uDAW0B;AAmBb,QAAA,WAAW,GAAG,GAAG,CAAA;AAE9B,MAAM,aAAa,GAAG,CAAC,GAA6B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;AAEjG,uCAAuC;AACvC,SAAgB,gBAAgB,CAAC,MAAmB;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAA;IACnC,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;AAC1F,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAC/B,SAAiB,EACjB,OAAgB,EAChB,IAAqC;IAErC,MAAM,MAAM,GAAsE,EAAE,CAAA;IACpF,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,MAAM,IAAI,GAAG,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAA;IACnE,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QACvF,MAAM,GAAG,GAAG,OAAO,MAAM,EAAE,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACpE,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;YAC5D,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAA;;gBACxE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC;aAAM,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAK,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAW,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;YACzJ,IAAI,GAAG,CAAC,MAAM;gBAAE,KAAK,MAAM,EAAE,IAAI,GAAG;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;;gBAC7E,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAClC,CAAC;aAAM,IAAI,GAAG,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QAC7C,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAW,CAAC,EAAE,UAAU,EAAE,CAAA;AAC7D,CAAC;AAED,mFAAmF;AAC5E,KAAK,UAAU,WAAW,CAAC,MAAmB,EAAE,GAAa,EAAE,GAAkB;IACtF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAO,CAAA;IAC7B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IACrF,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5F,OAAO,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAC5K,CAAC;AAED,yDAAyD;AACzD,SAAgB,UAAU,CAAC,MAAmB,EAAE,MAAyE,EAAE,OAAiC;IAC1J,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IAClF,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAa,EAAE;QAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAClC,MAAM,MAAM,GAAiB,EAAE,CAAA;QAC/B,MAAM,MAAM,GAA4B,EAAE,CAAA;QAC1C,MAAM,MAAM,GAA4B,EAAE,CAAA;QAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;gBACrE,SAAQ;YACV,CAAC;YACD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,IAAA,gCAAc,EAAC,KAAK,EAAE,KAAK,CAAC,CAAA;YACtH,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;gBACpB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAK,EAAE,MAAM,EAAE,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;YAClI,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;gBACnG,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;YACrB,CAAC;YACD,IAAI,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;QACjD,CAAC;QACD,IAAI,CAAC,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;aACjE,CAAC;YACJ,0HAA0H;YAC1H,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,IAAA,gCAAc,EAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjL,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;;gBAC5G,KAAK,MAAM,IAAI,IAAI,IAAI;oBAAE,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAA;QACxE,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QACpI,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;IAC3J,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,4FAA4F;AAC5F,SAAS,cAAc,CAAC,MAAmB,EAAE,IAAiB;IAC5D,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAClE,OAAO,gBAAgB,CAAC,MAAM,CAAC;SAC5B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SACrC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;AAC/L,CAAC;AAEM,KAAK,UAAU,cAAc,CAAC,MAAmB,EAAE,IAAS,EAAE,OAAY,EAAE,GAAkB;IACnG,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;IAC1F,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY;YACvE,OAAO,EACL,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU;gBACzD,CAAC,CAAC,uBAAuB,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,uDAAuD,IAAA,8BAAY,EAAC,MAAM,CAAC,GAAG,CAAC,GAAG;gBACnK,CAAC,CAAC,8DAA8D,IAAA,8BAAY,EAAC,MAAM,CAAC,GAAG,CAAC,sBAAsB;SACnH,CAAA;IACH,CAAC;IACD,IAAI,OAAiC,CAAA;IACrC,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;IACrE,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,+BAA+B,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,EAAE,CAAA;IACpH,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,IAAA,mCAAiB,EAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,IAAA,gCAAc,EAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAA;IACvL,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;IACxF,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAA;IACjD,OAAO;QACL,QAAQ,EAAE,IAAI;QACd,IAAI,EAAE,OAAO;QACb,EAAE,EAAE,QAAQ;QACZ,MAAM,EAAE,MAAM,CAAC,GAAG;QAClB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,UAAU;QAC7C,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC;QACrC,IAAI;QACJ,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;QAC5E,GAAG,CAAC,OAAO,IAAI,EAAE,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzG,OAAO,EACL,YAAY,IAAI,CAAC,MAAM,aAAa,IAAI,CAAC,MAAM,GAAG,OAAO,WAAW,OAAO,gEAAgE;YAC3I,4DAA4D;KAC/D,CAAA;AACH,CAAC;AAEY,QAAA,cAAc,GAAG,EAAE,CAAA;AAEhC,4GAA4G;AACrG,KAAK,UAAU,WAAW,CAAC,MAAmB,EAAE,IAAS,EAAE,GAAkB;IAClF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAA;IAChC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAA;IAClG,MAAM,QAAQ,GAA4B,EAAE,CAAA;IAC5C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,SAAQ;QACnE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,gCAAc,EAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAC7C,IAAI,IAAI,KAAK,SAAS;YAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACrD,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC9D,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;IACrI,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAA;IACrH,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,sBAAc,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAClK,OAAO,EACL,KAAK,CAAC,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,sCAAsC,IAAA,gCAAc,EAAC,MAAM,CAAC,GAAG,CAAC,GAAG;YACrE,CAAC,CAAC,KAAK,CAAC,MAAM;gBACZ,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,iBAAiB,KAAK,CAAC,MAAM,GAAG,sBAAc,CAAC,CAAC,CAAC,WAAW,sBAAc,SAAS,CAAC,CAAC,CAAC,EAAE,oEAAoE;gBAC7K,CAAC,CAAC,+DAA+D;KACxE,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,MAAmB,EAAE,IAAiB,EAAE,GAA6B;IACnG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IACvE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACpB,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC9B,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;QACrG,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAA,gCAAc,EAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAClJ,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,CAAA;IACpJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,gBAAgB,CAAsB,MAAmB,EAAE,IAAS,EAAE,OAAiC,EAAE,OAAuB;IACpJ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK;QAAE,OAAO,IAAI,CAAA;IACtC,IAAI,KAAiC,CAAA;IACrC,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAChI,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACzG,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;AAC5G,CAAC","sourcesContent":["/*\n * Changing records that exist - the 수정안 (operato-application/design/ai/data-entry.md §5-1).\n *\n * The most expensive mistake is changing the wrong record, so which record is meant is settled here, by the\n * server, never by the model's memory. A record is picked by the screen (the one being looked at, the rows\n * selected) or by an id the find tool handed back; whichever way, it is read again through the application's\n * read query as the person, and a record they cannot see is not found. The card shows what is there now and\n * what it becomes; pressing reads it once more, and a field that moved in between keeps its row out.\n *\n * Pure but for the GraphQL runner, which comes in as an argument - the rules are tested without a server.\n */\nimport {\n changeToolName,\n findToolName,\n readFieldValue,\n resolveReferences,\n zonedDateTimes,\n sameFieldValue,\n type EntryField,\n type EntryIssue,\n type EntryRecord,\n type EntryTarget\n} from './entry-target.js'\n\n/** Runs one of the application's queries or mutations as the person. */\nexport type GraphqlRunner = (document: string, variables: Record<string, unknown>) => Promise<{ data?: any; errors?: readonly { message: string }[] }>\n\n/** How the record of a change was picked - said on the card, so the person sees the ground of it. */\nexport type ChangeVia = 'current' | 'selected' | 'id'\n\nexport interface ChangeRow {\n index: number\n id: string\n via: ChangeVia\n label?: string\n /** What the record holds now, for the fields that change - read by the server. */\n before: Record<string, unknown>\n values: Record<string, unknown>\n issues: EntryIssue[]\n}\n\nexport const MAX_CHANGES = 100\n\nconst blockedChange = (row: { issues: EntryIssue[] }) => row.issues.some(issue => issue.blocking)\n\n/** The fields a target lets change. */\nexport function changeableFields(target: EntryTarget): EntryField[] {\n const names = target.update?.fields\n return names ? target.fields.filter(field => names.includes(field.name)) : target.fields\n}\n\n/**\n * The records the changes name. `current` is the record on screen, `selected` every row selected there -\n * both from the surface's host context, which is **not trusted**: an id from it is only a candidate, read\n * through the application before anything is shown. Any other ref is an id, from the find tool.\n */\nexport function resolveChangeRefs(\n targetKey: string,\n changes: unknown,\n host: Record<string, any> | undefined\n): { picked: { id: string; via: ChangeVia; values: Record<string, unknown> }[]; unresolved: string[] } {\n const picked: { id: string; via: ChangeVia; values: Record<string, unknown> }[] = []\n const unresolved: string[] = []\n const mine = (one: any) => !one?.target || one.target === targetKey\n for (const change of Array.isArray(changes) ? changes : []) {\n const values = change?.values && typeof change.values === 'object' ? change.values : {}\n const ref = typeof change?.ref === 'string' ? change.ref.trim() : ''\n if (ref === 'current') {\n const id = mine(host?.record) ? host?.record?.id : undefined\n if (typeof id === 'string' && id) picked.push({ id, via: 'current', values })\n else unresolved.push('current')\n } else if (ref === 'selected') {\n const ids = mine(host?.selection) && Array.isArray(host?.selection?.ids) ? host!.selection.ids.filter((id: unknown) => typeof id === 'string' && id) : []\n if (ids.length) for (const id of ids) picked.push({ id, via: 'selected', values })\n else unresolved.push('selected')\n } else if (ref) {\n picked.push({ id: ref, via: 'id', values })\n } else {\n unresolved.push('no-ref')\n }\n }\n return { picked: picked.slice(0, MAX_CHANGES), unresolved }\n}\n\n/** Reads the records by id through the application's read query, as the person. */\nexport async function readRecords(target: EntryTarget, ids: string[], run: GraphqlRunner): Promise<Map<string, EntryRecord>> {\n const update = target.update!\n const answer = await run(update.read.query, update.read.variables([...new Set(ids)]))\n if (answer.errors?.length) throw new Error(answer.errors.map(one => one.message).join('; '))\n return new Map((update.read.recordsOf(answer.data, [...new Set(ids)]) ?? []).filter(record => record && typeof record.id === 'string').map(record => [record.id, record]))\n}\n\n/** The change rows against what the records hold now. */\nexport function changeRows(target: EntryTarget, picked: { id: string; via: ChangeVia; values: Record<string, unknown> }[], records: Map<string, EntryRecord>): ChangeRow[] {\n const fields = new Map(changeableFields(target).map(field => [field.name, field]))\n return picked.map((one, index): ChangeRow => {\n const record = records.get(one.id)\n const issues: EntryIssue[] = []\n const values: Record<string, unknown> = {}\n const before: Record<string, unknown> = {}\n for (const [name, value] of Object.entries(one.values)) {\n const field = fields.get(name)\n if (!field) {\n issues.push({ field: name, code: 'not-changeable', blocking: false })\n continue\n }\n const { read, code } = value === null || value === '' ? { read: null, code: undefined } : readFieldValue(field, value)\n if (read === undefined) {\n values[name] = value\n issues.push({ field: name, code: code!, params: code === 'not-in-list' ? { values: field.values } : undefined, blocking: true })\n } else {\n if (read === null && field.required) issues.push({ field: name, code: 'required', blocking: true })\n values[name] = read\n }\n if (record) before[name] = record[name] ?? null\n }\n if (!record) issues.push({ code: 'record-not-found', blocking: true })\n else {\n /* A field the model restated as it already is does not change - the card shows it as no change, and it is not written. */\n const same = Object.keys(values).filter(name => fields.has(name) && !issues.some(issue => issue.field === name) && sameFieldValue(fields.get(name)!, before[name], values[name]))\n if (same.length && same.length === Object.keys(values).length) issues.push({ code: 'no-change', blocking: true })\n else for (const name of same) delete values[name], delete before[name]\n }\n if (!Object.keys(values).length && !issues.some(issue => issue.blocking)) issues.push({ code: 'nothing-to-change', blocking: true })\n return { index, id: one.id, via: one.via, ...(record && target.update?.labelOf ? { label: target.update.labelOf(record) } : {}), before, values, issues }\n })\n}\n\n/** What the card needs besides the rows - the fields that change, in the target's order. */\nfunction changedColumns(target: EntryTarget, rows: ChangeRow[]) {\n const used = new Set(rows.flatMap(row => Object.keys(row.values)))\n return changeableFields(target)\n .filter(field => used.has(field.name))\n .map(field => ({ name: field.name, type: field.type, ...(field.labelKey ? { labelKey: field.labelKey } : {}), ...(field.valueKeyPrefix ? { valueKeyPrefix: field.valueKeyPrefix } : {}) }))\n}\n\nexport async function proposeChanges(target: EntryTarget, args: any, context: any, run: GraphqlRunner) {\n const { picked, unresolved } = resolveChangeRefs(target.key, args?.changes, context?.host)\n if (!picked.length) {\n return {\n rejected: true,\n error: unresolved.length ? `unresolved-${unresolved[0]}` : 'no-changes',\n message:\n unresolved[0] === 'current' || unresolved[0] === 'selected'\n ? `the screen names no ${unresolved[0] === 'current' ? 'record' : 'selected rows'} of this kind. Ask the person which record, or call ${findToolName(target.key)}.`\n : `name each record: ref \"current\", \"selected\", or an id from ${findToolName(target.key)}. Never guess an id.`\n }\n }\n let records: Map<string, EntryRecord>\n try {\n records = await readRecords(target, picked.map(one => one.id), run)\n } catch (error: any) {\n return { rejected: true, error: 'read-failed', message: `could not read the records: ${error?.message ?? error}` }\n }\n const changed = await resolveReferences(changeableFields(target), zonedDateTimes(changeableFields(target), changeRows(target, picked, records), context?.state?.domain?.timezone), run)\n const rows = await withChangeChecks(target, changed, records, { state: context?.state })\n const blocked = rows.filter(blockedChange).length\n return {\n proposed: true,\n kind: 'entry',\n op: 'update',\n target: target.key,\n labelKey: target.labelKey,\n label: `${rows.length} ${target.key} changes`,\n icon: 'edit_note',\n columns: changedColumns(target, rows),\n rows,\n counts: { rows: rows.length, ready: rows.length - blocked, blocked, cut: 0 },\n ...(typeof args?.note === 'string' && args.note.trim() ? { reason: args.note.trim().slice(0, 300) } : {}),\n message:\n `proposed ${rows.length} changes (${rows.length - blocked} ready, ${blocked} blocked). Nothing changes until the person presses the card. ` +\n 'Tell them which records are not found or would not change.'\n }\n}\n\nexport const MAX_CANDIDATES = 20\n\n/** Candidates for what the person described - the model lists them and asks when there is more than one. */\nexport async function findRecords(target: EntryTarget, args: any, run: GraphqlRunner) {\n const find = target.update?.find\n if (!find) return { rejected: true, error: 'no-find', message: 'this record cannot be searched.' }\n const criteria: Record<string, unknown> = {}\n for (const field of find.criteria) {\n const value = args?.[field.name]\n if (value === undefined || value === null || value === '') continue\n const { read } = readFieldValue(field, value)\n if (read !== undefined) criteria[field.name] = read\n }\n const answer = await run(find.query, find.variables(criteria))\n if (answer.errors?.length) return { rejected: true, error: 'find-failed', message: answer.errors.map(one => one.message).join('; ') }\n const found = (find.recordsOf(answer.data, criteria) ?? []).filter(record => record && typeof record.id === 'string')\n return {\n total: found.length,\n candidates: found.slice(0, MAX_CANDIDATES).map(record => ({ id: record.id, ...(target.update?.labelOf ? { label: target.update.labelOf(record) } : {}), record })),\n message:\n found.length === 1\n ? `one record matches; pass its id to ${changeToolName(target.key)}.`\n : found.length\n ? `${found.length} records match${found.length > MAX_CANDIDATES ? ` (first ${MAX_CANDIDATES} shown)` : ''}. List them to the person and ask which - never pick one yourself.`\n : 'no record matches. Tell the person and ask for more to go on.'\n }\n}\n\n/**\n * The rows of a pressed 수정안, against what the records hold now. A row whose field moved since the card was\n * made is kept out as `changed-since` - it is not overwritten unseen.\n */\nexport function stillAsProposed(target: EntryTarget, rows: ChangeRow[], now: Map<string, EntryRecord>): (ChangeRow & { now?: EntryRecord })[] {\n const fields = new Map(target.fields.map(field => [field.name, field]))\n return rows.map(row => {\n const record = now.get(row.id)\n if (!record) return { ...row, issues: [...row.issues, { code: 'record-not-found', blocking: true }] }\n const moved = Object.keys(row.values).find(name => fields.get(name) && !sameFieldValue(fields.get(name)!, record[name] ?? null, row.before[name]))\n return moved ? { ...row, now: record, issues: [...row.issues, { field: moved, code: 'changed-since', blocking: true }] } : { ...row, now: record }\n })\n}\n\n/**\n * The target's own checks of the changes, added to each row. A check that could not run keeps every row out - a\n * change is not written unchecked (an entry's failed check refuses its card the same way).\n */\nexport async function withChangeChecks<T extends ChangeRow>(target: EntryTarget, rows: T[], records: Map<string, EntryRecord>, context: { state: any }): Promise<T[]> {\n if (!target.update?.check) return rows\n let found: EntryIssue[][] | undefined\n try {\n found = await target.update.check(rows.map(row => ({ id: row.id, record: records.get(row.id), values: row.values })), context)\n } catch {\n return rows.map(row => ({ ...row, issues: [...row.issues, { code: 'check-failed', blocking: true }] }))\n }\n return rows.map((row, i) => (found?.[i]?.length ? { ...row, issues: [...row.issues, ...found[i]] } : row))\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"entry-update.js","sourceRoot":"","sources":["../../../server/service/data-entry/entry-update.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Changing records that exist - the 수정안 (operato-application/design/ai/data-entry.md §5-1).\n *\n * The most expensive mistake is changing the wrong record, so which record is meant is settled here, by the\n * server, never by the model's memory. A record is picked by the screen (the one being looked at, the rows\n * selected) or by an id the find tool handed back; whichever way, it is read again through the application's\n * read query as the person, and a record they cannot see is not found. The card shows what is there now and\n * what it becomes; pressing reads it once more, and a field that moved in between keeps its row out.\n *\n * Pure but for the GraphQL runner, which comes in as an argument - the rules are tested without a server.\n */\nimport {\n changeToolName,\n findToolName,\n readFieldValue,\n recordIdOfKey,\n resolveReferences,\n zonedDateTimes,\n sameFieldValue,\n type EntryField,\n type EntryIssue,\n type EntryRecord,\n type EntryTarget\n} from './entry-target.js'\n\n/** Runs one of the application's queries or mutations as the person. */\nexport type GraphqlRunner = (document: string, variables: Record<string, unknown>) => Promise<{ data?: any; errors?: readonly { message: string }[] }>\n\n/** How the record of a change was picked - said on the card, so the person sees the ground of it. */\nexport type ChangeVia = 'current' | 'selected' | 'id'\n\nexport interface ChangeRow {\n index: number\n id: string\n via: ChangeVia\n label?: string\n /** What the record holds now, for the fields that change - read by the server. */\n before: Record<string, unknown>\n values: Record<string, unknown>\n issues: EntryIssue[]\n}\n\nexport const MAX_CHANGES = 100\n\nconst blockedChange = (row: { issues: EntryIssue[] }) => row.issues.some(issue => issue.blocking)\n\n/** The fields a target lets change. */\nexport function changeableFields(target: EntryTarget): EntryField[] {\n const names = target.update?.fields\n return names ? target.fields.filter(field => names.includes(field.name)) : target.fields\n}\n\n/**\n * The records the changes name. `current` is the record on screen, `selected` every row selected there -\n * both from the surface's host context, which is **not trusted**: an id from it is only a candidate, read\n * through the application before anything is shown. Any other ref is an id, from the find tool, or the key the record\n * was shown by.\n */\nexport function resolveChangeRefs(\n targetKey: string,\n changes: unknown,\n host: Record<string, any> | undefined\n): { picked: { id: string; via: ChangeVia; values: Record<string, unknown> }[]; unresolved: string[] } {\n const picked: { id: string; via: ChangeVia; values: Record<string, unknown> }[] = []\n const unresolved: string[] = []\n const mine = (one: any) => !one?.target || one.target === targetKey\n for (const change of Array.isArray(changes) ? changes : []) {\n const values = change?.values && typeof change.values === 'object' ? change.values : {}\n const ref = typeof change?.ref === 'string' ? change.ref.trim() : ''\n if (ref === 'current') {\n const id = mine(host?.record) ? host?.record?.id : undefined\n if (typeof id === 'string' && id) picked.push({ id, via: 'current', values })\n else unresolved.push('current')\n } else if (ref === 'selected') {\n const ids = mine(host?.selection) && Array.isArray(host?.selection?.ids) ? host!.selection.ids.filter((id: unknown) => typeof id === 'string' && id) : []\n if (ids.length) for (const id of ids) picked.push({ id, via: 'selected', values })\n else unresolved.push('selected')\n } else if (ref) {\n /* An open record's key - `contract-round:<id>` for `office.contract-round` - names the record of this target's axis. */\n picked.push({ id: recordIdOfKey(targetKey.split('.').pop()!, ref) ?? ref, via: 'id', values })\n } else {\n unresolved.push('no-ref')\n }\n }\n return { picked: picked.slice(0, MAX_CHANGES), unresolved }\n}\n\n/** Reads the records by id through the application's read query, as the person. */\nexport async function readRecords(target: EntryTarget, ids: string[], run: GraphqlRunner): Promise<Map<string, EntryRecord>> {\n const update = target.update!\n const answer = await run(update.read.query, update.read.variables([...new Set(ids)]))\n if (answer.errors?.length) throw new Error(answer.errors.map(one => one.message).join('; '))\n return new Map((update.read.recordsOf(answer.data, [...new Set(ids)]) ?? []).filter(record => record && typeof record.id === 'string').map(record => [record.id, record]))\n}\n\n/** The change rows against what the records hold now. */\nexport function changeRows(target: EntryTarget, picked: { id: string; via: ChangeVia; values: Record<string, unknown> }[], records: Map<string, EntryRecord>): ChangeRow[] {\n const fields = new Map(changeableFields(target).map(field => [field.name, field]))\n return picked.map((one, index): ChangeRow => {\n const record = records.get(one.id)\n const issues: EntryIssue[] = []\n const values: Record<string, unknown> = {}\n const before: Record<string, unknown> = {}\n for (const [name, value] of Object.entries(one.values)) {\n const field = fields.get(name)\n if (!field) {\n issues.push({ field: name, code: 'not-changeable', blocking: false })\n continue\n }\n const { read, code } = value === null || value === '' ? { read: null, code: undefined } : readFieldValue(field, value)\n if (read === undefined) {\n values[name] = value\n issues.push({ field: name, code: code!, params: code === 'not-in-list' ? { values: field.values } : undefined, blocking: true })\n } else {\n if (read === null && field.required) issues.push({ field: name, code: 'required', blocking: true })\n values[name] = read\n }\n if (record) before[name] = record[name] ?? null\n }\n if (!record) issues.push({ code: 'record-not-found', blocking: true })\n else {\n /* A field the model restated as it already is does not change - the card shows it as no change, and it is not written. */\n const same = Object.keys(values).filter(name => fields.has(name) && !issues.some(issue => issue.field === name) && sameFieldValue(fields.get(name)!, before[name], values[name]))\n if (same.length && same.length === Object.keys(values).length) issues.push({ code: 'no-change', blocking: true })\n else for (const name of same) delete values[name], delete before[name]\n }\n if (!Object.keys(values).length && !issues.some(issue => issue.blocking)) issues.push({ code: 'nothing-to-change', blocking: true })\n return { index, id: one.id, via: one.via, ...(record && target.update?.labelOf ? { label: target.update.labelOf(record) } : {}), before, values, issues }\n })\n}\n\n/** What the card needs besides the rows - the fields that change, in the target's order. */\nfunction changedColumns(target: EntryTarget, rows: ChangeRow[]) {\n const used = new Set(rows.flatMap(row => Object.keys(row.values)))\n return changeableFields(target)\n .filter(field => used.has(field.name))\n .map(field => ({ name: field.name, type: field.type, ...(field.labelKey ? { labelKey: field.labelKey } : {}), ...(field.valueKeyPrefix ? { valueKeyPrefix: field.valueKeyPrefix } : {}) }))\n}\n\nexport async function proposeChanges(target: EntryTarget, args: any, context: any, run: GraphqlRunner) {\n const { picked, unresolved } = resolveChangeRefs(target.key, args?.changes, context?.host)\n if (!picked.length) {\n return {\n rejected: true,\n error: unresolved.length ? `unresolved-${unresolved[0]}` : 'no-changes',\n message:\n unresolved[0] === 'current' || unresolved[0] === 'selected'\n ? `the screen names no ${unresolved[0] === 'current' ? 'record' : 'selected rows'} of this kind. Ask the person which record, or call ${findToolName(target.key)}.`\n : `name each record: ref \"current\", \"selected\", or an id a list read or ${findToolName(target.key)} returned. Never guess an id.`\n }\n }\n let records: Map<string, EntryRecord>\n try {\n records = await readRecords(target, picked.map(one => one.id), run)\n } catch (error: any) {\n return { rejected: true, error: 'read-failed', message: `could not read the records: ${error?.message ?? error}` }\n }\n const changed = await resolveReferences(changeableFields(target), zonedDateTimes(changeableFields(target), changeRows(target, picked, records), context?.state?.domain?.timezone), run)\n const rows = await withChangeChecks(target, changed, records, { state: context?.state })\n const blocked = rows.filter(blockedChange).length\n return {\n proposed: true,\n kind: 'entry',\n op: 'update',\n target: target.key,\n labelKey: target.labelKey,\n label: `${rows.length} ${target.key} changes`,\n icon: 'edit_note',\n columns: changedColumns(target, rows),\n rows,\n counts: { rows: rows.length, ready: rows.length - blocked, blocked, cut: 0 },\n ...(typeof args?.note === 'string' && args.note.trim() ? { reason: args.note.trim().slice(0, 300) } : {}),\n message:\n `proposed ${rows.length} changes (${rows.length - blocked} ready, ${blocked} blocked). Nothing changes until the person presses the card. ` +\n 'Tell them which records are not found or would not change.'\n }\n}\n\nexport const MAX_CANDIDATES = 20\n\n/** Candidates for what the person described - the model lists them and asks when there is more than one. */\nexport async function findRecords(target: EntryTarget, args: any, run: GraphqlRunner) {\n const find = target.update?.find\n if (!find) return { rejected: true, error: 'no-find', message: 'this record cannot be searched.' }\n const criteria: Record<string, unknown> = {}\n for (const field of find.criteria) {\n const value = args?.[field.name]\n if (value === undefined || value === null || value === '') continue\n const { read } = readFieldValue(field, value)\n if (read !== undefined) criteria[field.name] = read\n }\n const answer = await run(find.query, find.variables(criteria))\n if (answer.errors?.length) return { rejected: true, error: 'find-failed', message: answer.errors.map(one => one.message).join('; ') }\n const found = (find.recordsOf(answer.data, criteria) ?? []).filter(record => record && typeof record.id === 'string')\n return {\n total: found.length,\n candidates: found.slice(0, MAX_CANDIDATES).map(record => ({ id: record.id, ...(target.update?.labelOf ? { label: target.update.labelOf(record) } : {}), record })),\n message:\n found.length === 1\n ? `one record matches; pass its id to ${changeToolName(target.key)}.`\n : found.length\n ? `${found.length} records match${found.length > MAX_CANDIDATES ? ` (first ${MAX_CANDIDATES} shown)` : ''}. List them to the person and ask which - never pick one yourself.`\n : 'no record matches. Tell the person and ask for more to go on.'\n }\n}\n\n/**\n * The rows of a pressed 수정안, against what the records hold now. A row whose field moved since the card was\n * made is kept out as `changed-since` - it is not overwritten unseen.\n */\nexport function stillAsProposed(target: EntryTarget, rows: ChangeRow[], now: Map<string, EntryRecord>): (ChangeRow & { now?: EntryRecord })[] {\n const fields = new Map(target.fields.map(field => [field.name, field]))\n return rows.map(row => {\n const record = now.get(row.id)\n if (!record) return { ...row, issues: [...row.issues, { code: 'record-not-found', blocking: true }] }\n const moved = Object.keys(row.values).find(name => fields.get(name) && !sameFieldValue(fields.get(name)!, record[name] ?? null, row.before[name]))\n return moved ? { ...row, now: record, issues: [...row.issues, { field: moved, code: 'changed-since', blocking: true }] } : { ...row, now: record }\n })\n}\n\n/**\n * The target's own checks of the changes, added to each row. A check that could not run keeps every row out - a\n * change is not written unchecked (an entry's failed check refuses its card the same way).\n */\nexport async function withChangeChecks<T extends ChangeRow>(target: EntryTarget, rows: T[], records: Map<string, EntryRecord>, context: { state: any }): Promise<T[]> {\n if (!target.update?.check) return rows\n let found: EntryIssue[][] | undefined\n try {\n found = await target.update.check(rows.map(row => ({ id: row.id, record: records.get(row.id), values: row.values })), context)\n } catch {\n return rows.map(row => ({ ...row, issues: [...row.issues, { code: 'check-failed', blocking: true }] }))\n }\n return rows.map((row, i) => (found?.[i]?.length ? { ...row, issues: [...row.issues, ...found[i]] } : row))\n}\n\n"]}
|
|
@@ -34,5 +34,15 @@ export interface ListRead {
|
|
|
34
34
|
route?: string;
|
|
35
35
|
/** The route has a URL-bound grid. Otherwise conditions are disclosed as not applied on its screen card. */
|
|
36
36
|
screenQuery?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* What a row may be missing - the screen's own "no counterparty", "no account subject" filters - the `missing`
|
|
39
|
+
* condition. Asked to fill the bank lines' unregistered parties, the model had no way to say "unregistered" and
|
|
40
|
+
* searched the asker's own name (2026-10-24).
|
|
41
|
+
*/
|
|
42
|
+
missing?: {
|
|
43
|
+
name: string;
|
|
44
|
+
description: string;
|
|
45
|
+
filters: ReadFilter[];
|
|
46
|
+
}[];
|
|
37
47
|
}
|
|
38
48
|
export declare function listReadTarget(list: ListRead): ReadTarget;
|
|
@@ -27,6 +27,18 @@ function listReadTarget(list) {
|
|
|
27
27
|
...(list.status
|
|
28
28
|
? [{ name: 'status', type: 'enum', values: list.status.values, labelKey: 'ai-assistant.read.status', filter: (v) => ({ name: list.status.field, operator: 'eq', value: v }) }]
|
|
29
29
|
: []),
|
|
30
|
+
...(list.missing?.length
|
|
31
|
+
? [
|
|
32
|
+
{
|
|
33
|
+
name: 'missing',
|
|
34
|
+
type: 'enum',
|
|
35
|
+
values: list.missing.map(one => one.name),
|
|
36
|
+
labelKey: 'ai-assistant.read.missing',
|
|
37
|
+
description: `the rows missing one thing: ${list.missing.map(one => `${one.name} - ${one.description}`).join('; ')}`,
|
|
38
|
+
filter: (v) => list.missing.find(one => one.name === v).filters
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
: []),
|
|
30
42
|
...(amount
|
|
31
43
|
? [
|
|
32
44
|
{ name: 'minAmount', type: 'number', labelKey: 'ai-assistant.read.min-amount', description: `at least this ${amount}${inCurrency}`, filter: (v) => ({ name: amount, operator: 'gte', value: v }) },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-read.js","sourceRoot":"","sources":["../../../server/service/data-read/list-read.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * A list declared in one line (operato-application/design/ai/read-targets.md §3) - the shape most list screens share:\n * a ListParam query, the fields it reads, a date to range over, a status, an amount, search words, and a screen.\n * Each application writes its lists as these lines; this turns one into a read target with the conditions it takes.\n */\nimport type { ReadColumn, ReadCriterion, ReadFilter, ReadTarget } from './read-target.js'\n\nexport interface ListRead {\n /** `<app>.<record>`. */\n key: string\n /** i18n key of the screen's title - the card's name. */\n title: string\n /** The screen's name as the person knows it - the model picks the list by it. */\n name: string\n /** The ListParam query (`transactions`). */\n listQuery: string\n /** Filters every read applies, out of the model's reach - the records the list is of (`category` CONFIRMED). */\n fixedFilters?: ReadFilter[]\n /** The fields of each item it reads - the screen's own selection where there is one. */\n selection: string\n columns: ReadColumn[]\n /** A date (or date-time) field the `from` / `to` conditions range over. */\n dateField?: string\n /** Integer year and month fields, and an in/out field (INCOME | EXPENSE) - the `year`, `month`, `flow` conditions. */\n narrowing?: { year?: string; month?: string; flow?: string }\n /** A field holding the period as YYYY-MM - the `period` condition. */\n monthField?: string\n /** A status field and its values - the `status` condition. */\n status?: { field: string; values: string[] }\n /** The resolver's searchables, said for the model - the list takes ListParam search (the `text` condition). */\n search?: string\n /** The screen's route. Left out, the list has no screen card. */\n route?: string\n /** The route has a URL-bound grid. Otherwise conditions are disclosed as not applied on its screen card. */\n screenQuery?: boolean\n}\n\n/** The money column a minimum or maximum amount means - `amount` when there is one, else the first summed column. */\nconst amountOf = (list: ListRead) => list.columns.find(one => one.name === 'amount' && one.type === 'number')?.name ?? list.columns.find(one => one.total)?.name\n\nexport function listReadTarget(list: ListRead): ReadTarget {\n const search = !!list.search\n const amount = amountOf(list)\n /* A bound compares the stored number - in each row's own currency when the column has one. */\n const inCurrency = list.columns.find(one => one.name === amount)?.currency ? `, compared in each row's own ${list.columns.find(one => one.name === amount)!.currency} - a row in another currency is held to the same number` : ''\n const narrowing = list.narrowing ?? {}\n const criteria: ReadCriterion[] = [\n ...(list.dateField\n ? [\n { name: 'from', type: 'date', labelKey: 'ai-assistant.read.from', description: `the first ${list.dateField}, inclusive`, filter: (v: any) => ({ name: list.dateField!, operator: 'gte', value: v }) },\n { name: 'to', type: 'date', labelKey: 'ai-assistant.read.to', description: `the last ${list.dateField}, inclusive`, filter: (v: any) => ({ name: list.dateField!, operator: 'lte', value: `${v}${/T/.test(String(v)) ? '' : 'T23:59:59.999'}` }) }\n ]\n : []),\n ...(narrowing.year ? [{ name: 'year', type: 'integer', labelKey: 'ai-assistant.read.year', description: 'a year (2026)', filter: (v: any) => ({ name: narrowing.year!, operator: 'eq', value: v }) }] : []),\n ...(narrowing.month ? [{ name: 'month', type: 'integer', labelKey: 'ai-assistant.read.month', description: '1-12, with a year', filter: (v: any) => ({ name: narrowing.month!, operator: 'eq', value: v }) }] : []),\n ...(narrowing.flow\n ? [{ name: 'flow', type: 'enum', values: ['INCOME', 'EXPENSE'], labelKey: 'ai-assistant.read.flow', description: 'money in or out', filter: (v: any) => ({ name: narrowing.flow!, operator: 'eq', value: v }) }]\n : []),\n ...(list.monthField\n ? [{ name: 'period', type: 'string', labelKey: 'ai-assistant.read.period', description: 'a month as YYYY-MM', filter: (v: any) => ({ name: list.monthField!, operator: 'eq', value: v }) }]\n : []),\n ...(list.status\n ? [{ name: 'status', type: 'enum', values: list.status.values, labelKey: 'ai-assistant.read.status', filter: (v: any) => ({ name: list.status!.field, operator: 'eq', value: v }) }]\n : []),\n ...(amount\n ? [\n { name: 'minAmount', type: 'number', labelKey: 'ai-assistant.read.min-amount', description: `at least this ${amount}${inCurrency}`, filter: (v: any) => ({ name: amount, operator: 'gte', value: v }) },\n { name: 'maxAmount', type: 'number', labelKey: 'ai-assistant.read.max-amount', description: `at most this ${amount}${inCurrency}`, filter: (v: any) => ({ name: amount, operator: 'lte', value: v }) }\n ]\n : [])\n ] as ReadCriterion[]\n\n const takes = list.screenQuery\n ? ['id', ...criteria.map(criterion => criterion.name), ...(search ? ['text'] : [])]\n : []\n return {\n key: list.key,\n labelKey: list.title,\n description: `the rows of the list 「${list.name}」 (${list.columns.map(one => one.name).join(', ')}).`,\n query:\n `query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]${search ? ', $search: String' : ''}) ` +\n `{ ${list.listQuery}(filters: $filters, pagination: $pagination, sortings: $sortings${search ? ', search: $search' : ''}) { items { ${list.selection} } total } }`,\n criteria,\n ...(list.fixedFilters?.length ? { fixedFilters: list.fixedFilters } : {}),\n columns: list.columns,\n rowsOf: data => ({ rows: data?.[list.listQuery]?.items ?? [], total: data?.[list.listQuery]?.total ?? 0 }),\n ...(search ? { search: { description: `the ${list.search}` } } : {}),\n ...(list.dateField ? { sortings: [{ name: list.dateField, desc: true }] } : {}),\n ...(list.route\n ? {\n screen: {\n route: list.route,\n labelKey: list.title,\n takes,\n queryState: !!list.screenQuery,\n params: () => ({})\n }\n }\n : {})\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"list-read.js","sourceRoot":"","sources":["../../../server/service/data-read/list-read.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * A list declared in one line (operato-application/design/ai/read-targets.md §3) - the shape most list screens share:\n * a ListParam query, the fields it reads, a date to range over, a status, an amount, search words, and a screen.\n * Each application writes its lists as these lines; this turns one into a read target with the conditions it takes.\n */\nimport type { ReadColumn, ReadCriterion, ReadFilter, ReadTarget } from './read-target.js'\n\nexport interface ListRead {\n /** `<app>.<record>`. */\n key: string\n /** i18n key of the screen's title - the card's name. */\n title: string\n /** The screen's name as the person knows it - the model picks the list by it. */\n name: string\n /** The ListParam query (`transactions`). */\n listQuery: string\n /** Filters every read applies, out of the model's reach - the records the list is of (`category` CONFIRMED). */\n fixedFilters?: ReadFilter[]\n /** The fields of each item it reads - the screen's own selection where there is one. */\n selection: string\n columns: ReadColumn[]\n /** A date (or date-time) field the `from` / `to` conditions range over. */\n dateField?: string\n /** Integer year and month fields, and an in/out field (INCOME | EXPENSE) - the `year`, `month`, `flow` conditions. */\n narrowing?: { year?: string; month?: string; flow?: string }\n /** A field holding the period as YYYY-MM - the `period` condition. */\n monthField?: string\n /** A status field and its values - the `status` condition. */\n status?: { field: string; values: string[] }\n /** The resolver's searchables, said for the model - the list takes ListParam search (the `text` condition). */\n search?: string\n /** The screen's route. Left out, the list has no screen card. */\n route?: string\n /** The route has a URL-bound grid. Otherwise conditions are disclosed as not applied on its screen card. */\n screenQuery?: boolean\n /**\n * What a row may be missing - the screen's own \"no counterparty\", \"no account subject\" filters - the `missing`\n * condition. Asked to fill the bank lines' unregistered parties, the model had no way to say \"unregistered\" and\n * searched the asker's own name (2026-10-24).\n */\n missing?: { name: string; description: string; filters: ReadFilter[] }[]\n}\n\n/** The money column a minimum or maximum amount means - `amount` when there is one, else the first summed column. */\nconst amountOf = (list: ListRead) => list.columns.find(one => one.name === 'amount' && one.type === 'number')?.name ?? list.columns.find(one => one.total)?.name\n\nexport function listReadTarget(list: ListRead): ReadTarget {\n const search = !!list.search\n const amount = amountOf(list)\n /* A bound compares the stored number - in each row's own currency when the column has one. */\n const inCurrency = list.columns.find(one => one.name === amount)?.currency ? `, compared in each row's own ${list.columns.find(one => one.name === amount)!.currency} - a row in another currency is held to the same number` : ''\n const narrowing = list.narrowing ?? {}\n const criteria: ReadCriterion[] = [\n ...(list.dateField\n ? [\n { name: 'from', type: 'date', labelKey: 'ai-assistant.read.from', description: `the first ${list.dateField}, inclusive`, filter: (v: any) => ({ name: list.dateField!, operator: 'gte', value: v }) },\n { name: 'to', type: 'date', labelKey: 'ai-assistant.read.to', description: `the last ${list.dateField}, inclusive`, filter: (v: any) => ({ name: list.dateField!, operator: 'lte', value: `${v}${/T/.test(String(v)) ? '' : 'T23:59:59.999'}` }) }\n ]\n : []),\n ...(narrowing.year ? [{ name: 'year', type: 'integer', labelKey: 'ai-assistant.read.year', description: 'a year (2026)', filter: (v: any) => ({ name: narrowing.year!, operator: 'eq', value: v }) }] : []),\n ...(narrowing.month ? [{ name: 'month', type: 'integer', labelKey: 'ai-assistant.read.month', description: '1-12, with a year', filter: (v: any) => ({ name: narrowing.month!, operator: 'eq', value: v }) }] : []),\n ...(narrowing.flow\n ? [{ name: 'flow', type: 'enum', values: ['INCOME', 'EXPENSE'], labelKey: 'ai-assistant.read.flow', description: 'money in or out', filter: (v: any) => ({ name: narrowing.flow!, operator: 'eq', value: v }) }]\n : []),\n ...(list.monthField\n ? [{ name: 'period', type: 'string', labelKey: 'ai-assistant.read.period', description: 'a month as YYYY-MM', filter: (v: any) => ({ name: list.monthField!, operator: 'eq', value: v }) }]\n : []),\n ...(list.status\n ? [{ name: 'status', type: 'enum', values: list.status.values, labelKey: 'ai-assistant.read.status', filter: (v: any) => ({ name: list.status!.field, operator: 'eq', value: v }) }]\n : []),\n ...(list.missing?.length\n ? [\n {\n name: 'missing',\n type: 'enum',\n values: list.missing.map(one => one.name),\n labelKey: 'ai-assistant.read.missing',\n description: `the rows missing one thing: ${list.missing.map(one => `${one.name} - ${one.description}`).join('; ')}`,\n filter: (v: any) => list.missing!.find(one => one.name === v)!.filters\n }\n ]\n : []),\n ...(amount\n ? [\n { name: 'minAmount', type: 'number', labelKey: 'ai-assistant.read.min-amount', description: `at least this ${amount}${inCurrency}`, filter: (v: any) => ({ name: amount, operator: 'gte', value: v }) },\n { name: 'maxAmount', type: 'number', labelKey: 'ai-assistant.read.max-amount', description: `at most this ${amount}${inCurrency}`, filter: (v: any) => ({ name: amount, operator: 'lte', value: v }) }\n ]\n : [])\n ] as ReadCriterion[]\n\n const takes = list.screenQuery\n ? ['id', ...criteria.map(criterion => criterion.name), ...(search ? ['text'] : [])]\n : []\n return {\n key: list.key,\n labelKey: list.title,\n description: `the rows of the list 「${list.name}」 (${list.columns.map(one => one.name).join(', ')}).`,\n query:\n `query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]${search ? ', $search: String' : ''}) ` +\n `{ ${list.listQuery}(filters: $filters, pagination: $pagination, sortings: $sortings${search ? ', search: $search' : ''}) { items { ${list.selection} } total } }`,\n criteria,\n ...(list.fixedFilters?.length ? { fixedFilters: list.fixedFilters } : {}),\n columns: list.columns,\n rowsOf: data => ({ rows: data?.[list.listQuery]?.items ?? [], total: data?.[list.listQuery]?.total ?? 0 }),\n ...(search ? { search: { description: `the ${list.search}` } } : {}),\n ...(list.dateField ? { sortings: [{ name: list.dateField, desc: true }] } : {}),\n ...(list.route\n ? {\n screen: {\n route: list.route,\n labelKey: list.title,\n takes,\n queryState: !!list.screenQuery,\n params: () => ({})\n }\n }\n : {})\n }\n}\n"]}
|
|
@@ -91,6 +91,8 @@ export interface DetailArg {
|
|
|
91
91
|
values?: string[];
|
|
92
92
|
description?: string;
|
|
93
93
|
required?: boolean;
|
|
94
|
+
/** A record's id: the axis (or axes) of the record, whose key `<axis>:<id>` the model may have been shown (EntryField.axis). */
|
|
95
|
+
axis?: string | readonly string[];
|
|
94
96
|
}
|
|
95
97
|
/**
|
|
96
98
|
* A query whose answer is one thing, not a list - a 360's summary, the receivables, a statement (design/ai/read-targets.md
|
|
@@ -107,6 +109,11 @@ export interface DetailRead {
|
|
|
107
109
|
/** One query with one root field. Its variables are the arguments - each declared in `args`. */
|
|
108
110
|
query: string;
|
|
109
111
|
args?: DetailArg[];
|
|
112
|
+
/**
|
|
113
|
+
* The records the answer is about, whose screens put it in front (EntryTarget.axes) - the management check answers
|
|
114
|
+
* for any ledger record; asked on a deposit's 360 why it was in the check, the model never opened it (2026-10-24).
|
|
115
|
+
*/
|
|
116
|
+
axes?: string[];
|
|
110
117
|
}
|
|
111
118
|
/** Characters of an answer handed to the model - a longer one is refused, and the model narrows it. */
|
|
112
119
|
export declare const MAX_DETAIL_CHARS = 60000;
|
|
@@ -125,9 +125,9 @@ function detailReadOf(key) {
|
|
|
125
125
|
function readCriteria(target, args) {
|
|
126
126
|
const criteria = {};
|
|
127
127
|
const refused = [];
|
|
128
|
-
/* One record by its id - every target takes it (the id a list answer or a find tool gave). */
|
|
128
|
+
/* One record by its id - every target takes it (the id a list answer or a find tool gave, or the key `<axis>:<id>` an open record is shown by, the axis being the key's last part). */
|
|
129
129
|
if (typeof args?.id === 'string' && args.id.trim())
|
|
130
|
-
criteria.id = args.id.trim();
|
|
130
|
+
criteria.id = (0, entry_target_js_1.recordIdOfKey)(target.key.split('.').pop(), args.id) ?? args.id.trim();
|
|
131
131
|
if (target.search && typeof args?.text === 'string' && args.text.trim())
|
|
132
132
|
criteria.text = args.text.trim();
|
|
133
133
|
for (const criterion of target.criteria) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-target.js","sourceRoot":"","sources":["../../../server/service/data-read/read-target.ts"],"names":[],"mappings":";;;AAyGA,8CAoBC;AAED,oCAEC;AAED,4CAGC;AA2CD,8CAeC;AAED,oCAEC;AAGD,oCAcC;AAED,8BAOC;AAKD,sBAcC;AAMD,4BAkBC;AAiBD,wBAeC;AAGD,oCAIC;AAGD,4BAsBC;AAGD,sCAmBC;AA/VD;;;;;;;;;;GAUG;AACH,mEAA4F;AAC5F,gEAA8D;AAE9D,qCAA+B;AAuE/B,wGAAwG;AAC3F,QAAA,aAAa,GAAG,IAAI,CAAA;AACjC,0DAA0D;AAC7C,QAAA,cAAc,GAAG,EAAE,CAAA;AAChC,gCAAgC;AACnB,QAAA,SAAS,GAAG,GAAG,CAAA;AAE5B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAA;AAE9C,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE,CAC/B,GAAG;KACA,KAAK,CAAC,eAAe,CAAC;KACtB,MAAM,CAAC,OAAO,CAAC;KACf,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAClD,IAAI,CAAC,EAAE,CAAC,CAAA;AAEN,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,QAAQ,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAA;AAAxD,QAAA,aAAa,iBAA2C;AAC9D,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAA;AAA9D,QAAA,cAAc,kBAAgD;AACpE,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAA;AAAtD,QAAA,gBAAgB,oBAAsC;AAEnE,SAAgB,iBAAiB,CAAC,MAAkB;IAClD,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,GAAG,yBAAyB,CAAC,CAAA;IAC1H,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,qBAAqB,CAAC,CAAA;IACzH,IAAA,6BAAW,EAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAClC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAA;IAC1F,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,IAAI,SAAS,MAAM,CAAC,GAAG,+CAA+C,CAAC,CAAA;QACxJ,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,IAAI,SAAS,MAAM,CAAC,GAAG,8BAA8B,MAAM,CAAC,QAAQ,8BAA8B,CAAC,CAAA;IACxN,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,CAAC,CAAA;IACrC,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxC,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,yCAAyC,CAAC,CAAA;QACjH,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,6DAA6D,CAAC,CAAA;QACxJ,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,0BAA0B,SAAS,CAAC,IAAI,SAAS,CAAC,CAAA;QAC3H,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACzB,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,cAAc,SAAS,CAAC,IAAI,SAAS,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAA;IACjJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM;QAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACpC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;QAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,CAAC,GAAG,YAAY,KAAK,0BAA0B,CAAC,CAAA;IAC/J,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;AAClC,CAAC;AAED,SAAgB,YAAY,CAAC,GAAuB;IAClD,OAAO,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5C,CAAC;AAED,SAAgB,gBAAgB;IAC9B,QAAQ,CAAC,KAAK,EAAE,CAAA;IAChB,OAAO,CAAC,KAAK,EAAE,CAAA;AACjB,CAAC;AA8BD,uGAAuG;AAC1F,QAAA,gBAAgB,GAAG,MAAM,CAAA;AAEtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAA;AAEtC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAA;AAAxD,QAAA,cAAc,kBAA0C;AAErE,0EAA0E;AAC1E,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,SAAS,GAAQ,IAAA,eAAK,EAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAA;IACzG,OAAO,CAAC,SAAS,EAAE,mBAAmB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;AACtK,CAAC;AAED,SAAgB,iBAAiB,CAAC,MAAkB;IAClD,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,GAAG,wBAAwB,CAAC,CAAA;IACzH,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,qBAAqB,CAAC,CAAA;IACzH,IAAA,6BAAW,EAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAA;IAC9B,KAAK,MAAM,QAAQ,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAA;QACxD,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,YAAY,QAAQ,CAAC,IAAI,wBAAwB,CAAC,CAAA;QACtG,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,OAAO,QAAQ,CAAC,IAAI,iDAAiD,CAAC,CAAA;IAC1J,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,eAAe,GAAG,CAAC,IAAI,kCAAkC,CAAC,CAAA;QACvK,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,IAAI,SAAS,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAA;IAC9H,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;AACjC,CAAC;AAED,SAAgB,YAAY,CAAC,GAAuB;IAClD,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC3C,CAAC;AAED,uHAAuH;AACvH,SAAgB,YAAY,CAAC,MAAkB,EAAE,IAAS;IACxD,MAAM,QAAQ,GAA4B,EAAE,CAAA;IAC5C,MAAM,OAAO,GAAqC,EAAE,CAAA;IACpD,8FAA8F;IAC9F,IAAI,OAAO,IAAI,EAAE,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;IAChF,IAAI,MAAM,CAAC,MAAM,IAAI,OAAO,IAAI,EAAE,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;IACzG,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACpC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,SAAQ;QACnE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAA,gCAAc,EAAC,SAAuB,EAAE,KAAK,CAAC,CAAA;QACrE,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,YAAY,EAAE,CAAC,CAAA;;YACrF,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtC,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;AAC9B,CAAC;AAED,SAAgB,SAAS,CAAC,MAAkB,EAAE,QAAiC;IAC7E,OAAO;QACL,GAAG,CAAC,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChG,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CACrC,SAAS,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CACtF;KACF,CAAA;AACH,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,GAAQ,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AAE/I,yFAAyF;AACzF,SAAgB,KAAK,CAAC,MAAkB,EAAE,IAAS;IACjD,OAAO,MAAM,CAAC,WAAW,CAAC;QACxB,8FAA8F;QAC9F,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAqB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;YACrD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE;gBAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAC/E,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;gBAC1B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAC/D,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QACnC,CAAC,CAAC;KACH,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,QAAQ,CAAC,MAAkB,EAAE,OAAqB,EAAE,GAAkB,EAAE,MAAe;IAC3G,MAAM,IAAI,GAA0B,EAAE,CAAA;IACtC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,qBAAa,EAAE,IAAI,EAAE,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE;YACrC,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAS,EAAE;YACtC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1D,CAAC,CAAA;QACF,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC5F,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACvC,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAChC,MAAM,KAAK,GAAG,IAAI,EAAE,IAAI,IAAI,EAAE,CAAA;QAC9B,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAa,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1F,IAAI,KAAK,CAAC,MAAM,GAAG,iBAAS,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK;YAAE,MAAK;IAC7D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAA;AACxD,CAAC;AAWD,wGAAwG;AAC3F,QAAA,gBAAgB,GAAG,SAAS,CAAA;AAEzC,MAAM,KAAK,GAAG,CAAC,IAA2B,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAA;AAExK,4HAA4H;AAC5H,SAAgB,MAAM,CAAC,MAAkB,EAAE,IAA2B;IACpE,MAAM,IAAI,GAA4B,EAAE,CAAA;IACxC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;QACtF,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;YAC5C,SAAQ;QACV,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAiC,CAAA;QAC3D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,wBAAgB,CAAA;YACvH,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QAC9D,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAC9J,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,kGAAkG;AAClG,SAAgB,YAAY,CAAC,IAA+B,EAAE,MAAc;IAC1E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ;YAAE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAW,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAClJ,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;AAC1B,CAAC;AAED,iHAAiH;AACjH,SAAgB,QAAQ,CAAC,MAAkB,EAAE,IAA2B,EAAE,EAAU;IAClF,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAA;IAC1D,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAiC,CAAA;IACvD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,CAAA;QACrB,MAAM,GAAG,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC3H,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;IACpD,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;IACjH,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAClF,sHAAsH;IACtH,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAA;IACzD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7E,MAAM,IAAI,GAAG,CAAC,KAAgB,EAAE,EAAE;QAChC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACjD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACvH,CAAC,CAAA;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QACjC,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAA;IAC5F,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,4GAA4G;AAC5G,SAAgB,aAAa,CAAC,MAAkB,EAAE,QAAiC;IACjF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC5B,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAC7B,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;IACpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAAE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAC/J,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACnC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC/G,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU;QAC7B,CAAC,CAAC,IAAA,+BAAe,EAAC;YACd,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;YACtC,MAAM,EAAE,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YACzE,OAAO,EAAE,MAAM,CAAC,QAAQ;SACzB,CAAC;QACJ,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAA;IACrB,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;QACvD,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1D,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;KAC/D,CAAA;AACH,CAAC","sourcesContent":["/*\n * AI 조회 - an application's list, read through its own query as the person (operato-application/design/ai/read-targets.md).\n *\n * The application declares what it lets the assistant read: its list query, the conditions the model may set and\n * how each becomes one of the query's filters, the columns to show, and the screen that lists the same records.\n * The framework reads the rows through that query with the person's request state - the same @privilege and\n * domain as the screen - counts and sums them itself, and puts a long result on the AI 작업판 as the query returned\n * it. The model is told the count, the sums and a few rows; it never copies a table.\n *\n * Pure but for the GraphQL runner, which comes in as an argument - the rules are tested without a server.\n */\nimport { readFieldValue, rootFieldOf, type EntryField } from '../data-entry/entry-target.js'\nimport { encodeListQuery } from '@operato/utils/list-query.js'\nimport type { GraphqlRunner } from '../data-entry/entry-update.js'\nimport { parse } from 'graphql'\n\nexport interface ReadFilter {\n name: string\n operator: string\n value: unknown\n}\n\n/** A condition the model may set - read with the entry fields' rules, turned into the query's filters by the application. */\nexport interface ReadCriterion extends Omit<EntryField, 'required' | 'reference' | 'total'> {\n filter: (value: any) => ReadFilter | ReadFilter[]\n}\n\nexport interface ReadColumn {\n /** The key in the workspace table. */\n name: string\n /** Where the value is in a row - a dotted path into the query's item (`account.name`). Defaults to `name`. */\n path?: string\n type: 'string' | 'number' | 'date'\n labelKey?: string\n /** A number column the server sums. */\n total?: boolean\n /**\n * The column that holds this amount's currency (ISO 4217, `KRW`). Its sums are kept per currency - amounts of two\n * currencies are never added into one number.\n */\n currency?: string\n}\n\nexport interface ReadScreen {\n /** A URL-bound grid accepts the same predicates used by readRows, including conditions outside its form. */\n queryState?: boolean\n /** The application's route of the list screen (`cash-transaction-list`). */\n route: string\n /** The conditions the screen takes, as its address's query arguments. A condition left out is said on the card. */\n params: (criteria: Record<string, any>) => Record<string, string | number | undefined>\n /** The conditions `params` carries - the card names the others as not applied on the screen. */\n takes: string[]\n labelKey?: string\n}\n\nexport interface ReadTarget {\n /** `<app>.<record>` - the tools are named after it. */\n key: string\n /** i18n key naming the records (「은행 입출금」). */\n labelKey?: string\n /** What the records are, for the model. */\n description: string\n /**\n * The list query - takes `$filters: [Filter!]`, `$pagination: Pagination` and `$sortings: [Sorting!]`, and\n * `$search: String` when `search` is declared.\n */\n query: string\n /**\n * The list takes ListParam's free-text term, matched by the resolver across its own searchable fields - the\n * condition `text`. Say what it finds in, for the model.\n */\n search?: { description: string }\n criteria: ReadCriterion[]\n /**\n * Filters every read of this list applies - the records it is of (a book's confirmed lines, not its forecasts). Not\n * a condition: the model neither sees nor sets them, so a read can narrow the list but never widen it.\n */\n fixedFilters?: ReadFilter[]\n columns: ReadColumn[]\n rowsOf: (data: any) => { rows: any[]; total: number }\n /** Orders the rows; the query's own order when left out. */\n sortings?: { name: string; desc?: boolean }[]\n screen?: ReadScreen\n}\n\n/** At most this many rows are read - the AI 작업판 table's own limit (workspace-blocks MAX_TABLE_ROWS). */\nexport const MAX_READ_ROWS = 1000\n/** Rows the model is shown; the rest stay on the card. */\nexport const ROWS_FOR_MODEL = 20\n/** A page of the list query. */\nexport const READ_PAGE = 200\n\nconst registry = new Map<string, ReadTarget>()\n\nconst pascalOf = (key: string) =>\n key\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map(part => part[0].toUpperCase() + part.slice(1))\n .join('')\n\nexport const queryToolName = (key: string) => `query${pascalOf(key)}`\nexport const screenToolName = (key: string) => `open${pascalOf(key)}Screen`\nexport const readCategoryName = (key: string) => `data-read:${key}`\n\nexport function declareReadTarget(target: ReadTarget): void {\n if (!/^[a-z0-9-]+\\.[a-z0-9-]+$/.test(target.key)) throw new Error(`read target key '${target.key}' is not <app>.<record>`)\n if (registry.has(target.key) || details.has(target.key)) throw new Error(`read target '${target.key}' is declared twice`)\n rootFieldOf(target.query, 'query')\n if (!target.columns.length) throw new Error(`read target '${target.key}' shows no column`)\n for (const column of target.columns.filter(one => one.currency)) {\n if (!column.total || column.type !== 'number') throw new Error(`column '${column.name}' of '${target.key}' names a currency but is not a summed number`)\n if (target.columns.find(one => one.name === column.currency)?.type !== 'string') throw new Error(`column '${column.name}' of '${target.key}' takes its currency from '${column.currency}', which is no string column`)\n }\n const names = new Set<string>(['id'])\n for (const criterion of target.criteria) {\n if (criterion.name === 'id') throw new Error(`read target '${target.key}' declares 'id' - every target takes it`)\n if (criterion.name === 'text' && target.search) throw new Error(`read target '${target.key}' declares 'text' and search - search is the text condition`)\n if (names.has(criterion.name)) throw new Error(`read target '${target.key}' names the condition '${criterion.name}' twice`)\n names.add(criterion.name)\n if (criterion.type === 'enum' && !criterion.values?.length) throw new Error(`condition '${criterion.name}' of '${target.key}' lists no values`)\n }\n if (target.search) names.add('text')\n for (const taken of target.screen?.takes ?? []) if (!names.has(taken)) throw new Error(`the screen of '${target.key}' takes '${taken}', which is no condition`)\n registry.set(target.key, target)\n}\n\nexport function readTargetOf(key: string | undefined): ReadTarget | undefined {\n return key ? registry.get(key) : undefined\n}\n\nexport function clearReadTargets(): void {\n registry.clear()\n details.clear()\n}\n\n/* ── One answer of a query ──────────────────────────────────────────────────────────────────────────────────── */\n\n/** An argument of a detail read - one variable of its query, read with the entry fields' rules. */\nexport interface DetailArg {\n name: string\n type: 'string' | 'integer' | 'number' | 'boolean' | 'date' | 'enum'\n values?: string[]\n description?: string\n required?: boolean\n}\n\n/**\n * A query whose answer is one thing, not a list - a 360's summary, the receivables, a statement (design/ai/read-targets.md\n * §9). The application declares the query with the fields its screen reads; the framework runs it as the person, with\n * the arguments the model set, and hands the answer over as the query returned it. Nothing is summed or cut here: the\n * selection is the projection, and an answer too long to hand over is refused, never cut.\n */\nexport interface DetailRead {\n /** `<app>.<thing>` - the tool is named after it. */\n key: string\n labelKey?: string\n /** What it answers, for the model. */\n description: string\n /** One query with one root field. Its variables are the arguments - each declared in `args`. */\n query: string\n args?: DetailArg[]\n}\n\n/** Characters of an answer handed to the model - a longer one is refused, and the model narrows it. */\nexport const MAX_DETAIL_CHARS = 60_000\n\nconst details = new Map<string, DetailRead>()\n\nexport const detailToolName = (key: string) => `read${pascalOf(key)}`\n\n/** The variables a query declares, and whether each is required (`!`). */\nfunction variablesOf(document: string): { name: string; required: boolean }[] {\n const operation: any = parse(document).definitions.find((one: any) => one.kind === 'OperationDefinition')\n return (operation?.variableDefinitions ?? []).map((one: any) => ({ name: one.variable.name.value, required: one.type.kind === 'NonNullType' && !one.defaultValue }))\n}\n\nexport function declareDetailRead(target: DetailRead): void {\n if (!/^[a-z0-9-]+\\.[a-z0-9-]+$/.test(target.key)) throw new Error(`detail read key '${target.key}' is not <app>.<thing>`)\n if (details.has(target.key) || registry.has(target.key)) throw new Error(`read target '${target.key}' is declared twice`)\n rootFieldOf(target.query, 'query')\n const args = target.args ?? []\n for (const variable of variablesOf(target.query)) {\n const arg = args.find(one => one.name === variable.name)\n if (!arg) throw new Error(`detail read '${target.key}' takes $${variable.name}, which is no argument`)\n if (variable.required && !arg.required) throw new Error(`detail read '${target.key}': $${variable.name} is required by the query - declare it required`)\n }\n for (const arg of args) {\n if (!variablesOf(target.query).some(one => one.name === arg.name)) throw new Error(`detail read '${target.key}' declares '${arg.name}', which its query does not take`)\n if (arg.type === 'enum' && !arg.values?.length) throw new Error(`argument '${arg.name}' of '${target.key}' lists no values`)\n }\n details.set(target.key, target)\n}\n\nexport function detailReadOf(key: string | undefined): DetailRead | undefined {\n return key ? details.get(key) : undefined\n}\n\n/** The conditions the model set, read by their declared types; a value that does not fit is said, never guessed at. */\nexport function readCriteria(target: ReadTarget, args: any): { criteria: Record<string, unknown>; refused: { name: string; code: string }[] } {\n const criteria: Record<string, unknown> = {}\n const refused: { name: string; code: string }[] = []\n /* One record by its id - every target takes it (the id a list answer or a find tool gave). */\n if (typeof args?.id === 'string' && args.id.trim()) criteria.id = args.id.trim()\n if (target.search && typeof args?.text === 'string' && args.text.trim()) criteria.text = args.text.trim()\n for (const criterion of target.criteria) {\n const value = args?.[criterion.name]\n if (value === undefined || value === null || value === '') continue\n const { read, code } = readFieldValue(criterion as EntryField, value)\n if (read === undefined) refused.push({ name: criterion.name, code: code ?? 'unreadable' })\n else criteria[criterion.name] = read\n }\n return { criteria, refused }\n}\n\nexport function filtersOf(target: ReadTarget, criteria: Record<string, unknown>): ReadFilter[] {\n return [\n ...(typeof criteria.id === 'string' ? [{ name: 'id', operator: 'eq', value: criteria.id }] : []),\n ...target.criteria.flatMap(criterion =>\n criterion.name in criteria ? [criterion.filter(criteria[criterion.name])].flat() : []\n )\n ]\n}\n\nconst valueAt = (row: any, path: string) => path.split('.').reduce((at, part) => (at === null || at === undefined ? undefined : at[part]), row)\n\n/** One row as the columns say - a number column as a number, a missing value as null. */\nexport function rowOf(target: ReadTarget, item: any): Record<string, string | number | null> {\n return Object.fromEntries([\n /* The id names the record to the model - for one record's detail, a change, or its screen. */\n ...(item?.id ? [['id', String(item.id)] as [string, string]] : []),\n ...target.columns.map(column => {\n const raw = valueAt(item, column.path ?? column.name)\n if (raw === undefined || raw === null || raw === '') return [column.name, null]\n if (column.type === 'number') {\n const number = Number(raw)\n return [column.name, Number.isFinite(number) ? number : null]\n }\n return [column.name, String(raw)]\n })\n ])\n}\n\n/**\n * Reads the rows through the application's query, page by page, up to MAX_READ_ROWS. `complete` is false when the\n * list holds more - a sum of the rows read is then not the sum of the list, and is never said as one.\n */\nexport async function readRows(target: ReadTarget, filters: ReadFilter[], run: GraphqlRunner, search?: string): Promise<{ rows: Record<string, any>[]; total: number; complete: boolean }> {\n const rows: Record<string, any>[] = []\n let total = 0\n for (let page = 1; rows.length < MAX_READ_ROWS; page++) {\n const answer = await run(target.query, {\n filters: [...filters, ...(target.fixedFilters ?? [])],\n ...(search ? { search } : {}),\n pagination: { page, limit: READ_PAGE },\n ...(target.sortings ? { sortings: target.sortings } : {})\n })\n if (answer.errors?.length) throw new Error(answer.errors.map(one => one.message).join('; '))\n const read = target.rowsOf(answer.data)\n total = Number(read?.total) || 0\n const items = read?.rows ?? []\n rows.push(...items.slice(0, MAX_READ_ROWS - rows.length).map(item => rowOf(target, item)))\n if (items.length < READ_PAGE || rows.length >= total) break\n }\n return { rows, total, complete: rows.length >= total }\n}\n\n/** A column's sum - one number, or one per currency when the column names its currency (`{ KRW: 1000, USD: 100 }`). */\nexport type ReadSum = number | Record<string, number>\n\nexport interface ReadGroup {\n key: string\n count: number\n sums: Record<string, ReadSum>\n}\n\n/** The currency a row without one is summed under - said as it is, never taken for the domain's own. */\nexport const UNKNOWN_CURRENCY = 'unknown'\n\nconst sumOf = (rows: Record<string, any>[], name: string) => Math.round(rows.reduce((sum, row) => sum + (typeof row[name] === 'number' ? row[name] : 0), 0) * 100) / 100\n\n/** The sums of the number columns marked total - the server's, never the model's; a column with a currency per currency. */\nexport function sumsOf(target: ReadTarget, rows: Record<string, any>[]): Record<string, ReadSum> {\n const sums: Record<string, ReadSum> = {}\n for (const column of target.columns.filter(one => one.total && one.type === 'number')) {\n if (!column.currency) {\n sums[column.name] = sumOf(rows, column.name)\n continue\n }\n const byCurrency = new Map<string, Record<string, any>[]>()\n for (const row of rows) {\n const code = typeof row[column.currency] === 'string' && row[column.currency] ? row[column.currency] : UNKNOWN_CURRENCY\n byCurrency.set(code, [...(byCurrency.get(code) ?? []), row])\n }\n sums[column.name] = Object.fromEntries([...byCurrency].sort(([a], [b]) => a.localeCompare(b)).map(([code, members]) => [code, sumOf(members, column.name)]))\n }\n return sums\n}\n\n/** The currencies a set of sums holds for one column - none for a column summed as one number. */\nexport function currenciesOf(sums: Record<string, ReadSum>[], column: string): string[] {\n const codes = new Set<string>()\n for (const one of sums) if (one[column] && typeof one[column] === 'object') for (const code of Object.keys(one[column] as object)) codes.add(code)\n return [...codes].sort()\n}\n\n/** The rows grouped by one column - a date column by its month - each with its count and sums, largest first. */\nexport function groupsOf(target: ReadTarget, rows: Record<string, any>[], by: string): ReadGroup[] | undefined {\n const column = target.columns.find(one => one.name === by)\n if (!column) return undefined\n const groups = new Map<string, Record<string, any>[]>()\n for (const row of rows) {\n const value = row[by]\n const key = value === null || value === undefined ? '' : column.type === 'date' ? String(value).slice(0, 7) : String(value)\n groups.set(key, [...(groups.get(key) ?? []), row])\n }\n const list = [...groups].map(([key, members]) => ({ key, count: members.length, sums: sumsOf(target, members) }))\n if (column.type === 'date') return list.sort((a, b) => a.key.localeCompare(b.key))\n /* Largest first by the first sum - in its one currency; groups in two currencies have no common size, so by count. */\n const first = target.columns.find(one => one.total)?.name\n const codes = first ? currenciesOf(list.map(group => group.sums), first) : []\n const size = (group: ReadGroup) => {\n const sum = first ? group.sums[first] : undefined\n return typeof sum === 'number' ? Math.abs(sum) : codes.length === 1 && sum ? Math.abs(sum[codes[0]] ?? 0) : undefined\n }\n return list.sort((a, b) => {\n const [x, y] = [size(a), size(b)]\n return x !== undefined && y !== undefined && codes.length <= 1 ? y - x : b.count - a.count\n })\n}\n\n/** The address of the target's list screen with the conditions it takes, and the conditions it does not. */\nexport function screenAddress(target: ReadTarget, criteria: Record<string, unknown>): { href: string; applied: string[]; notApplied: string[] } | undefined {\n const screen = target.screen\n if (!screen) return undefined\n const params = new URLSearchParams()\n for (const [name, value] of Object.entries(screen.params(criteria))) if (value !== undefined && value !== null && value !== '') params.set(name, String(value))\n const given = Object.keys(criteria)\n const applicable = Object.fromEntries(Object.entries(criteria).filter(([name]) => screen.takes.includes(name)))\n const query = screen.queryState\n ? encodeListQuery({\n filters: filtersOf(target, applicable),\n search: typeof applicable.text === 'string' ? applicable.text : undefined,\n sorters: target.sortings\n })\n : params.toString()\n return {\n href: query ? `${screen.route}?${query}` : screen.route,\n applied: given.filter(name => screen.takes.includes(name)),\n notApplied: given.filter(name => !screen.takes.includes(name))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"read-target.js","sourceRoot":"","sources":["../../../server/service/data-read/read-target.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * AI 조회 - an application's list, read through its own query as the person (operato-application/design/ai/read-targets.md).\n *\n * The application declares what it lets the assistant read: its list query, the conditions the model may set and\n * how each becomes one of the query's filters, the columns to show, and the screen that lists the same records.\n * The framework reads the rows through that query with the person's request state - the same @privilege and\n * domain as the screen - counts and sums them itself, and puts a long result on the AI 작업판 as the query returned\n * it. The model is told the count, the sums and a few rows; it never copies a table.\n *\n * Pure but for the GraphQL runner, which comes in as an argument - the rules are tested without a server.\n */\nimport { readFieldValue, recordIdOfKey, rootFieldOf, type EntryField } from '../data-entry/entry-target.js'\nimport { encodeListQuery } from '@operato/utils/list-query.js'\nimport type { GraphqlRunner } from '../data-entry/entry-update.js'\nimport { parse } from 'graphql'\n\nexport interface ReadFilter {\n name: string\n operator: string\n value: unknown\n}\n\n/** A condition the model may set - read with the entry fields' rules, turned into the query's filters by the application. */\nexport interface ReadCriterion extends Omit<EntryField, 'required' | 'reference' | 'total'> {\n filter: (value: any) => ReadFilter | ReadFilter[]\n}\n\nexport interface ReadColumn {\n /** The key in the workspace table. */\n name: string\n /** Where the value is in a row - a dotted path into the query's item (`account.name`). Defaults to `name`. */\n path?: string\n type: 'string' | 'number' | 'date'\n labelKey?: string\n /** A number column the server sums. */\n total?: boolean\n /**\n * The column that holds this amount's currency (ISO 4217, `KRW`). Its sums are kept per currency - amounts of two\n * currencies are never added into one number.\n */\n currency?: string\n}\n\nexport interface ReadScreen {\n /** A URL-bound grid accepts the same predicates used by readRows, including conditions outside its form. */\n queryState?: boolean\n /** The application's route of the list screen (`cash-transaction-list`). */\n route: string\n /** The conditions the screen takes, as its address's query arguments. A condition left out is said on the card. */\n params: (criteria: Record<string, any>) => Record<string, string | number | undefined>\n /** The conditions `params` carries - the card names the others as not applied on the screen. */\n takes: string[]\n labelKey?: string\n}\n\nexport interface ReadTarget {\n /** `<app>.<record>` - the tools are named after it. */\n key: string\n /** i18n key naming the records (「은행 입출금」). */\n labelKey?: string\n /** What the records are, for the model. */\n description: string\n /**\n * The list query - takes `$filters: [Filter!]`, `$pagination: Pagination` and `$sortings: [Sorting!]`, and\n * `$search: String` when `search` is declared.\n */\n query: string\n /**\n * The list takes ListParam's free-text term, matched by the resolver across its own searchable fields - the\n * condition `text`. Say what it finds in, for the model.\n */\n search?: { description: string }\n criteria: ReadCriterion[]\n /**\n * Filters every read of this list applies - the records it is of (a book's confirmed lines, not its forecasts). Not\n * a condition: the model neither sees nor sets them, so a read can narrow the list but never widen it.\n */\n fixedFilters?: ReadFilter[]\n columns: ReadColumn[]\n rowsOf: (data: any) => { rows: any[]; total: number }\n /** Orders the rows; the query's own order when left out. */\n sortings?: { name: string; desc?: boolean }[]\n screen?: ReadScreen\n}\n\n/** At most this many rows are read - the AI 작업판 table's own limit (workspace-blocks MAX_TABLE_ROWS). */\nexport const MAX_READ_ROWS = 1000\n/** Rows the model is shown; the rest stay on the card. */\nexport const ROWS_FOR_MODEL = 20\n/** A page of the list query. */\nexport const READ_PAGE = 200\n\nconst registry = new Map<string, ReadTarget>()\n\nconst pascalOf = (key: string) =>\n key\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map(part => part[0].toUpperCase() + part.slice(1))\n .join('')\n\nexport const queryToolName = (key: string) => `query${pascalOf(key)}`\nexport const screenToolName = (key: string) => `open${pascalOf(key)}Screen`\nexport const readCategoryName = (key: string) => `data-read:${key}`\n\nexport function declareReadTarget(target: ReadTarget): void {\n if (!/^[a-z0-9-]+\\.[a-z0-9-]+$/.test(target.key)) throw new Error(`read target key '${target.key}' is not <app>.<record>`)\n if (registry.has(target.key) || details.has(target.key)) throw new Error(`read target '${target.key}' is declared twice`)\n rootFieldOf(target.query, 'query')\n if (!target.columns.length) throw new Error(`read target '${target.key}' shows no column`)\n for (const column of target.columns.filter(one => one.currency)) {\n if (!column.total || column.type !== 'number') throw new Error(`column '${column.name}' of '${target.key}' names a currency but is not a summed number`)\n if (target.columns.find(one => one.name === column.currency)?.type !== 'string') throw new Error(`column '${column.name}' of '${target.key}' takes its currency from '${column.currency}', which is no string column`)\n }\n const names = new Set<string>(['id'])\n for (const criterion of target.criteria) {\n if (criterion.name === 'id') throw new Error(`read target '${target.key}' declares 'id' - every target takes it`)\n if (criterion.name === 'text' && target.search) throw new Error(`read target '${target.key}' declares 'text' and search - search is the text condition`)\n if (names.has(criterion.name)) throw new Error(`read target '${target.key}' names the condition '${criterion.name}' twice`)\n names.add(criterion.name)\n if (criterion.type === 'enum' && !criterion.values?.length) throw new Error(`condition '${criterion.name}' of '${target.key}' lists no values`)\n }\n if (target.search) names.add('text')\n for (const taken of target.screen?.takes ?? []) if (!names.has(taken)) throw new Error(`the screen of '${target.key}' takes '${taken}', which is no condition`)\n registry.set(target.key, target)\n}\n\nexport function readTargetOf(key: string | undefined): ReadTarget | undefined {\n return key ? registry.get(key) : undefined\n}\n\nexport function clearReadTargets(): void {\n registry.clear()\n details.clear()\n}\n\n/* ── One answer of a query ──────────────────────────────────────────────────────────────────────────────────── */\n\n/** An argument of a detail read - one variable of its query, read with the entry fields' rules. */\nexport interface DetailArg {\n name: string\n type: 'string' | 'integer' | 'number' | 'boolean' | 'date' | 'enum'\n values?: string[]\n description?: string\n required?: boolean\n /** A record's id: the axis (or axes) of the record, whose key `<axis>:<id>` the model may have been shown (EntryField.axis). */\n axis?: string | readonly string[]\n}\n\n/**\n * A query whose answer is one thing, not a list - a 360's summary, the receivables, a statement (design/ai/read-targets.md\n * §9). The application declares the query with the fields its screen reads; the framework runs it as the person, with\n * the arguments the model set, and hands the answer over as the query returned it. Nothing is summed or cut here: the\n * selection is the projection, and an answer too long to hand over is refused, never cut.\n */\nexport interface DetailRead {\n /** `<app>.<thing>` - the tool is named after it. */\n key: string\n labelKey?: string\n /** What it answers, for the model. */\n description: string\n /** One query with one root field. Its variables are the arguments - each declared in `args`. */\n query: string\n args?: DetailArg[]\n /**\n * The records the answer is about, whose screens put it in front (EntryTarget.axes) - the management check answers\n * for any ledger record; asked on a deposit's 360 why it was in the check, the model never opened it (2026-10-24).\n */\n axes?: string[]\n}\n\n/** Characters of an answer handed to the model - a longer one is refused, and the model narrows it. */\nexport const MAX_DETAIL_CHARS = 60_000\n\nconst details = new Map<string, DetailRead>()\n\nexport const detailToolName = (key: string) => `read${pascalOf(key)}`\n\n/** The variables a query declares, and whether each is required (`!`). */\nfunction variablesOf(document: string): { name: string; required: boolean }[] {\n const operation: any = parse(document).definitions.find((one: any) => one.kind === 'OperationDefinition')\n return (operation?.variableDefinitions ?? []).map((one: any) => ({ name: one.variable.name.value, required: one.type.kind === 'NonNullType' && !one.defaultValue }))\n}\n\nexport function declareDetailRead(target: DetailRead): void {\n if (!/^[a-z0-9-]+\\.[a-z0-9-]+$/.test(target.key)) throw new Error(`detail read key '${target.key}' is not <app>.<thing>`)\n if (details.has(target.key) || registry.has(target.key)) throw new Error(`read target '${target.key}' is declared twice`)\n rootFieldOf(target.query, 'query')\n const args = target.args ?? []\n for (const variable of variablesOf(target.query)) {\n const arg = args.find(one => one.name === variable.name)\n if (!arg) throw new Error(`detail read '${target.key}' takes $${variable.name}, which is no argument`)\n if (variable.required && !arg.required) throw new Error(`detail read '${target.key}': $${variable.name} is required by the query - declare it required`)\n }\n for (const arg of args) {\n if (!variablesOf(target.query).some(one => one.name === arg.name)) throw new Error(`detail read '${target.key}' declares '${arg.name}', which its query does not take`)\n if (arg.type === 'enum' && !arg.values?.length) throw new Error(`argument '${arg.name}' of '${target.key}' lists no values`)\n }\n details.set(target.key, target)\n}\n\nexport function detailReadOf(key: string | undefined): DetailRead | undefined {\n return key ? details.get(key) : undefined\n}\n\n/** The conditions the model set, read by their declared types; a value that does not fit is said, never guessed at. */\nexport function readCriteria(target: ReadTarget, args: any): { criteria: Record<string, unknown>; refused: { name: string; code: string }[] } {\n const criteria: Record<string, unknown> = {}\n const refused: { name: string; code: string }[] = []\n /* One record by its id - every target takes it (the id a list answer or a find tool gave, or the key `<axis>:<id>` an open record is shown by, the axis being the key's last part). */\n if (typeof args?.id === 'string' && args.id.trim()) criteria.id = recordIdOfKey(target.key.split('.').pop()!, args.id) ?? args.id.trim()\n if (target.search && typeof args?.text === 'string' && args.text.trim()) criteria.text = args.text.trim()\n for (const criterion of target.criteria) {\n const value = args?.[criterion.name]\n if (value === undefined || value === null || value === '') continue\n const { read, code } = readFieldValue(criterion as EntryField, value)\n if (read === undefined) refused.push({ name: criterion.name, code: code ?? 'unreadable' })\n else criteria[criterion.name] = read\n }\n return { criteria, refused }\n}\n\nexport function filtersOf(target: ReadTarget, criteria: Record<string, unknown>): ReadFilter[] {\n return [\n ...(typeof criteria.id === 'string' ? [{ name: 'id', operator: 'eq', value: criteria.id }] : []),\n ...target.criteria.flatMap(criterion =>\n criterion.name in criteria ? [criterion.filter(criteria[criterion.name])].flat() : []\n )\n ]\n}\n\nconst valueAt = (row: any, path: string) => path.split('.').reduce((at, part) => (at === null || at === undefined ? undefined : at[part]), row)\n\n/** One row as the columns say - a number column as a number, a missing value as null. */\nexport function rowOf(target: ReadTarget, item: any): Record<string, string | number | null> {\n return Object.fromEntries([\n /* The id names the record to the model - for one record's detail, a change, or its screen. */\n ...(item?.id ? [['id', String(item.id)] as [string, string]] : []),\n ...target.columns.map(column => {\n const raw = valueAt(item, column.path ?? column.name)\n if (raw === undefined || raw === null || raw === '') return [column.name, null]\n if (column.type === 'number') {\n const number = Number(raw)\n return [column.name, Number.isFinite(number) ? number : null]\n }\n return [column.name, String(raw)]\n })\n ])\n}\n\n/**\n * Reads the rows through the application's query, page by page, up to MAX_READ_ROWS. `complete` is false when the\n * list holds more - a sum of the rows read is then not the sum of the list, and is never said as one.\n */\nexport async function readRows(target: ReadTarget, filters: ReadFilter[], run: GraphqlRunner, search?: string): Promise<{ rows: Record<string, any>[]; total: number; complete: boolean }> {\n const rows: Record<string, any>[] = []\n let total = 0\n for (let page = 1; rows.length < MAX_READ_ROWS; page++) {\n const answer = await run(target.query, {\n filters: [...filters, ...(target.fixedFilters ?? [])],\n ...(search ? { search } : {}),\n pagination: { page, limit: READ_PAGE },\n ...(target.sortings ? { sortings: target.sortings } : {})\n })\n if (answer.errors?.length) throw new Error(answer.errors.map(one => one.message).join('; '))\n const read = target.rowsOf(answer.data)\n total = Number(read?.total) || 0\n const items = read?.rows ?? []\n rows.push(...items.slice(0, MAX_READ_ROWS - rows.length).map(item => rowOf(target, item)))\n if (items.length < READ_PAGE || rows.length >= total) break\n }\n return { rows, total, complete: rows.length >= total }\n}\n\n/** A column's sum - one number, or one per currency when the column names its currency (`{ KRW: 1000, USD: 100 }`). */\nexport type ReadSum = number | Record<string, number>\n\nexport interface ReadGroup {\n key: string\n count: number\n sums: Record<string, ReadSum>\n}\n\n/** The currency a row without one is summed under - said as it is, never taken for the domain's own. */\nexport const UNKNOWN_CURRENCY = 'unknown'\n\nconst sumOf = (rows: Record<string, any>[], name: string) => Math.round(rows.reduce((sum, row) => sum + (typeof row[name] === 'number' ? row[name] : 0), 0) * 100) / 100\n\n/** The sums of the number columns marked total - the server's, never the model's; a column with a currency per currency. */\nexport function sumsOf(target: ReadTarget, rows: Record<string, any>[]): Record<string, ReadSum> {\n const sums: Record<string, ReadSum> = {}\n for (const column of target.columns.filter(one => one.total && one.type === 'number')) {\n if (!column.currency) {\n sums[column.name] = sumOf(rows, column.name)\n continue\n }\n const byCurrency = new Map<string, Record<string, any>[]>()\n for (const row of rows) {\n const code = typeof row[column.currency] === 'string' && row[column.currency] ? row[column.currency] : UNKNOWN_CURRENCY\n byCurrency.set(code, [...(byCurrency.get(code) ?? []), row])\n }\n sums[column.name] = Object.fromEntries([...byCurrency].sort(([a], [b]) => a.localeCompare(b)).map(([code, members]) => [code, sumOf(members, column.name)]))\n }\n return sums\n}\n\n/** The currencies a set of sums holds for one column - none for a column summed as one number. */\nexport function currenciesOf(sums: Record<string, ReadSum>[], column: string): string[] {\n const codes = new Set<string>()\n for (const one of sums) if (one[column] && typeof one[column] === 'object') for (const code of Object.keys(one[column] as object)) codes.add(code)\n return [...codes].sort()\n}\n\n/** The rows grouped by one column - a date column by its month - each with its count and sums, largest first. */\nexport function groupsOf(target: ReadTarget, rows: Record<string, any>[], by: string): ReadGroup[] | undefined {\n const column = target.columns.find(one => one.name === by)\n if (!column) return undefined\n const groups = new Map<string, Record<string, any>[]>()\n for (const row of rows) {\n const value = row[by]\n const key = value === null || value === undefined ? '' : column.type === 'date' ? String(value).slice(0, 7) : String(value)\n groups.set(key, [...(groups.get(key) ?? []), row])\n }\n const list = [...groups].map(([key, members]) => ({ key, count: members.length, sums: sumsOf(target, members) }))\n if (column.type === 'date') return list.sort((a, b) => a.key.localeCompare(b.key))\n /* Largest first by the first sum - in its one currency; groups in two currencies have no common size, so by count. */\n const first = target.columns.find(one => one.total)?.name\n const codes = first ? currenciesOf(list.map(group => group.sums), first) : []\n const size = (group: ReadGroup) => {\n const sum = first ? group.sums[first] : undefined\n return typeof sum === 'number' ? Math.abs(sum) : codes.length === 1 && sum ? Math.abs(sum[codes[0]] ?? 0) : undefined\n }\n return list.sort((a, b) => {\n const [x, y] = [size(a), size(b)]\n return x !== undefined && y !== undefined && codes.length <= 1 ? y - x : b.count - a.count\n })\n}\n\n/** The address of the target's list screen with the conditions it takes, and the conditions it does not. */\nexport function screenAddress(target: ReadTarget, criteria: Record<string, unknown>): { href: string; applied: string[]; notApplied: string[] } | undefined {\n const screen = target.screen\n if (!screen) return undefined\n const params = new URLSearchParams()\n for (const [name, value] of Object.entries(screen.params(criteria))) if (value !== undefined && value !== null && value !== '') params.set(name, String(value))\n const given = Object.keys(criteria)\n const applicable = Object.fromEntries(Object.entries(criteria).filter(([name]) => screen.takes.includes(name)))\n const query = screen.queryState\n ? encodeListQuery({\n filters: filtersOf(target, applicable),\n search: typeof applicable.text === 'string' ? applicable.text : undefined,\n sorters: target.sortings\n })\n : params.toString()\n return {\n href: query ? `${screen.route}?${query}` : screen.route,\n applied: given.filter(name => screen.takes.includes(name)),\n notApplied: given.filter(name => !screen.takes.includes(name))\n }\n}\n"]}
|
|
@@ -225,7 +225,7 @@ async function queryDetail(target, args, run) {
|
|
|
225
225
|
refused.push({ name: arg.name, code: 'required' });
|
|
226
226
|
continue;
|
|
227
227
|
}
|
|
228
|
-
const { read, code } = (0, entry_target_js_1.readFieldValue)({ name: arg.name, type: arg.type === 'string' ? 'text' : arg.type, values: arg.values }, value);
|
|
228
|
+
const { read, code } = (0, entry_target_js_1.readFieldValue)({ name: arg.name, type: arg.type === 'string' ? 'text' : arg.type, values: arg.values, axis: arg.axis }, value);
|
|
229
229
|
if (read === undefined)
|
|
230
230
|
refused.push({ name: arg.name, code: code ?? 'unreadable' });
|
|
231
231
|
else
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-tools.js","sourceRoot":"","sources":["../../../server/service/data-read/read-tools.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The tools of an AI 조회 target (operato-application/design/ai/read-targets.md §4, §5).\n *\n * query<X> reads the rows through the application's list query as the person, and tells the model the count, the\n * sums, the groups and a few rows. A longer result goes on the AI 작업판 as a proposal the server builds from the rows\n * themselves - the table is never written by the model. open<X>Screen reads nothing: it hands the card the address\n * of the application's list screen with the conditions it takes.\n */\nimport { registerToolCategory, type ToolCategory, type ToolSpec } from '@things-factory/ai-client-base'\n\nimport { readFieldValue, rootFieldOf } from '../data-entry/entry-target.js'\nimport type { GraphqlRunner } from '../data-entry/entry-update.js'\nimport { runAsCaller } from '../data-entry/entry-tools.js'\nimport { normalizeWorkspace, workspaceContents } from '../workspace/workspace-blocks.js'\nimport {\n declareReadTarget,\n filtersOf,\n currenciesOf,\n declareDetailRead,\n detailToolName,\n MAX_DETAIL_CHARS,\n type DetailArg,\n type DetailRead,\n groupsOf,\n queryToolName,\n readCategoryName,\n readCriteria,\n readRows,\n ROWS_FOR_MODEL,\n screenAddress,\n screenToolName,\n sumsOf,\n type ReadCriterion,\n type ReadTarget\n} from './read-target.js'\n\n/** The reader's words for a key - the key's own default when the translator has none. */\nconst wordsOf = (context: any) => (key: string | undefined, fallback: string) => {\n if (!key || typeof context?.t !== 'function') return fallback\n try {\n const said = context.t(key)\n return said && said !== key ? String(said) : fallback\n } catch {\n return fallback\n }\n}\n\nfunction criterionSchema(criterion: ReadCriterion): any {\n /* One type per field - Gemini's function schema refuses a list of types (2026-10-01). */\n const type = criterion.type === 'number' ? 'number' : criterion.type === 'integer' ? 'integer' : criterion.type === 'boolean' ? 'boolean' : 'string'\n const said = [criterion.description, criterion.type === 'date' ? 'YYYY-MM-DD' : undefined, criterion.type === 'enum' ? `one of: ${criterion.values!.join(', ')}` : undefined]\n .filter(Boolean)\n .join('. ')\n return { type, ...(said ? { description: said } : {}) }\n}\n\nexport async function queryRecords(target: ReadTarget, args: any, context: any, run: GraphqlRunner) {\n const { criteria, refused } = readCriteria(target, args)\n if (refused.length) {\n return { rejected: true, error: 'condition-unreadable', refused, message: `these conditions do not fit their type: ${refused.map(one => `${one.name} (${one.code})`).join(', ')}. Fix them and call again.` }\n }\n let read\n try {\n read = await readRows(target, filtersOf(target, criteria), run, typeof criteria.text === 'string' && target.search ? criteria.text : undefined)\n } catch (error: any) {\n return { rejected: true, error: 'query-failed', message: `the list could not be read: ${error?.message ?? error}` }\n }\n const { rows, total, complete } = read\n const sums = sumsOf(target, rows)\n const groupBy = typeof args?.groupBy === 'string' && args.groupBy ? args.groupBy : undefined\n const groups = groupBy ? groupsOf(target, rows, groupBy) : undefined\n const words = wordsOf(context)\n const label = words(target.labelKey, target.key)\n\n const said = {\n target: target.key,\n criteria,\n total,\n read: rows.length,\n complete,\n sums,\n ...(groupBy ? (groups ? { groupBy, groups: groups.slice(0, 50), ...(groups.length > 50 ? { moreGroups: groups.length - 50 } : {}) } : { groupBy, groupRefused: 'no such column' }) : {}),\n rows: rows.slice(0, ROWS_FOR_MODEL),\n ...(rows.length > ROWS_FOR_MODEL ? { rowsNotShown: rows.length - ROWS_FOR_MODEL } : {})\n }\n const incomplete = complete\n ? ''\n : ` Only ${rows.length} of ${total} rows were read; the sums and groups are of those rows, not of the list - say so, and ask the person to narrow the conditions.`\n\n if (rows.length === 1 && args?.show !== 'workspace') {\n return { ...said, record: rows[0], message: 'one record - answer from its fields; say a field it does not have as not recorded.' }\n }\n if (rows.length <= ROWS_FOR_MODEL && args?.show !== 'workspace') {\n return { ...said, message: `${rows.length} rows of ${total}.${incomplete} Answer from these rows; every number you say comes from them.` }\n }\n\n /* The workspace is built here from the rows as read - the model never copies the table. */\n const columns = target.columns.map(column => ({ name: column.name, label: words(column.labelKey, column.name), type: column.type }))\n const totalColumns = target.columns.filter(one => one.total)\n /* A sum per currency is one figure and one group column per currency it holds - 「계약금액 (USD)」. */\n const sumColumns = totalColumns.flatMap(column => {\n const label = words(column.labelKey, column.name)\n const codes = currenciesOf([sums, ...(groups ?? []).map(group => group.sums)], column.name)\n return column.currency\n ? codes.map(code => ({ name: `${column.name}:${code}`, label: `${label} (${code})`, of: (one: Record<string, any>) => one[column.name]?.[code] ?? 0 }))\n : [{ name: column.name, label, of: (one: Record<string, any>) => one[column.name] }]\n })\n const title = typeof args?.title === 'string' && args.title.trim() ? args.title.trim() : `${label} · ${rows.length}`\n const { workspace } = normalizeWorkspace({\n name: typeof args?.name === 'string' && args.name ? args.name : target.key.replace(/\\./g, '-'),\n title,\n ...(complete ? {} : { summary: `${total} / ${rows.length}` }),\n blocks: [\n {\n kind: 'metrics',\n items: [{ label: words('ai-assistant.read.count', 'rows'), value: String(rows.length), ...(complete ? {} : { note: `/ ${total}` }) }, ...sumColumns.map(column => ({ label: column.label, value: String(column.of(sums)) }))]\n },\n ...(groups\n ? [\n {\n kind: 'table',\n caption: words(target.columns.find(one => one.name === groupBy)?.labelKey, groupBy!),\n columns: [{ name: 'key', label: words(target.columns.find(one => one.name === groupBy)?.labelKey, groupBy!), type: 'string' }, { name: 'count', label: words('ai-assistant.read.count', 'rows'), type: 'number' }, ...sumColumns.map(column => ({ name: column.name, label: column.label, type: 'number' }))],\n rows: groups.map(group => ({ key: group.key, count: group.count, ...Object.fromEntries(sumColumns.map(column => [column.name, column.of(group.sums)])) }))\n }\n ]\n : []),\n { kind: 'table', caption: label, columns, rows }\n ]\n })\n return {\n proposed: true,\n kind: 'workspace',\n icon: 'table_view',\n label: title,\n ...said,\n forScreen: { workspace, contents: workspaceContents(workspace!) },\n message: `${rows.length} rows of ${total} are on the AI 작업판 as read - the person opens it from the card.${incomplete} Say the point in one or two lines from the sums, groups and rows above; do not write the table out.`\n }\n}\n\nexport function openScreen(target: ReadTarget, args: any, context: any) {\n const { criteria, refused } = readCriteria(target, args)\n if (refused.length) return { rejected: true, error: 'condition-unreadable', refused, message: 'fix the conditions and call again.' }\n const address = screenAddress(target, criteria)\n if (!address) return { rejected: true, error: 'no-screen', message: 'this list has no screen to open.' }\n const words = wordsOf(context)\n return {\n proposed: true,\n kind: 'open-page',\n icon: 'open_in_new',\n label: words(target.screen!.labelKey ?? target.labelKey, target.key),\n target: target.key,\n href: address.href,\n applied: address.applied,\n notApplied: address.notApplied,\n /* The card says them in the reader's words. */\n notAppliedLabels: address.notApplied.map(name => words(target.criteria.find(one => one.name === name)?.labelKey ?? (name === 'text' || name === 'id' ? `ai-assistant.read.${name}` : undefined), name)),\n message:\n 'the card opens the screen when the person presses it.' +\n (address.notApplied.length ? ` The screen does not take ${address.notApplied.join(', ')} - say so.` : '')\n }\n}\n\nexport function readCategoryOf(target: ReadTarget, run: (context: any) => GraphqlRunner = runAsCaller): ToolCategory {\n const door = rootFieldOf(target.query, 'query')\n const conditions = {\n ...Object.fromEntries(target.criteria.map(criterion => [criterion.name, criterionSchema(criterion)])),\n ...(target.search ? { text: { type: 'string', description: `words to find - ${target.search.description}` } } : {})\n }\n const specs: ToolSpec[] = [\n {\n kind: 'read',\n name: queryToolName(target.key),\n /* The person must be able to read the list on its screen - the tool is not a second way in. */\n doors: [door],\n description:\n `Read ${target.description} Set the conditions the question names. Returns the count, the sums, ` +\n `groups when groupBy is given (a date column groups by month) and the first ${ROWS_FOR_MODEL} rows; more rows go on the AI 작업판 as read.`,\n schema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'One record by its id, from an earlier answer - its detail.' },\n ...conditions,\n groupBy: { type: 'string', description: `One column to group by: ${target.columns.map(one => one.name).join(', ')}.` },\n show: { type: 'string', enum: ['answer', 'workspace'], description: 'workspace to put even a short result on the AI 작업판.' },\n title: { type: 'string', description: 'The workspace title, in the person\\'s language.' },\n name: { type: 'string', description: 'The workspace key; the same key again makes a new version.' }\n }\n },\n builder: (args: any, context: any) => queryRecords(target, args, context, run(context))\n } as ToolSpec,\n ...(target.screen\n ? [\n {\n kind: 'read',\n name: screenToolName(target.key),\n doors: [door],\n description: `Offer the person the screen that lists ${target.description} with these conditions. Reads nothing. The screen takes: ${target.screen.takes.join(', ')}.`,\n schema: { type: 'object', properties: conditions },\n builder: (args: any, context: any) => openScreen(target, args, context)\n } as ToolSpec\n ]\n : [])\n ]\n return {\n name: readCategoryName(target.key),\n description: `data read: ${target.key}`,\n guidance: [\n `- To answer from ${target.key} records - a list, or one record found by its name, code or id - call ${queryToolName(target.key)} with the conditions the question names. Every number you say comes from its result - never add up rows yourself; use its sums and groups.`,\n `- A list, a summary by item or month, or a comparison: call it with groupBy, and let a long result go on the AI 작업판 - then answer in one or two lines.`,\n `- When the result says complete: false, say how many of how many were read and ask to narrow - never call partial sums the total.`,\n ...(target.columns.some(one => one.currency)\n ? [`- Sums of ${target.columns.filter(one => one.currency).map(one => one.name).join(', ')} come per currency. Say each currency's sum; never add two currencies into one number. A comparison across currencies uses a rate you read, and says the rate and its date.`]\n : []),\n ...(target.screen ? [`- When the person wants to work on the records themselves (edit, sort, export), call ${screenToolName(target.key)}; say which conditions the screen does not take.`] : [])\n ].join('\\n'),\n specs\n }\n}\n\n/**\n * What an application calls at boot to let the assistant read one of its lists. A mode opens it by naming the key\n * in `readTargets`.\n */\nexport function registerReadTarget(target: ReadTarget): void {\n declareReadTarget(target)\n registerToolCategory(readCategoryOf(target))\n}\n\n/* ── One answer of a query (DetailRead) ───────────────────────────────────────────────────────────────────── */\n\nfunction argSchema(arg: DetailArg): any {\n const type = arg.type === 'number' ? 'number' : arg.type === 'integer' ? 'integer' : arg.type === 'boolean' ? 'boolean' : 'string'\n const said = [arg.description, arg.type === 'date' ? 'YYYY-MM-DD' : undefined, arg.type === 'enum' ? `one of: ${arg.values!.join(', ')}` : undefined].filter(Boolean).join('. ')\n return { type, ...(said ? { description: said } : {}) }\n}\n\n/** Runs the query as the person with the arguments the model set; the answer as the query returned it. */\nexport async function queryDetail(target: DetailRead, args: any, run: GraphqlRunner) {\n const variables: Record<string, unknown> = {}\n const refused: { name: string; code: string }[] = []\n for (const arg of target.args ?? []) {\n const value = args?.[arg.name]\n if (value === undefined || value === null || value === '') {\n if (arg.required) refused.push({ name: arg.name, code: 'required' })\n continue\n }\n const { read, code } = readFieldValue({ name: arg.name, type: arg.type === 'string' ? 'text' : arg.type, values: arg.values } as any, value)\n if (read === undefined) refused.push({ name: arg.name, code: code ?? 'unreadable' })\n else variables[arg.name] = read\n }\n if (refused.length) return { rejected: true, error: 'argument-unreadable', refused, message: `these arguments are missing or do not fit their type: ${refused.map(one => `${one.name} (${one.code})`).join(', ')}. Fix them and call again.` }\n let answer\n try {\n answer = await run(target.query, variables)\n } catch (error: any) {\n return { rejected: true, error: 'query-failed', message: `it could not be read: ${error?.message ?? error}` }\n }\n if (answer.errors?.length) return { rejected: true, error: 'query-failed', message: `it could not be read: ${answer.errors.map(one => one.message).join('; ')}` }\n const root = rootFieldOf(target.query, 'query').replace(/^Query\\./, '')\n const value = answer.data?.[root]\n if (value === null || value === undefined) return { target: target.key, found: false, message: 'nothing was found for these arguments - say so; do not fill it in.' }\n const size = JSON.stringify(value).length\n if (size > MAX_DETAIL_CHARS) return { rejected: true, error: 'answer-too-large', size, message: `the answer runs to ${size} characters, more than ${MAX_DETAIL_CHARS} - narrow the arguments, or read the list it is made of.` }\n return { target: target.key, answer: value, message: 'answer from these fields; every number you say comes from them. Amounts are in the currency beside them - never add two currencies into one number.' }\n}\n\nexport function detailCategoryOf(target: DetailRead, run: (context: any) => GraphqlRunner = runAsCaller): ToolCategory {\n const door = rootFieldOf(target.query, 'query')\n const name = detailToolName(target.key)\n return {\n name: readCategoryName(target.key),\n description: `data read: ${target.key}`,\n guidance: `- To answer about ${target.description.replace(/\\.$/, '')}, call ${name}. Every number you say comes from its answer.`,\n specs: [\n {\n kind: 'read',\n name,\n /* The person must be able to run the query on its screen - the tool is not a second way in. */\n doors: [door],\n description: `Read ${target.description}`,\n schema: {\n type: 'object',\n ...((target.args ?? []).some(one => one.required) ? { required: (target.args ?? []).filter(one => one.required).map(one => one.name) } : {}),\n properties: Object.fromEntries((target.args ?? []).map(arg => [arg.name, argSchema(arg)]))\n },\n builder: (args: any, context: any) => queryDetail(target, args, run(context))\n } as ToolSpec\n ]\n }\n}\n\n/** What an application calls at boot to let the assistant read one answer of its API. A mode opens it by key in `readTargets`. */\nexport function registerDetailRead(target: DetailRead): void {\n declareDetailRead(target)\n registerToolCategory(detailCategoryOf(target))\n}\n"]}
|
|
1
|
+
{"version":3,"file":"read-tools.js","sourceRoot":"","sources":["../../../server/service/data-read/read-tools.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The tools of an AI 조회 target (operato-application/design/ai/read-targets.md §4, §5).\n *\n * query<X> reads the rows through the application's list query as the person, and tells the model the count, the\n * sums, the groups and a few rows. A longer result goes on the AI 작업판 as a proposal the server builds from the rows\n * themselves - the table is never written by the model. open<X>Screen reads nothing: it hands the card the address\n * of the application's list screen with the conditions it takes.\n */\nimport { registerToolCategory, type ToolCategory, type ToolSpec } from '@things-factory/ai-client-base'\n\nimport { readFieldValue, rootFieldOf } from '../data-entry/entry-target.js'\nimport type { GraphqlRunner } from '../data-entry/entry-update.js'\nimport { runAsCaller } from '../data-entry/entry-tools.js'\nimport { normalizeWorkspace, workspaceContents } from '../workspace/workspace-blocks.js'\nimport {\n declareReadTarget,\n filtersOf,\n currenciesOf,\n declareDetailRead,\n detailToolName,\n MAX_DETAIL_CHARS,\n type DetailArg,\n type DetailRead,\n groupsOf,\n queryToolName,\n readCategoryName,\n readCriteria,\n readRows,\n ROWS_FOR_MODEL,\n screenAddress,\n screenToolName,\n sumsOf,\n type ReadCriterion,\n type ReadTarget\n} from './read-target.js'\n\n/** The reader's words for a key - the key's own default when the translator has none. */\nconst wordsOf = (context: any) => (key: string | undefined, fallback: string) => {\n if (!key || typeof context?.t !== 'function') return fallback\n try {\n const said = context.t(key)\n return said && said !== key ? String(said) : fallback\n } catch {\n return fallback\n }\n}\n\nfunction criterionSchema(criterion: ReadCriterion): any {\n /* One type per field - Gemini's function schema refuses a list of types (2026-10-01). */\n const type = criterion.type === 'number' ? 'number' : criterion.type === 'integer' ? 'integer' : criterion.type === 'boolean' ? 'boolean' : 'string'\n const said = [criterion.description, criterion.type === 'date' ? 'YYYY-MM-DD' : undefined, criterion.type === 'enum' ? `one of: ${criterion.values!.join(', ')}` : undefined]\n .filter(Boolean)\n .join('. ')\n return { type, ...(said ? { description: said } : {}) }\n}\n\nexport async function queryRecords(target: ReadTarget, args: any, context: any, run: GraphqlRunner) {\n const { criteria, refused } = readCriteria(target, args)\n if (refused.length) {\n return { rejected: true, error: 'condition-unreadable', refused, message: `these conditions do not fit their type: ${refused.map(one => `${one.name} (${one.code})`).join(', ')}. Fix them and call again.` }\n }\n let read\n try {\n read = await readRows(target, filtersOf(target, criteria), run, typeof criteria.text === 'string' && target.search ? criteria.text : undefined)\n } catch (error: any) {\n return { rejected: true, error: 'query-failed', message: `the list could not be read: ${error?.message ?? error}` }\n }\n const { rows, total, complete } = read\n const sums = sumsOf(target, rows)\n const groupBy = typeof args?.groupBy === 'string' && args.groupBy ? args.groupBy : undefined\n const groups = groupBy ? groupsOf(target, rows, groupBy) : undefined\n const words = wordsOf(context)\n const label = words(target.labelKey, target.key)\n\n const said = {\n target: target.key,\n criteria,\n total,\n read: rows.length,\n complete,\n sums,\n ...(groupBy ? (groups ? { groupBy, groups: groups.slice(0, 50), ...(groups.length > 50 ? { moreGroups: groups.length - 50 } : {}) } : { groupBy, groupRefused: 'no such column' }) : {}),\n rows: rows.slice(0, ROWS_FOR_MODEL),\n ...(rows.length > ROWS_FOR_MODEL ? { rowsNotShown: rows.length - ROWS_FOR_MODEL } : {})\n }\n const incomplete = complete\n ? ''\n : ` Only ${rows.length} of ${total} rows were read; the sums and groups are of those rows, not of the list - say so, and ask the person to narrow the conditions.`\n\n if (rows.length === 1 && args?.show !== 'workspace') {\n return { ...said, record: rows[0], message: 'one record - answer from its fields; say a field it does not have as not recorded.' }\n }\n if (rows.length <= ROWS_FOR_MODEL && args?.show !== 'workspace') {\n return { ...said, message: `${rows.length} rows of ${total}.${incomplete} Answer from these rows; every number you say comes from them.` }\n }\n\n /* The workspace is built here from the rows as read - the model never copies the table. */\n const columns = target.columns.map(column => ({ name: column.name, label: words(column.labelKey, column.name), type: column.type }))\n const totalColumns = target.columns.filter(one => one.total)\n /* A sum per currency is one figure and one group column per currency it holds - 「계약금액 (USD)」. */\n const sumColumns = totalColumns.flatMap(column => {\n const label = words(column.labelKey, column.name)\n const codes = currenciesOf([sums, ...(groups ?? []).map(group => group.sums)], column.name)\n return column.currency\n ? codes.map(code => ({ name: `${column.name}:${code}`, label: `${label} (${code})`, of: (one: Record<string, any>) => one[column.name]?.[code] ?? 0 }))\n : [{ name: column.name, label, of: (one: Record<string, any>) => one[column.name] }]\n })\n const title = typeof args?.title === 'string' && args.title.trim() ? args.title.trim() : `${label} · ${rows.length}`\n const { workspace } = normalizeWorkspace({\n name: typeof args?.name === 'string' && args.name ? args.name : target.key.replace(/\\./g, '-'),\n title,\n ...(complete ? {} : { summary: `${total} / ${rows.length}` }),\n blocks: [\n {\n kind: 'metrics',\n items: [{ label: words('ai-assistant.read.count', 'rows'), value: String(rows.length), ...(complete ? {} : { note: `/ ${total}` }) }, ...sumColumns.map(column => ({ label: column.label, value: String(column.of(sums)) }))]\n },\n ...(groups\n ? [\n {\n kind: 'table',\n caption: words(target.columns.find(one => one.name === groupBy)?.labelKey, groupBy!),\n columns: [{ name: 'key', label: words(target.columns.find(one => one.name === groupBy)?.labelKey, groupBy!), type: 'string' }, { name: 'count', label: words('ai-assistant.read.count', 'rows'), type: 'number' }, ...sumColumns.map(column => ({ name: column.name, label: column.label, type: 'number' }))],\n rows: groups.map(group => ({ key: group.key, count: group.count, ...Object.fromEntries(sumColumns.map(column => [column.name, column.of(group.sums)])) }))\n }\n ]\n : []),\n { kind: 'table', caption: label, columns, rows }\n ]\n })\n return {\n proposed: true,\n kind: 'workspace',\n icon: 'table_view',\n label: title,\n ...said,\n forScreen: { workspace, contents: workspaceContents(workspace!) },\n message: `${rows.length} rows of ${total} are on the AI 작업판 as read - the person opens it from the card.${incomplete} Say the point in one or two lines from the sums, groups and rows above; do not write the table out.`\n }\n}\n\nexport function openScreen(target: ReadTarget, args: any, context: any) {\n const { criteria, refused } = readCriteria(target, args)\n if (refused.length) return { rejected: true, error: 'condition-unreadable', refused, message: 'fix the conditions and call again.' }\n const address = screenAddress(target, criteria)\n if (!address) return { rejected: true, error: 'no-screen', message: 'this list has no screen to open.' }\n const words = wordsOf(context)\n return {\n proposed: true,\n kind: 'open-page',\n icon: 'open_in_new',\n label: words(target.screen!.labelKey ?? target.labelKey, target.key),\n target: target.key,\n href: address.href,\n applied: address.applied,\n notApplied: address.notApplied,\n /* The card says them in the reader's words. */\n notAppliedLabels: address.notApplied.map(name => words(target.criteria.find(one => one.name === name)?.labelKey ?? (name === 'text' || name === 'id' ? `ai-assistant.read.${name}` : undefined), name)),\n message:\n 'the card opens the screen when the person presses it.' +\n (address.notApplied.length ? ` The screen does not take ${address.notApplied.join(', ')} - say so.` : '')\n }\n}\n\nexport function readCategoryOf(target: ReadTarget, run: (context: any) => GraphqlRunner = runAsCaller): ToolCategory {\n const door = rootFieldOf(target.query, 'query')\n const conditions = {\n ...Object.fromEntries(target.criteria.map(criterion => [criterion.name, criterionSchema(criterion)])),\n ...(target.search ? { text: { type: 'string', description: `words to find - ${target.search.description}` } } : {})\n }\n const specs: ToolSpec[] = [\n {\n kind: 'read',\n name: queryToolName(target.key),\n /* The person must be able to read the list on its screen - the tool is not a second way in. */\n doors: [door],\n description:\n `Read ${target.description} Set the conditions the question names. Returns the count, the sums, ` +\n `groups when groupBy is given (a date column groups by month) and the first ${ROWS_FOR_MODEL} rows; more rows go on the AI 작업판 as read.`,\n schema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'One record by its id, from an earlier answer - its detail.' },\n ...conditions,\n groupBy: { type: 'string', description: `One column to group by: ${target.columns.map(one => one.name).join(', ')}.` },\n show: { type: 'string', enum: ['answer', 'workspace'], description: 'workspace to put even a short result on the AI 작업판.' },\n title: { type: 'string', description: 'The workspace title, in the person\\'s language.' },\n name: { type: 'string', description: 'The workspace key; the same key again makes a new version.' }\n }\n },\n builder: (args: any, context: any) => queryRecords(target, args, context, run(context))\n } as ToolSpec,\n ...(target.screen\n ? [\n {\n kind: 'read',\n name: screenToolName(target.key),\n doors: [door],\n description: `Offer the person the screen that lists ${target.description} with these conditions. Reads nothing. The screen takes: ${target.screen.takes.join(', ')}.`,\n schema: { type: 'object', properties: conditions },\n builder: (args: any, context: any) => openScreen(target, args, context)\n } as ToolSpec\n ]\n : [])\n ]\n return {\n name: readCategoryName(target.key),\n description: `data read: ${target.key}`,\n guidance: [\n `- To answer from ${target.key} records - a list, or one record found by its name, code or id - call ${queryToolName(target.key)} with the conditions the question names. Every number you say comes from its result - never add up rows yourself; use its sums and groups.`,\n `- A list, a summary by item or month, or a comparison: call it with groupBy, and let a long result go on the AI 작업판 - then answer in one or two lines.`,\n `- When the result says complete: false, say how many of how many were read and ask to narrow - never call partial sums the total.`,\n ...(target.columns.some(one => one.currency)\n ? [`- Sums of ${target.columns.filter(one => one.currency).map(one => one.name).join(', ')} come per currency. Say each currency's sum; never add two currencies into one number. A comparison across currencies uses a rate you read, and says the rate and its date.`]\n : []),\n ...(target.screen ? [`- When the person wants to work on the records themselves (edit, sort, export), call ${screenToolName(target.key)}; say which conditions the screen does not take.`] : [])\n ].join('\\n'),\n specs\n }\n}\n\n/**\n * What an application calls at boot to let the assistant read one of its lists. A mode opens it by naming the key\n * in `readTargets`.\n */\nexport function registerReadTarget(target: ReadTarget): void {\n declareReadTarget(target)\n registerToolCategory(readCategoryOf(target))\n}\n\n/* ── One answer of a query (DetailRead) ───────────────────────────────────────────────────────────────────── */\n\nfunction argSchema(arg: DetailArg): any {\n const type = arg.type === 'number' ? 'number' : arg.type === 'integer' ? 'integer' : arg.type === 'boolean' ? 'boolean' : 'string'\n const said = [arg.description, arg.type === 'date' ? 'YYYY-MM-DD' : undefined, arg.type === 'enum' ? `one of: ${arg.values!.join(', ')}` : undefined].filter(Boolean).join('. ')\n return { type, ...(said ? { description: said } : {}) }\n}\n\n/** Runs the query as the person with the arguments the model set; the answer as the query returned it. */\nexport async function queryDetail(target: DetailRead, args: any, run: GraphqlRunner) {\n const variables: Record<string, unknown> = {}\n const refused: { name: string; code: string }[] = []\n for (const arg of target.args ?? []) {\n const value = args?.[arg.name]\n if (value === undefined || value === null || value === '') {\n if (arg.required) refused.push({ name: arg.name, code: 'required' })\n continue\n }\n const { read, code } = readFieldValue({ name: arg.name, type: arg.type === 'string' ? 'text' : arg.type, values: arg.values, axis: arg.axis } as any, value)\n if (read === undefined) refused.push({ name: arg.name, code: code ?? 'unreadable' })\n else variables[arg.name] = read\n }\n if (refused.length) return { rejected: true, error: 'argument-unreadable', refused, message: `these arguments are missing or do not fit their type: ${refused.map(one => `${one.name} (${one.code})`).join(', ')}. Fix them and call again.` }\n let answer\n try {\n answer = await run(target.query, variables)\n } catch (error: any) {\n return { rejected: true, error: 'query-failed', message: `it could not be read: ${error?.message ?? error}` }\n }\n if (answer.errors?.length) return { rejected: true, error: 'query-failed', message: `it could not be read: ${answer.errors.map(one => one.message).join('; ')}` }\n const root = rootFieldOf(target.query, 'query').replace(/^Query\\./, '')\n const value = answer.data?.[root]\n if (value === null || value === undefined) return { target: target.key, found: false, message: 'nothing was found for these arguments - say so; do not fill it in.' }\n const size = JSON.stringify(value).length\n if (size > MAX_DETAIL_CHARS) return { rejected: true, error: 'answer-too-large', size, message: `the answer runs to ${size} characters, more than ${MAX_DETAIL_CHARS} - narrow the arguments, or read the list it is made of.` }\n return { target: target.key, answer: value, message: 'answer from these fields; every number you say comes from them. Amounts are in the currency beside them - never add two currencies into one number.' }\n}\n\nexport function detailCategoryOf(target: DetailRead, run: (context: any) => GraphqlRunner = runAsCaller): ToolCategory {\n const door = rootFieldOf(target.query, 'query')\n const name = detailToolName(target.key)\n return {\n name: readCategoryName(target.key),\n description: `data read: ${target.key}`,\n guidance: `- To answer about ${target.description.replace(/\\.$/, '')}, call ${name}. Every number you say comes from its answer.`,\n specs: [\n {\n kind: 'read',\n name,\n /* The person must be able to run the query on its screen - the tool is not a second way in. */\n doors: [door],\n description: `Read ${target.description}`,\n schema: {\n type: 'object',\n ...((target.args ?? []).some(one => one.required) ? { required: (target.args ?? []).filter(one => one.required).map(one => one.name) } : {}),\n properties: Object.fromEntries((target.args ?? []).map(arg => [arg.name, argSchema(arg)]))\n },\n builder: (args: any, context: any) => queryDetail(target, args, run(context))\n } as ToolSpec\n ]\n }\n}\n\n/** What an application calls at boot to let the assistant read one answer of its API. A mode opens it by key in `readTargets`. */\nexport function registerDetailRead(target: DetailRead): void {\n declareDetailRead(target)\n registerToolCategory(detailCategoryOf(target))\n}\n"]}
|