Просмотр исходного кода

feat(oa): wire start dialog to per-node initiator select in flow preview

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 3 месяцев назад
Родитель
Сommit
4641d333e6

Разница между файлами не показана из-за своего большого размера
+ 408 - 629
web-admin/graphify-out/.graphify_analysis.json


Разница между файлами не показана из-за своего большого размера
+ 531 - 55
web-admin/graphify-out/.graphify_extract.json


+ 146 - 140
web-admin/graphify-out/GRAPH_REPORT.md

@@ -1,11 +1,11 @@
-# Graph Report - src  (2026-07-22)
+# Graph Report - src  (2026-07-23)
 
 ## Corpus Check
-- Large corpus: 883 files · ~590,189 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
+- Large corpus: 889 files · ~594,384 words. Semantic extraction will be expensive (many Claude tokens). Consider running on a subfolder, or use --no-semantic to run AST-only.
 
 ## Summary
-- 3051 nodes · 4278 edges · 63 communities detected
-- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 961 edges (avg confidence: 0.8)
+- 3092 nodes · 4349 edges · 63 communities detected
+- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 978 edges (avg confidence: 0.8)
 - Token cost: 0 input · 0 output
 
 ## Community Hubs (Navigation)
@@ -49,36 +49,36 @@
 - [[_COMMUNITY_Community 37|Community 37]]
 - [[_COMMUNITY_Community 38|Community 38]]
 - [[_COMMUNITY_Community 39|Community 39]]
-- [[_COMMUNITY_Community 40|Community 40]]
 - [[_COMMUNITY_Community 41|Community 41]]
-- [[_COMMUNITY_Community 43|Community 43]]
-- [[_COMMUNITY_Community 44|Community 44]]
-- [[_COMMUNITY_Community 45|Community 45]]
+- [[_COMMUNITY_Community 42|Community 42]]
+- [[_COMMUNITY_Community 46|Community 46]]
 - [[_COMMUNITY_Community 47|Community 47]]
+- [[_COMMUNITY_Community 49|Community 49]]
 - [[_COMMUNITY_Community 50|Community 50]]
 - [[_COMMUNITY_Community 51|Community 51]]
+- [[_COMMUNITY_Community 52|Community 52]]
 - [[_COMMUNITY_Community 53|Community 53]]
 - [[_COMMUNITY_Community 54|Community 54]]
 - [[_COMMUNITY_Community 55|Community 55]]
-- [[_COMMUNITY_Community 56|Community 56]]
 - [[_COMMUNITY_Community 57|Community 57]]
 - [[_COMMUNITY_Community 58|Community 58]]
-- [[_COMMUNITY_Community 60|Community 60]]
+- [[_COMMUNITY_Community 62|Community 62]]
 - [[_COMMUNITY_Community 64|Community 64]]
+- [[_COMMUNITY_Community 65|Community 65]]
 - [[_COMMUNITY_Community 66|Community 66]]
 - [[_COMMUNITY_Community 70|Community 70]]
 - [[_COMMUNITY_Community 72|Community 72]]
 - [[_COMMUNITY_Community 73|Community 73]]
-- [[_COMMUNITY_Community 82|Community 82]]
 - [[_COMMUNITY_Community 84|Community 84]]
-- [[_COMMUNITY_Community 85|Community 85]]
+- [[_COMMUNITY_Community 86|Community 86]]
+- [[_COMMUNITY_Community 87|Community 87]]
 
 ## God Nodes (most connected - your core abstractions)
-1. `get()` - 291 edges
-2. `push()` - 92 edges
-3. `emit()` - 28 edges
+1. `get()` - 294 edges
+2. `push()` - 96 edges
+3. `emit()` - 29 edges
 4. `WebSocketClient` - 26 edges
-5. `set()` - 20 edges
+5. `set()` - 21 edges
 6. `handleDynamicRoutes()` - 18 edges
 7. `parseProtocolStandardImportText()` - 17 edges
 8. `scopeQuery()` - 16 edges
@@ -86,180 +86,176 @@
 10. `TableCache` - 14 edges
 
 ## Surprising Connections (you probably didn't know these)
+- `handleBatchDelete()` --calls--> `withFullscreenLoading()`  [INFERRED]
+  views/basic-info/customer/index.vue → utils/fullscreen-loading.ts
 - `buildInboundMetaFields()` --calls--> `push()`  [INFERRED]
   utils/production-work-order-card-meta.ts → views/operations/storage-facility/index.vue
-- `dash()` --calls--> `formatDisplayOrDash()`  [INFERRED]
-  components/business/infusion-schedule-outbound-chain-view/index.vue → utils/datetime-display.ts
-- `dash()` --calls--> `formatDisplayOrDash()`  [INFERRED]
-  components/business/clinical-schedule-payment-detail/index.vue → utils/datetime-display.ts
 - `fmtMoney()` --calls--> `formatMoneyDisplay()`  [INFERRED]
   components/business/clinical-schedule-payment-detail/index.vue → utils/money-format.ts
-- `subscribeTokenRefresh()` --calls--> `push()`  [INFERRED]
-  utils/http/index.ts → views/operations/storage-facility/index.vue
+- `defaultInstallmentRatios()` --calls--> `push()`  [INFERRED]
+  utils/protocol-payment-installment.ts → views/operations/storage-facility/index.vue
+- `calcUnpaidAmountsByRatios()` --calls--> `push()`  [INFERRED]
+  utils/protocol-payment-installment.ts → views/operations/storage-facility/index.vue
 
 ## Communities
 
 ### Community 0 - "Community 0"
 Cohesion: 0.01
-Nodes (170): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchChannelAccount() (+162 more)
+Nodes (178): fetchAccessLogList(), fetchActiveRegions(), fetchCategoryList(), fetchCategoryParameters(), fetchCellProductPriceList(), fetchCellProductSpecList(), fetchCellProductTypeList(), fetchChannelAccount() (+170 more)
 
 ### Community 1 - "Community 1"
 Cohesion: 0.03
-Nodes (96): fetchUploadAttachment(), handleReportUpload(), handleReportUpload(), walk(), buildTemporaryViewSections(), appendTaskResultSections(), batchTasksForPanelSlot(), buildConfiguredOnlySection() (+88 more)
+Nodes (83): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionList(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), fetchPilotCheckupList(), markPilotCheckupChecked() (+75 more)
 
 ### Community 2 - "Community 2"
 Cohesion: 0.03
-Nodes (83): batchSavePilotCheckup(), deletePilotCheckupActualItem(), fetchCheckupInstitutionList(), fetchCheckupInstitutionPackageDetail(), fetchCheckupInstitutionPackages(), fetchPilotCheckupDetail(), fetchPilotCheckupList(), markPilotCheckupChecked() (+75 more)
+Nodes (70): fetchUploadAttachment(), fetchOaInstanceDetail(), fetchOaRelatedSummaries(), fetchOaTasks(), FireworkSystem, currentPrinterName(), load(), openDetail() (+62 more)
 
 ### Community 3 - "Community 3"
 Cohesion: 0.03
-Nodes (63): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchCreateProtocolInvoiceRequest(), fetchInvoiceEligiblePayments(), fetchPaymentDetailList() (+55 more)
+Nodes (61): buildInboundBasicSection(), buildInboundCellStorageViewSections(), buildInboundResearchDonationViewSections(), buildReceptionSection(), buildTemporaryViewSections(), buildTransportSection(), resolveInboundProtocolStatus(), buildInsertedSiblingCard() (+53 more)
 
 ### Community 4 - "Community 4"
-Cohesion: 0.03
-Nodes (63): fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchDispatchProductionTaskSteps(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchProductionTaskEditorInit(), fetchProductionTaskList() (+55 more)
+Cohesion: 0.04
+Nodes (69): formatNowDatetime(), formatTodayDate(), addPaymentDetail(), applyFqPaymentDefaults(), applyPaymentPresetForMode(), createEmptyTransport(), datetimeToYmd(), defaultInstallmentStartDateYmd() (+61 more)
 
 ### Community 5 - "Community 5"
 Cohesion: 0.03
-Nodes (57): buildInboundBasicSection(), buildInboundCellStorageViewSections(), buildInboundResearchDonationViewSections(), buildReceptionSection(), buildTransportSection(), resolveInboundProtocolStatus(), buildBaseFields(), buildFeeSection() (+49 more)
+Nodes (50): fetchCreateOaRole(), fetchDeleteOaRole(), fetchOaAppDraft(), fetchOaAppList(), fetchOaGroupList(), fetchOaRelatedCandidates(), fetchOaRoleList(), fetchOaRoleUsers() (+42 more)
 
 ### Community 6 - "Community 6"
 Cohesion: 0.03
-Nodes (33): fetchGetMenuList(), ComponentLoader, IframeRouteManager, MenuProcessor, RouteRegistry, RouteTransformer, useAppMode(), useAuth() (+25 more)
+Nodes (51): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), if(), branchTitle() (+43 more)
 
 ### Community 7 - "Community 7"
-Cohesion: 0.04
-Nodes (50): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice(), fetchUpdateCheckupInstitutionProject() (+42 more)
+Cohesion: 0.03
+Nodes (59): fetchFullmoonTodoList(), fetchUpdateFullmoonTodoInsurance(), fetchCollectionProtocolAuditList(), fetchCollectionProtocolDetail(), fetchCollectionProtocolList(), fetchCreateProtocolInvoiceRequest(), fetchInvoiceEligiblePayments(), fetchPaymentDetailList() (+51 more)
 
 ### Community 8 - "Community 8"
 Cohesion: 0.03
-Nodes (46): useSettingsHandlers(), useSettingsPanel(), useSettingsState(), RoutePermissionValidator, useCeremony(), useTheme(), if(), branchTitle() (+38 more)
+Nodes (49): fetchCheckupInstitutionInvoices(), fetchCheckupInstitutionProjects(), fetchCreateCheckupInstitution(), fetchCreateCheckupInstitutionInvoice(), fetchCreateCheckupInstitutionProject(), fetchUpdateCheckupInstitution(), fetchUpdateCheckupInstitutionInvoice(), fetchUpdateCheckupInstitutionProject() (+41 more)
 
 ### Community 9 - "Community 9"
 Cohesion: 0.04
-Nodes (32): handleBlur(), handleFocus(), handleInput(), fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions() (+24 more)
+Nodes (41): fetchGetMenuList(), fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchUpdateProfile(), fetchUploadProfileAvatar(), MenuProcessor, RouteRegistry (+33 more)
 
 ### Community 10 - "Community 10"
-Cohesion: 0.04
-Nodes (44): fetchMyProductionTasks(), buildMineTableRows(), buildPresetTasksMap(), buildWorkOrderFromTasks(), fetchAllMineProductionTasks(), fetchMineTasksByScope(), groupMineTasksByWorkOrder(), keywordMatchesWorkOrder() (+36 more)
+Cohesion: 0.03
+Nodes (51): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleDialogClose(), handleAdd(), handleBatchDelete() (+43 more)
 
 ### Community 11 - "Community 11"
-Cohesion: 0.04
-Nodes (35): fetchCreateOaRole(), fetchDeleteOaRole(), fetchOaAppDraft(), fetchOaAppList(), fetchOaGroupList(), fetchOaRoleList(), fetchOaRoleUsers(), fetchOaTemplateDetail() (+27 more)
+Cohesion: 0.03
+Nodes (51): fetchMyProductionTasks(), fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), fetchMineTasksForWorkOrders(), useInboundSiblingNavigation(), shouldApplyTriggerSourceFilter(), useQcWorkOrderTabPage() (+43 more)
 
 ### Community 12 - "Community 12"
 Cohesion: 0.04
-Nodes (39): fetchEthnicList(), formatNowDatetime(), applyDonationBundleToForm(), createEmptyTransport(), ensureEthnicOptionInList(), handleOpenForAdd(), if(), loadEthnicOptions() (+31 more)
+Nodes (42): buildBaseFields(), buildFeeSection(), buildInboundBasicSection(), buildInboundCellStorageProductionViewSections(), buildInboundResearchDonationProductionViewSections(), buildOutboundBasicExperimentProductionViewSections(), buildOutboundClinicalProductionViewSections(), buildOutboundDetail() (+34 more)
 
 ### Community 13 - "Community 13"
-Cohesion: 0.05
-Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
+Cohesion: 0.04
+Nodes (31): fetchProductionWorkOrderQcInfo(), dash(), fmtMoney(), attachmentFullUrl(), dash(), handleAttachmentDownload(), handleAttachmentPreview(), auditorDisplay() (+23 more)
 
 ### Community 14 - "Community 14"
 Cohesion: 0.05
-Nodes (27): fetchUserList(), fetchProductionReceptionBySampleCode(), fetchProductionReceptionSubmit(), fetchProductionReceptionUpdate(), loadUsers(), formatHandoverUserLabel(), formatNowDatetime(), fullFileUrl() (+19 more)
+Nodes (48): fetchEthnicList(), applyDonationBundleToForm(), createEmptyTransport(), ensureEthnicOptionInList(), handleOpenForAdd(), if(), loadEthnicOptions(), normalizeSampleRow() (+40 more)
 
 ### Community 15 - "Community 15"
 Cohesion: 0.04
-Nodes (21): fetchAvailableMaterialBatches(), fetchMyProductionMaterialConsumptions(), fetchMyProductionMaterialUsageList(), fetchProductionMaterialBatchList(), fetchProductionMaterialBatchOptions(), fetchProductionMaterialConsumptions(), fetchProductionMaterialFormula(), fetchProductionMaterialLinkedStepUsages() (+13 more)
+Nodes (37): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList() (+29 more)
 
 ### Community 16 - "Community 16"
-Cohesion: 0.08
-Nodes (37): formatDatetimeToMinute(), handleChineseDatetimePaste(), parseChineseDatetimeText(), parseBirthOrder(), parseChineseNumeral(), addSampleHint(), earliestCollectTime(), isMaternalBloodEmpty() (+29 more)
+Cohesion: 0.05
+Nodes (34): fetchClinicalPaymentDetail(), fetchClinicalPayments(), fetchClinicalReceiptConfirmed(), fetchClinicalReceiptPending(), fetchClinicalRefundConfirmed(), fetchClinicalRefundPending(), fetchOrderAdjusts(), fetchOrderDetail() (+26 more)
 
 ### Community 17 - "Community 17"
 Cohesion: 0.06
-Nodes (23): fetchCreateMenu(), fetchDeleteMenu(), fetchMenuTree(), fetchUpdateMenu(), collectIds(), postorder(), preorder(), applyTreeExpand() (+15 more)
+Nodes (39): fetchUserList(), fetchAddTaskStep(), fetchCopyTaskStep(), fetchDeleteTaskStep(), fetchDispatchProductionTaskSteps(), fetchForwardProductionTask(), fetchProductionTaskDetail(), fetchProductionTaskEditorInit() (+31 more)
 
 ### Community 18 - "Community 18"
-Cohesion: 0.06
-Nodes (22): fetchQcMaterialBatchDetail(), fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), financeAttachmentsToUrlString() (+14 more)
+Cohesion: 0.04
+Nodes (21): fetchAvailableMaterialBatches(), fetchMyProductionMaterialConsumptions(), fetchMyProductionMaterialUsageList(), fetchProductionMaterialBatchList(), fetchProductionMaterialBatchOptions(), fetchProductionMaterialConsumptions(), fetchProductionMaterialFormula(), fetchProductionMaterialLinkedStepUsages() (+13 more)
 
 ### Community 19 - "Community 19"
 Cohesion: 0.06
-Nodes (28): fetchMyQcTaskList(), fetchQcTaskDetail(), fetchQcTaskList(), buildInsertedSiblingCard(), fetchMineTasksForWorkOrders(), resolveShowProtocolPaymentAtGroup(), useInboundSiblingNavigation(), shouldApplyTriggerSourceFilter() (+20 more)
+Nodes (21): fetchQcMaterialBatchDetail(), fetchQcMaterialBatchList(), fetchQcMaterialBatchOptions(), fetchQcMaterialList(), fetchQcMaterialOptions(), fetchUpdateQcMaterialBatch(), fetchMarkQcMaterialUsageFullyUsed(), financeAttachmentsToUrlString() (+13 more)
 
 ### Community 20 - "Community 20"
-Cohesion: 0.06
-Nodes (13): fetchProductionWorkOrderQcInfo(), dash(), fmtMoney(), auditorDisplay(), dash(), ensureUnitsInOptions(), expressName(), formatYm() (+5 more)
-
-### Community 21 - "Community 21"
 Cohesion: 0.1
 Nodes (2): WebSocketClient, TableCache
 
+### Community 21 - "Community 21"
+Cohesion: 0.08
+Nodes (33): fetchRefreshToken(), toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url() (+25 more)
+
 ### Community 22 - "Community 22"
-Cohesion: 0.07
-Nodes (28): fetchOaInstanceDetail(), fetchOaTasks(), currentPrinterName(), load(), openDetail(), printRow(), load(), openDetail() (+20 more)
+Cohesion: 0.09
+Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
 
 ### Community 23 - "Community 23"
 Cohesion: 0.08
-Nodes (32): toLogin(), base64ToBytes(), bytesToBase64(), decryptJson(), deriveKey(), encryptJson(), fromBase64Url(), hexToBytes() (+24 more)
+Nodes (12): ComponentLoader, IframeRouteManager, RouteTransformer, getFirstMenuPath(), getFirstSecondLevelMenuPath(), isIframe(), isNavigableMenuItem(), isWorkbenchMenuItem() (+4 more)
 
 ### Community 24 - "Community 24"
-Cohesion: 0.09
-Nodes (8): getDefaultLanguage(), checkStorageCompatibility(), StorageConfig, getSystemStorage(), getSysVersion(), StorageKeyManager, StorageCompatibilityManager, validateStorageData()
+Cohesion: 0.08
+Nodes (20): createEmptySnapshots(), normalizeConfiguredReagents(), normalizeConsumables(), normalizeDataCollections(), normalizeReagents(), normalizeStepOutputs(), serializeAttachments(), serializeEquipmentIds() (+12 more)
 
 ### Community 25 - "Community 25"
 Cohesion: 0.08
-Nodes (20): createEmptySnapshots(), normalizeConfiguredReagents(), normalizeConsumables(), normalizeDataCollections(), normalizeReagents(), normalizeStepOutputs(), serializeAttachments(), serializeEquipmentIds() (+12 more)
+Nodes (18): fetchProductionReceptionBySampleCode(), fetchProductionReceptionSubmit(), fetchProductionReceptionUpdate(), onUserSelectVisible(), remoteSearchUsers(), buildPayload(), ensureDefaultHandler(), initDialog() (+10 more)
 
 ### Community 26 - "Community 26"
-Cohesion: 0.1
-Nodes (28): fetchCreateCustomer(), fetchCustomerList(), fetchDeleteCustomer(), fetchUpdateCustomer(), updateInfusionScheduleStatus(), handleAdd(), handleDelete(), handleDropdownCommand() (+20 more)
+Cohesion: 0.07
+Nodes (19): fetchDeleteMaterialBatch(), fetchMaterialBatchList(), fetchMaterialBatchOptions(), fetchMaterialList(), fetchMaterialOptions(), fetchUpdateMaterialBatch(), fetchMaterialUsageList(), fetchMyMaterialUsageList() (+11 more)
 
 ### Community 27 - "Community 27"
-Cohesion: 0.09
-Nodes (28): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), clearTableSelection(), handleBatchComplete(), handleBatchStart() (+20 more)
+Cohesion: 0.07
+Nodes (13): handleBlur(), handleFocus(), handleInput(), formatAmount(), formatAmount(), formatProtocolAmount(), formatInvoiceAmount(), fmtMoney() (+5 more)
 
 ### Community 28 - "Community 28"
 Cohesion: 0.09
-Nodes (22): fetchMineProductionWorkOrderTabStepCounts(), fetchMineProductionWorkOrderTabStepCountsDeduped(), fetchProductionWorkOrderCellProductOptions(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchProductionWorkOrderQcDispatchOptions(), fetchProductionWorkOrderTabStepCounts(), fetchProductionWorkOrderTabStepCountsDeduped() (+14 more)
+Nodes (27): completePilotApplication(), deletePilotApplication(), fetchPilotApplicationList(), startPilotApplication(), voidPilotApplication(), handleBatchComplete(), handleBatchStart(), handleBatchVoid() (+19 more)
 
 ### Community 29 - "Community 29"
-Cohesion: 0.11
-Nodes (21): fetchGetMenuCodes(), fetchGetUserInfo(), fetchLogin(), fetchRefreshToken(), fetchUpdateProfile(), fetchUploadProfileAvatar(), fetchUserInfo(), buildWebEncryptedLoginBody() (+13 more)
+Cohesion: 0.09
+Nodes (22): fetchMineProductionWorkOrderTabStepCounts(), fetchMineProductionWorkOrderTabStepCountsDeduped(), fetchProductionWorkOrderCellProductOptions(), fetchProductionWorkOrderDetail(), fetchProductionWorkOrderList(), fetchProductionWorkOrderQcDispatchOptions(), fetchProductionWorkOrderTabStepCounts(), fetchProductionWorkOrderTabStepCountsDeduped() (+14 more)
 
 ### Community 30 - "Community 30"
 Cohesion: 0.09
 Nodes (12): fetchMineQcWorkOrderTabUnfinishedCounts(), fetchOutboundQcDetail(), fetchQcWorkOrderDetail(), fetchQcWorkOrderList(), fetchQcWorkOrdersBySample(), fetchQcWorkOrderTabUnfinishedCounts(), reload(), reloadTabCounts() (+4 more)
 
 ### Community 31 - "Community 31"
-Cohesion: 0.18
-Nodes (22): buildPaymentFlowSteps(), dash(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit(), receiptSubmitTime() (+14 more)
+Cohesion: 0.12
+Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
 
 ### Community 32 - "Community 32"
-Cohesion: 0.09
-Nodes (13): fetchQcSmsList(), fetchApproveTask(), fetchBusinessAllTasks(), fetchCompletedTasks(), fetchDesignerData(), fetchInstanceDetail(), fetchMyInstances(), fetchPendingTasks() (+5 more)
+Cohesion: 0.13
+Nodes (18): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleDropdownCommand(), handleEdit() (+10 more)
 
 ### Community 33 - "Community 33"
-Cohesion: 0.12
-Nodes (15): addCopyButton(), highlightCode(), insertLineNumbers(), isBlockProcessed(), markBlockAsProcessed(), processBlock(), setupHighlightDirective(), setupRippleDirective() (+7 more)
-
-### Community 34 - "Community 34"
 Cohesion: 0.11
 Nodes (11): fetchOutboundReleaseMaterial(), fetchOutboundReleaseReviewDetail(), fetchOutboundReleaseReviewList(), fetchReleaseReviewList(), handleReset(), handleSearch(), handleToggleSelect(), loadData() (+3 more)
 
-### Community 35 - "Community 35"
-Cohesion: 0.13
-Nodes (18): fetchCellSampleTypeList(), fetchCreateCellSampleType(), fetchDeleteCellSampleType(), fetchUpdateCellSampleType(), handleAdd(), handleDelete(), handleDropdownCommand(), handleEdit() (+10 more)
-
-### Community 36 - "Community 36"
+### Community 34 - "Community 34"
 Cohesion: 0.19
 Nodes (15): fetchAttachmentDownloadUrl(), attachmentFullUrl(), ensureUniqueZipEntryName(), fetchAttachmentBlob(), getAttachmentExtension(), resolveAttachmentFileName(), sanitizeZipPathSegment(), applyInboundLabStorageCodePrefix() (+7 more)
 
-### Community 37 - "Community 37"
-Cohesion: 0.16
-Nodes (14): fetchCreateEnvDetectItem(), fetchDeleteEnvDetectItem(), fetchEnvDetectItemDetail(), fetchEnvDetectItemList(), fetchEnvDetectItemsActive(), fetchUpdateEnvDetectItem(), handleAdd(), handleBatchDelete() (+6 more)
+### Community 35 - "Community 35"
+Cohesion: 0.15
+Nodes (11): displayPeople(), personLines(), personTitle(), showNodeComment(), signBadge(), signBadgeText(), statusText(), displayName() (+3 more)
 
-### Community 38 - "Community 38"
+### Community 36 - "Community 36"
 Cohesion: 0.16
 Nodes (10): useTable(), useTableImpl(), getColumnChecks(), useTableColumns(), createErrorHandler(), createSmartDebounce(), defaultResponseAdapter(), extractPagination() (+2 more)
 
-### Community 39 - "Community 39"
+### Community 37 - "Community 37"
 Cohesion: 0.27
 Nodes (14): useChart(), useChartComponent(), useChartOps(), colourBlend(), getCssVar(), getDarkColor(), getLightColor(), handleElementThemeColor() (+6 more)
 
-### Community 40 - "Community 40"
+### Community 38 - "Community 38"
+Cohesion: 0.33
+Nodes (13): buildProtocolPaymentFlowSteps(), dash(), financeReceiptTime(), formatAmount(), hasFinanceReceipt(), hasFinanceRefund(), hasReceiptSubmit(), hasRefundSubmit() (+5 more)
+
+### Community 39 - "Community 39"
 Cohesion: 0.19
 Nodes (6): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabChange(), loadData(), switchTab()
 
@@ -267,66 +263,70 @@ Nodes (6): fetchServiceOrderTxnList(), handleReset(), handleSearch(), handleTabC
 Cohesion: 0.24
 Nodes (8): fullFileUrl(), handlePreviewAttachment(), isVideoFile(), normalizeDisplayValue(), resolveReviewCellType(), resolveReviewQuantity(), resolveReviewSpecText(), uniqueJoined()
 
-### Community 43 - "Community 43"
-Cohesion: 0.2
-Nodes (4): personTitle(), signBadge(), signBadgeText(), statusText()
-
-### Community 44 - "Community 44"
+### Community 42 - "Community 42"
 Cohesion: 0.25
 Nodes (2): handleTouchEnd(), setTransition()
 
-### Community 45 - "Community 45"
-Cohesion: 0.28
-Nodes (1): FireworkSystem
-
-### Community 47 - "Community 47"
-Cohesion: 0.31
-Nodes (4): annotateForkEdges(), chainApiToElements(), walkAncestorBranch(), walkAncestorParents()
-
-### Community 50 - "Community 50"
+### Community 46 - "Community 46"
 Cohesion: 0.39
 Nodes (6): isIgnorableScriptError(), normalizeErrorMessage(), registerPromiseErrorHandler(), registerResourceErrorHandler(), scriptErrorHandler(), setupErrorHandle()
 
-### Community 51 - "Community 51"
+### Community 47 - "Community 47"
 Cohesion: 0.36
 Nodes (1): TableHeightCalculator
 
-### Community 53 - "Community 53"
+### Community 49 - "Community 49"
 Cohesion: 0.33
 Nodes (2): logApiCryptoBootInfo(), maskSecret()
 
-### Community 54 - "Community 54"
+### Community 50 - "Community 50"
 Cohesion: 0.38
 Nodes (4): handleFocus(), handleInput(), parseDecimalToNumber(), sanitizeDecimalInput()
 
-### Community 55 - "Community 55"
+### Community 51 - "Community 51"
+Cohesion: 0.29
+Nodes (2): fetchLeaveDetail(), fetchLeaveList()
+
+### Community 52 - "Community 52"
 Cohesion: 0.4
 Nodes (2): isUnfinishedQcWorkOrder(), resolveQcWorkOrderUnfinishedBadgeCount()
 
-### Community 56 - "Community 56"
+### Community 53 - "Community 53"
 Cohesion: 0.47
 Nodes (3): isPaymentDueWithinWarnWindow(), parsePaymentDueYmd(), startOfLocalDay()
 
-### Community 57 - "Community 57"
+### Community 54 - "Community 54"
 Cohesion: 0.5
 Nodes (2): formatProtocolDocDeleteConfirm(), formatProtocolDocSubject()
 
-### Community 58 - "Community 58"
+### Community 55 - "Community 55"
 Cohesion: 0.5
 Nodes (2): parseEquipmentIds(), syncEquipmentNamesFromOptions()
 
-### Community 60 - "Community 60"
+### Community 57 - "Community 57"
 Cohesion: 0.5
 Nodes (2): focusInput(), handleKeydown()
 
-### Community 64 - "Community 64"
+### Community 58 - "Community 58"
+Cohesion: 0.4
+Nodes (1): fetchQcMaterialAmountAuthUsers()
+
+### Community 62 - "Community 62"
 Cohesion: 0.67
 Nodes (2): if(), logSidebarMenu()
 
-### Community 66 - "Community 66"
+### Community 64 - "Community 64"
 Cohesion: 0.5
 Nodes (1): fetchStorageEntrySmsList()
 
+### Community 65 - "Community 65"
+Cohesion: 0.5
+Nodes (1): fetchSampleSmsNotificationList()
+
+### Community 66 - "Community 66"
+Cohesion: 0.5
+Nodes (1): fetchQcSmsList()
+
 ### Community 70 - "Community 70"
 Cohesion: 1.0
 Nodes (2): getSettingDefaults(), resetToDefaults()
@@ -339,40 +339,46 @@ Nodes (2): copyTextToClipboard(), copyTextWithFallback()
 Cohesion: 1.0
 Nodes (2): getSourceProtocolAttachment(), normalizeAttachmentFiles()
 
-### Community 82 - "Community 82"
+### Community 84 - "Community 84"
 Cohesion: 1.0
 Nodes (2): emptyTabCounts(), useProductionWorkOrderTabStepCounts()
 
-### Community 84 - "Community 84"
+### Community 86 - "Community 86"
 Cohesion: 1.0
 Nodes (2): initialProgress(), useQcWorkOrderAttachmentExport()
 
-### Community 85 - "Community 85"
+### Community 87 - "Community 87"
 Cohesion: 1.0
 Nodes (2): emptyTabCounts(), useQcWorkOrderTabUnfinishedCounts()
 
 ## Knowledge Gaps
-- **Thin community `Community 21`** (42 nodes): `WebSocketClient`, `.calculateReconnectDelay()`, `.clearAllTimers()`, `.clearConnectionTimers()`, `.clearTimer()`, `.close()`, `.closeCurrentSocketForReconnect()`, `.connect()`, `.connectionStatusText()`, `.constructor()`, `.destroyInstance()`, `.flushMessageQueue()`, `.getInstance()`, `.getReadyStateText()`, `.handleClose()`, `.handleConnectionTimeout()`, `.handleError()`, `.handleMessage()`, `.handleOpen()`, `.init()`, `.isWebSocketConnected()`, `.reconnect()`, `.resetHeartbeat()`, `.send()`, `.startHeartbeat()`, `.startPing()`, `TableCache`, `.cleanupExpired()`, `.clear()`, `.clearByTags()`, `.clearCurrentSearch()`, `.clearPagination()`, `.constructor()`, `.evictLRU()`, `.generateKey()`, `.generateTags()`, `.get()`, `.getStats()`, `.log()`, `.set()`, `index.ts`, `tableCache.ts`
+- **Thin community `Community 20`** (42 nodes): `WebSocketClient`, `.calculateReconnectDelay()`, `.clearAllTimers()`, `.clearConnectionTimers()`, `.clearTimer()`, `.close()`, `.closeCurrentSocketForReconnect()`, `.connect()`, `.connectionStatusText()`, `.constructor()`, `.destroyInstance()`, `.flushMessageQueue()`, `.getInstance()`, `.getReadyStateText()`, `.handleClose()`, `.handleConnectionTimeout()`, `.handleError()`, `.handleMessage()`, `.handleOpen()`, `.init()`, `.isWebSocketConnected()`, `.reconnect()`, `.resetHeartbeat()`, `.send()`, `.startHeartbeat()`, `.startPing()`, `TableCache`, `.cleanupExpired()`, `.clear()`, `.clearByTags()`, `.clearCurrentSearch()`, `.clearPagination()`, `.constructor()`, `.evictLRU()`, `.generateKey()`, `.generateTags()`, `.get()`, `.getStats()`, `.log()`, `.set()`, `index.ts`, `tableCache.ts`
+  Too small to be a meaningful cluster - may be noise or needs more connections extracted.
+- **Thin community `Community 42`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
+  Too small to be a meaningful cluster - may be noise or needs more connections extracted.
+- **Thin community `Community 47`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
+  Too small to be a meaningful cluster - may be noise or needs more connections extracted.
+- **Thin community `Community 49`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 44`** (9 nodes): `cleanupEventListeners()`, `handleTouchEnd()`, `handleTouchMove()`, `handleTouchStart()`, `handleWheelScroll()`, `if()`, `setTransition()`, `setupEventListeners()`, `index.vue`
+- **Thin community `Community 51`** (7 nodes): `fetchCreateLeave()`, `fetchDeleteLeave()`, `fetchLeaveDetail()`, `fetchLeaveList()`, `fetchSubmitLeave()`, `fetchUpdateLeave()`, `leave.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 45`** (9 nodes): `FireworkSystem`, `.constructor()`, `.createFirework()`, `.createParticle()`, `.getAvailableParticle()`, `.initializePool()`, `.preloadAllImages()`, `.preloadImage()`, `index.vue`
+- **Thin community `Community 52`** (6 nodes): `formatQcWorkOrderUnfinishedBadgeCount()`, `isUnfinishedQcWorkOrder()`, `qcWorkOrderUnfinishedBadgeTitle()`, `resolveQcWorkOrderUnfinishedBadgeCount()`, `sumQcWorkOrderGroupUnfinishedBadgeCount()`, `qc-work-order-unfinished-badge.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 51`** (8 nodes): `TableHeightCalculator`, `.calculate()`, `.calculateOffset()`, `.calculatePaginationOffset()`, `.constructor()`, `.getHeaderHeight()`, `useTableHeight()`, `useTableHeight.ts`
+- **Thin community `Community 54`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 53`** (7 nodes): `App.vue`, `main.ts`, `refreshButtonAutoIcons()`, `refreshPanelTitleIcons()`, `logApiCryptoBootInfo()`, `maskSecret()`, `console.ts`
+- **Thin community `Community 55`** (5 nodes): `equipmentOptionLabel()`, `joinEquipmentIds()`, `parseEquipmentIds()`, `syncEquipmentNamesFromOptions()`, `equipment-select.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 55`** (6 nodes): `formatQcWorkOrderUnfinishedBadgeCount()`, `isUnfinishedQcWorkOrder()`, `qcWorkOrderUnfinishedBadgeTitle()`, `resolveQcWorkOrderUnfinishedBadgeCount()`, `sumQcWorkOrderGroupUnfinishedBadgeCount()`, `qc-work-order-unfinished-badge.ts`
+- **Thin community `Community 57`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 57`** (5 nodes): `formatProtocolDocBatchDeleteConfirm()`, `formatProtocolDocDeleteConfirm()`, `formatProtocolDocSubject()`, `getProtocolDocTypeLabel()`, `protocol-doc-label.ts`
+- **Thin community `Community 58`** (5 nodes): `fetchBatchRevokeQcMaterialAmountAuth()`, `fetchGrantQcMaterialAmountAuth()`, `fetchQcMaterialAmountAuthUsers()`, `fetchRevokeQcMaterialAmountAuth()`, `qc-material-amount-auth.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 58`** (5 nodes): `equipmentOptionLabel()`, `joinEquipmentIds()`, `parseEquipmentIds()`, `syncEquipmentNamesFromOptions()`, `equipment-select.ts`
+- **Thin community `Community 62`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 60`** (5 nodes): `focusInput()`, `handleKeydown()`, `if()`, `search()`, `index.vue`
+- **Thin community `Community 64`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 64`** (4 nodes): `if()`, `logSidebarMenu()`, `index.vue`, `SidebarSubmenu.vue`
+- **Thin community `Community 65`** (4 nodes): `fetchGenerateSms()`, `fetchSampleSmsNotificationList()`, `fetchToggleSmsNotified()`, `sample-sms-notification.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 66`** (4 nodes): `fetchGenerateStorageEntrySms()`, `fetchStorageEntrySmsList()`, `fetchToggleStorageEntrySmsNotified()`, `storage-entry-sms-notification.ts`
+- **Thin community `Community 66`** (4 nodes): `fetchGenerateQcSms()`, `fetchQcSmsList()`, `fetchToggleQcSmsNotified()`, `qc-sms-notification.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
 - **Thin community `Community 70`** (3 nodes): `getSettingDefaults()`, `resetToDefaults()`, `setting.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
@@ -380,27 +386,27 @@ Nodes (2): emptyTabCounts(), useQcWorkOrderTabUnfinishedCounts()
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
 - **Thin community `Community 73`** (3 nodes): `getSourceProtocolAttachment()`, `normalizeAttachmentFiles()`, `protocol-source-attachment.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 82`** (3 nodes): `emptyTabCounts()`, `useProductionWorkOrderTabStepCounts()`, `useProductionWorkOrderTabStepCounts.ts`
+- **Thin community `Community 84`** (3 nodes): `emptyTabCounts()`, `useProductionWorkOrderTabStepCounts()`, `useProductionWorkOrderTabStepCounts.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 84`** (3 nodes): `initialProgress()`, `useQcWorkOrderAttachmentExport()`, `useQcWorkOrderAttachmentExport.ts`
+- **Thin community `Community 86`** (3 nodes): `initialProgress()`, `useQcWorkOrderAttachmentExport()`, `useQcWorkOrderAttachmentExport.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
-- **Thin community `Community 85`** (3 nodes): `emptyTabCounts()`, `useQcWorkOrderTabUnfinishedCounts()`, `useQcWorkOrderTabUnfinishedCounts.ts`
+- **Thin community `Community 87`** (3 nodes): `emptyTabCounts()`, `useQcWorkOrderTabUnfinishedCounts()`, `useQcWorkOrderTabUnfinishedCounts.ts`
   Too small to be a meaningful cluster - may be noise or needs more connections extracted.
 
 ## Suggested Questions
 _Questions this graph is uniquely positioned to answer:_
 
-- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 17`, `Community 18`, `Community 19`, `Community 20`, `Community 22`, `Community 26`, `Community 27`, `Community 28`, `Community 29`, `Community 30`, `Community 32`, `Community 34`, `Community 35`, `Community 37`, `Community 40`, `Community 47`, `Community 66`?**
-  _High betweenness centrality (0.248) - this node is a cross-community bridge._
-- **Why does `push()` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 7`, `Community 8`, `Community 10`, `Community 11`, `Community 12`, `Community 14`, `Community 16`, `Community 17`, `Community 19`, `Community 20`, `Community 21`, `Community 22`, `Community 23`, `Community 25`, `Community 27`, `Community 28`, `Community 30`, `Community 36`, `Community 45`?**
-  _High betweenness centrality (0.227) - this node is a cross-community bridge._
-- **Why does `handleDynamicRoutes()` connect `Community 6` to `Community 8`, `Community 28`, `Community 29`, `Community 30`?**
-  _High betweenness centrality (0.041) - this node is a cross-community bridge._
-- **Are the 290 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
-  _`get()` has 290 INFERRED edges - model-reasoned connections that need verification._
-- **Are the 91 inferred relationships involving `push()` (e.g. with `refreshQcMenuBadges()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
-  _`push()` has 91 INFERRED edges - model-reasoned connections that need verification._
-- **Are the 27 inferred relationships involving `emit()` (e.g. with `handleSubmit()` and `handleDialogClose()`) actually correct?**
-  _`emit()` has 27 INFERRED edges - model-reasoned connections that need verification._
-- **Are the 19 inferred relationships involving `set()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
-  _`set()` has 19 INFERRED edges - model-reasoned connections that need verification._
+- **Why does `push()` connect `Community 2` to `Community 0`, `Community 1`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 11`, `Community 12`, `Community 13`, `Community 14`, `Community 15`, `Community 17`, `Community 20`, `Community 21`, `Community 24`, `Community 28`, `Community 29`, `Community 30`, `Community 34`, `Community 35`?**
+  _High betweenness centrality (0.295) - this node is a cross-community bridge._
+- **Why does `get()` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`, `Community 7`, `Community 8`, `Community 9`, `Community 10`, `Community 11`, `Community 13`, `Community 14`, `Community 15`, `Community 16`, `Community 17`, `Community 18`, `Community 19`, `Community 25`, `Community 26`, `Community 28`, `Community 29`, `Community 30`, `Community 32`, `Community 33`, `Community 39`, `Community 51`, `Community 58`, `Community 64`, `Community 65`, `Community 66`?**
+  _High betweenness centrality (0.277) - this node is a cross-community bridge._
+- **Why does `handleDynamicRoutes()` connect `Community 9` to `Community 2`, `Community 6`, `Community 23`, `Community 29`, `Community 30`?**
+  _High betweenness centrality (0.042) - this node is a cross-community bridge._
+- **Are the 293 inferred relationships involving `get()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
+  _`get()` has 293 INFERRED edges - model-reasoned connections that need verification._
+- **Are the 95 inferred relationships involving `push()` (e.g. with `refreshQcMenuBadges()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
+  _`push()` has 95 INFERRED edges - model-reasoned connections that need verification._
+- **Are the 28 inferred relationships involving `emit()` (e.g. with `handleSubmit()` and `handleDialogClose()`) actually correct?**
+  _`emit()` has 28 INFERRED edges - model-reasoned connections that need verification._
+- **Are the 20 inferred relationships involving `set()` (e.g. with `buildNodeCodePathFromFlat()` and `collectLeafFacilityNodesInTreeOrder()`) actually correct?**
+  _`set()` has 20 INFERRED edges - model-reasoned connections that need verification._

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
web-admin/graphify-out/graph.html


Разница между файлами не показана из-за своего большого размера
+ 195 - 114
web-admin/graphify-out/graph.json


+ 21 - 15
web-admin/graphify-out/manifest.json

@@ -1,6 +1,6 @@
 {
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/App.vue": 1782893851.4905877,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/main.ts": 1784274843.7468073,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/main.ts": 1784710978.3545387,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/env.d.ts": 1781272556.3788364,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/shims-loose.d.ts": 1781272556.417826,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/directives/index.ts": 1781272556.3521712,
@@ -17,8 +17,8 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/common/index.ts": 1781272556.3597305,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/directive/directive.d.ts": 1781272556.3601494,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/api/api.d.ts": 1781272556.3606477,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1784686266.7518713,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1784686242.3599403,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/components.d.ts": 1784789058.1868522,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/import/auto-imports.d.ts": 1784785052.6011834,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/store/index.ts": 1781272556.364766,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/types/router/index.ts": 1782394569.8806834,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/composables/useAttachmentActions.ts": 1783921717.4015942,
@@ -50,6 +50,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/fullscreen-loading.ts": 1781272556.3849921,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-numeral-parse.ts": 1782960575.662593,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sample-production-reception-fields.ts": 1782806741.4880455,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/oa-approval-print-related.ts": 1784732529.7353477,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-material-ui.ts": 1781525352.6976836,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-tabs.ts": 1783326303.9709864,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/qc-work-order-unfinished-badge.ts": 1782878267.729195,
@@ -84,9 +85,10 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/mask-sensitive.ts": 1781272556.4029639,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/sample-reception-view-sections.ts": 1783389099.9667985,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-labels.ts": 1783306730.912153,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/oa-approval-print.ts": 1784276981.3083122,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/oa-approval-print.ts": 1784790919.6282659,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/inbound-sample-special-mark.ts": 1782889894.1376855,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-work-order-category.ts": 1783393556.2431076,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/oa-related-approval-rule.ts": 1784714034.8219328,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-menu-badge.ts": 1783307225.4832592,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/attachment-zip.ts": 1782875325.855345,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/numeric-input-parse.ts": 1782179343.5953708,
@@ -105,10 +107,12 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-fq-params-change.ts": 1781687645.2065177,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/oa-form-create-upload.ts": 1784277173.1550035,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-flow-steps.ts": 1782806499.3099828,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/oa-form-create-related-approval.ts": 1784710930.181968,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/loginRsa.ts": 1781272556.4129546,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/chinese-datetime-parse.ts": 1782958233.483039,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/production-task-editor-cache.ts": 1782602746.754815,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-pay-mode-switch.ts": 1783329869.6204023,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/oa-progress-person-lines.ts": 1784790917.6300406,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-payment-installment.ts": 1783329873.2829163,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/protocol-source-attachment.ts": 1783921716.666595,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/download-attachment.ts": 1781272556.4160507,
@@ -147,7 +151,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/socket/index.ts": 1781272556.4146817,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/utils/router/sidebar-menu-filter.ts": 1781272556.4163456,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/oa-fc-host/App.vue": 1784273205.773055,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/oa-fc-host/main.ts": 1784274843.746828,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/oa-fc-host/main.ts": 1784710978.6271818,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/tables/art-table/index.vue": 1782893852.037499,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/tables/art-table-header/index.vue": 1782893852.0053234,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/core/forms/art-search-bar/index.vue": 1782893851.915658,
@@ -261,12 +265,14 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/list-datetime-column.vue": 1782893851.4989195,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/amount-input/index.vue": 1782893851.5061834,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/common/decimal-input/index.vue": 1782893851.5090024,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaFlowPreview.vue": 1784276122.848332,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaFlowPreview.vue": 1784794440.8679106,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/oa-condition-fields.ts": 1784272584.166454,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaApprovalPrintSheet.vue": 1784108772.892926,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaApprovalPrintSheet.vue": 1784787305.0324392,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaPrintRelatedTree.vue": 1784732622.1574717,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaFcRow.vue": 1784277170.6285605,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaFormDesignerEmbed.vue": 1784271049.82102,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaProgressChain.vue": 1784277516.7419543,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaRelatedApproval.vue": 1784732439.374116,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/OaProgressChain.vue": 1784790920.0893972,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/flow-tree/FlowBranch.vue": 1784273803.9009435,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/flow-tree/ConditionRuleEditor.vue": 1784273504.6858127,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/components/oa-approval/flow-tree/FlowDesigner.vue": 1784273804.1612618,
@@ -314,7 +320,7 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-lab-test-item.ts": 1781272556.666375,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/cell-product.ts": 1782710852.6608956,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/sample-sms-notification.ts": 1781272556.666838,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/oaApproval.ts": 1784276081.4709907,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/oaApproval.ts": 1784794285.846623,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/material-stock-check.ts": 1781427280.4992144,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/research-donation.ts": 1782893816.502791,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/api/qc-task.ts": 1783327864.9737554,
@@ -399,16 +405,16 @@
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/dept/index.vue": 1784018212.022131,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/dict/index.vue": 1783326448.9326534,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/system/leave/index.vue": 1783326448.934463,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/start/index.vue": 1784276545.557209,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/start/index.vue": 1784794765.2458756,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/roles/index.vue": 1784269877.2911904,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/form-designer-spike/index.vue": 1784018202.8769164,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/done/index.vue": 1784102239.4821205,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/mine/index.vue": 1784173366.0358684,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/done/index.vue": 1784791080.19711,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/mine/index.vue": 1784791078.6245425,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/designer/index.vue": 1784271066.9590933,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/instances/detail.vue": 1784276981.3081641,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/cc/index.vue": 1784173366.0354402,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/instances/detail.vue": 1784791022.6888332,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/cc/index.vue": 1784791079.648433,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/apps/index.vue": 1784260925.8786883,
-  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/pending/index.vue": 1784102236.6623435,
+  "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/oa-approval/pending/index.vue": 1784791081.2430966,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/output-type/index.vue": 1782893852.8585393,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/index.vue": 1783326448.9373286,
   "/Users/wuzilong/work/00code/zkxw/web-admin/src/views/production/cell-product/SourceChainGraph.vue": 1782893852.699336,

+ 17 - 52
web-admin/src/views/oa-approval/start/index.vue

@@ -98,27 +98,6 @@
         :close-on-click-modal="false"
       >
         <div v-loading="detailLoading">
-          <el-form v-if="needInitiatorSelect" label-position="top" class="oa-start__meta">
-            <el-form-item label="自选审批人" required>
-              <el-select
-                v-model="initiatorSelectUserIds"
-                multiple
-                filterable
-                collapse-tags
-                collapse-tags-tooltip
-                placeholder="请选择审批人"
-                style="width: 100%"
-                :loading="userLoading"
-              >
-                <el-option
-                  v-for="u in userOptions"
-                  :key="u.id"
-                  :label="`${u.nickName}(${u.userNo})`"
-                  :value="u.id"
-                />
-              </el-select>
-            </el-form-item>
-          </el-form>
           <form-create
             v-if="formRule.length"
             v-model="formData"
@@ -129,10 +108,13 @@
           <p v-else-if="!detailLoading" class="oa-start__tip">该模板暂无表单字段,仍可直接提交。</p>
           <OaFlowPreview
             v-if="!detailLoading"
+            v-model:select-by-node="initiatorSelectByNode"
             :steps="flowSteps"
             :loading="previewLoading"
             :resolved="flowResolved"
             :pending-message="flowPendingMessage"
+            :user-options="userOptions"
+            @select-change="scheduleFlowPreview"
           />
         </div>
         <template #footer>
@@ -195,8 +177,7 @@
   const fapi = ref<any>(null)
   const submitting = ref(false)
   const needInitiatorSelect = ref(false)
-  const initiatorSelectUserIds = ref<string[]>([])
-  const userLoading = ref(false)
+  const initiatorSelectByNode = ref<Record<string, string[]>>({})
   const userOptions = ref<Array<{ id: string; nickName: string; userNo: string }>>([])
   const flowSteps = ref<OaFlowPreviewStep[]>([])
   const flowResolved = ref(true)
@@ -254,7 +235,6 @@
   }
 
   async function loadUsers() {
-    userLoading.value = true
     try {
       const pageSize = MAX_ADMIN_LIST_PAGE_SIZE
       const raw: any[] = []
@@ -272,8 +252,8 @@
         nickName: u.nickName || '',
         userNo: u.userNo || ''
       }))
-    } finally {
-      userLoading.value = false
+    } catch {
+      userOptions.value = []
     }
   }
 
@@ -282,8 +262,7 @@
     try {
       const preview = await fetchOaFlowPreview(appId, {
         formData: { ...formData.value },
-        // Task 4: API 已切到按节点 map;完整 UI 见 Task 5–6
-        initiatorSelectByNode: {}
+        initiatorSelectByNode: { ...initiatorSelectByNode.value }
       })
       flowResolved.value = preview?.resolved !== false
       flowPendingMessage.value =
@@ -310,7 +289,7 @@
     formData.value = {}
     formRule.value = []
     needInitiatorSelect.value = false
-    initiatorSelectUserIds.value = []
+    initiatorSelectByNode.value = {}
     flowSteps.value = []
     flowResolved.value = false
     flowPendingMessage.value = '必填信息填写后,流程将自动显示'
@@ -366,21 +345,16 @@
     { deep: true }
   )
 
-  watch(
-    initiatorSelectUserIds,
-    () => {
-      if (dlgVisible.value && picked.value?.id && needInitiatorSelect.value) {
-        scheduleFlowPreview()
-      }
-    },
-    { deep: true }
-  )
-
   async function submit() {
     if (!picked.value?.id) return
-    if (needInitiatorSelect.value && !initiatorSelectUserIds.value.length) {
-      ElMessage.warning('请选择自选审批人')
-      return
+    for (const s of flowSteps.value) {
+      if (s.type === 'approval' && s.assigneeType === 'initiator_select') {
+        const ids = initiatorSelectByNode.value[s.id] || []
+        if (!ids.length) {
+          ElMessage.warning(`请为「${s.name || '审批人'}」选择审批人`)
+          return
+        }
+      }
     }
     if (fapi.value?.validate) {
       try {
@@ -395,8 +369,7 @@
       const data: any = await fetchStartOaInstance({
         appId: picked.value.id,
         formData: { ...formData.value },
-        // Task 4: API 已切到按节点 map;完整 UI 见 Task 5–6
-        initiatorSelectByNode: {}
+        initiatorSelectByNode: { ...initiatorSelectByNode.value }
       })
       dlgVisible.value = false
       if (data?.id) {
@@ -673,14 +646,6 @@
     font-size: 13px;
   }
 
-  .oa-start__meta {
-    margin-bottom: 8px;
-
-    :deep(.el-form-item) {
-      margin-bottom: 12px;
-    }
-  }
-
   @media (max-width: 640px) {
     .oa-app-card {
       width: 100%;

Некоторые файлы не были показаны из-за большого количества измененных файлов