@opengeni/db 0.36.1 → 3.1.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attached-browser-devices.d.ts +7 -0
- package/dist/automations.d.ts +154 -0
- package/dist/canonical-human-identities.js +3 -3
- package/dist/capability-integrations.d.ts +13 -0
- package/dist/child-lifecycle-notices.d.ts +68 -0
- package/dist/{chunk-GYO7ED2Q.js → chunk-EULAN2NP.js} +2 -2
- package/dist/{chunk-VTPRIXKG.js → chunk-NJVZPWXY.js} +3 -3
- package/dist/{chunk-HSOWSYOX.js → chunk-NMUBV7Z5.js} +19 -11
- package/dist/chunk-NMUBV7Z5.js.map +1 -0
- package/dist/chunk-OF5OBB76.js +4457 -0
- package/dist/chunk-OF5OBB76.js.map +1 -0
- package/dist/{chunk-5KTIEDX7.js → chunk-PR2WMLOQ.js} +7714 -4443
- package/dist/chunk-PR2WMLOQ.js.map +1 -0
- package/dist/{chunk-Z7VYMNPZ.js → chunk-SCPUJS53.js} +41 -4
- package/dist/chunk-SCPUJS53.js.map +1 -0
- package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
- package/dist/chunk-SIBYBA2D.js.map +1 -0
- package/dist/chunk-TIKF3KTI.js +383 -0
- package/dist/chunk-TIKF3KTI.js.map +1 -0
- package/dist/chunk-ZZ5LJEFX.js +516 -0
- package/dist/chunk-ZZ5LJEFX.js.map +1 -0
- package/dist/codemode-operations.d.ts +1 -6
- package/dist/company-brain-context-selection-schema.d.ts +705 -0
- package/dist/company-brain-context-selection.d.ts +94 -0
- package/dist/company-brain-governed-writes.d.ts +24 -0
- package/dist/company-brain.d.ts +55 -0
- package/dist/company-profile-agent-admin.d.ts +15 -0
- package/dist/company-profile-schema.d.ts +619 -2
- package/dist/company-profile.d.ts +9 -4
- package/dist/connection-authority.d.ts +95 -0
- package/dist/connection-scopes.d.ts +8 -0
- package/dist/connection-tenancy-backfill.d.ts +41 -0
- package/dist/connection-token-resolver.d.ts +30 -1
- package/dist/database.d.ts +19 -0
- package/dist/editable-artifact-durable-export.d.ts +10 -0
- package/dist/editable-artifact-durable-export.js +18 -3
- package/dist/editable-artifact-durable-export.js.map +1 -1
- package/dist/editable-artifacts.d.ts +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/governed-learning-activation-schema.d.ts +984 -0
- package/dist/governed-learning-activation.d.ts +98 -0
- package/dist/governed-learning-evaluator-schema.d.ts +633 -0
- package/dist/governed-learning-evaluator.d.ts +28 -0
- package/dist/index.d.ts +1633 -87
- package/dist/index.js +22004 -8109
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +18 -0
- package/dist/integration-bindings.d.ts +1 -0
- package/dist/integration-facets.d.ts +30 -0
- package/dist/interaction-placement-loss.d.ts +22 -0
- package/dist/knowledge-source-sync-schema.d.ts +730 -0
- package/dist/knowledge-source-sync.d.ts +60 -0
- package/dist/managed-human-provisioning.d.ts +25 -0
- package/dist/memory-domain.d.ts +3 -3
- package/dist/migrate.d.ts +11 -1
- package/dist/migrate.js +1 -1
- package/dist/new-session-drafts.d.ts +43 -5
- package/dist/organization-membership-backfill.d.ts +174 -0
- package/dist/organization-membership-lifecycle.d.ts +162 -0
- package/dist/pr-review.d.ts +107 -0
- package/dist/preference-registry-schema.d.ts +2 -0
- package/dist/preference-registry.d.ts +2 -0
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +23 -9
- package/dist/schema.d.ts +24925 -13697
- package/dist/schema.js +103 -1
- package/dist/scoped-knowledge-schema.d.ts +52 -1
- package/dist/session-background-commands.d.ts +125 -0
- package/dist/session-background-commands.js +34 -0
- package/dist/session-background-commands.js.map +1 -0
- package/dist/session-control.d.ts +156 -3
- package/dist/session-goal-pacing.d.ts +68 -0
- package/dist/session-queue-commands.d.ts +42 -5
- package/dist/session-realtime-ledger.d.ts +3 -0
- package/dist/session-tenancy.d.ts +71 -1
- package/dist/session-tenancy.js +25 -3
- package/dist/session-tool-call-settlement.d.ts +9 -4
- package/dist/slack-routing-personal-workspace.d.ts +23 -0
- package/dist/slack-routing.d.ts +153 -0
- package/dist/slack-task-policy-schema.d.ts +34 -0
- package/dist/slack-task-policy.d.ts +8 -0
- package/dist/slack-user-link-access.d.ts +1 -0
- package/dist/task-notes-schema.d.ts +594 -0
- package/dist/task-notes.d.ts +39 -0
- package/dist/turn-initiator.d.ts +2 -0
- package/dist/user-resource-authority.d.ts +109 -0
- package/dist/video-generation.js +3 -3
- package/dist/workspace-authority.d.ts +81 -0
- package/dist/workspace-instruction-policies-schema.d.ts +279 -0
- package/dist/workspace-instruction-policies.d.ts +62 -0
- package/dist/workspace-learning-policy.d.ts +1 -0
- package/dist/workspace-membership-permissions.d.ts +2 -0
- package/drizzle/0240_enrollment_connection_authority.sql +39 -0
- package/drizzle/0240_model_context_user_messages.sql +204 -0
- package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
- package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
- package/drizzle/0243_google_drive_object_acl_authority.sql +554 -0
- package/drizzle/0244_slack_app_home_refresh_queue.sql +120 -0
- package/drizzle/0245_model_context_contribution_facts.sql +88 -0
- package/drizzle/0246_integration_personal_instance_authority.sql +70 -0
- package/drizzle/0247_terraform_stacks_provenance_repair.sql +428 -0
- package/drizzle/0248_terraform_stacks_component_resolution_fence.sql +83 -0
- package/drizzle/0249_personal_resource_delegation_authority_correction.sql +662 -0
- package/drizzle/0250_direct_retained_process_owner_liveness.sql +199 -0
- package/drizzle/0251_connected_machine_operation_policy.sql +45 -0
- package/drizzle/0252_scheduled_personal_resource_delegation.sql +1867 -0
- package/drizzle/0253_common_user_resource_authority_lifecycle.sql +1555 -0
- package/drizzle/0254_scoped_variable_set_authority.sql +1255 -0
- package/drizzle/0255_company_brain_governed_write_proposals.sql +524 -0
- package/drizzle/0256_connection_authority_delegation.sql +703 -0
- package/drizzle/0257_goal_revision_decisions_and_root_constraints.sql +436 -0
- package/drizzle/0258_three_scope_document_knowledge_authority.sql +1273 -0
- package/drizzle/0259_company_brain_context_selection_receipts.sql +869 -0
- package/drizzle/0260_task_note_knowledge_promotion.sql +820 -0
- package/drizzle/0261_preference_knowledge_proposal_actor_binding.sql +471 -0
- package/drizzle/0262_scoped_connected_machines_and_rigs.sql +1700 -0
- package/drizzle/0263_organization_membership_lifecycle.sql +3284 -0
- package/drizzle/0264_connection_authority_runtime_activation.sql +1084 -0
- package/drizzle/0266_company_brain_context_receipt_inspection.sql +156 -0
- package/drizzle/0268_governed_learning_decision_receipts.sql +825 -0
- package/drizzle/0269_governed_learning_activation_controller.sql +1874 -0
- package/drizzle/0270_governed_learning_history_inspection.sql +170 -0
- package/drizzle/0271_company_brain_retrieval_only_default.sql +524 -0
- package/drizzle/0272_human_confirmed_learning_activation.sql +591 -0
- package/drizzle/0273_scheduled_variable_set_materialization.sql +268 -0
- package/drizzle/0274_human_confirmed_knowledge_review.sql +310 -0
- package/drizzle/0275_scheduled_connection_authority.sql +5527 -0
- package/drizzle/0276_onboarding_proposal_initiating_human_guc.sql +198 -0
- package/drizzle/0277_workspace_writer_authority_attribution.sql +393 -0
- package/drizzle/0278_workspace_membership_removal_fencing.sql +1174 -0
- package/drizzle/0279_workspace_connection_use_lane.sql +343 -0
- package/drizzle/0280_connection_and_variable_set_audit_attribution.sql +773 -0
- package/drizzle/0281_viewer_holder_authority_claims.sql +52 -0
- package/drizzle/0282_variable_set_session_attach_attribution.sql +178 -0
- package/drizzle/0283_editable_spreadsheet_authored_state.sql +82 -0
- package/drizzle/0284_truthful_human_confirmed_review_reason.sql +930 -0
- package/drizzle/0285_organization_tenancy_inventory.sql +329 -0
- package/drizzle/0286_widen_task_note_expiry_ceiling.sql +391 -0
- package/drizzle/0287_open_suffix_pending_tool_calls.sql +18 -0
- package/drizzle/0288_attached_browser_reenrollment.sql +64 -0
- package/drizzle/0289_session_composer_policy_authority.sql +597 -0
- package/drizzle/0290_organization_membership_backfill.sql +268 -0
- package/drizzle/0291_resource_authority_classification_assertion.sql +371 -0
- package/drizzle/0292_truthful_tenancy_inventory_counters.sql +291 -0
- package/drizzle/0293_confirm_time_rule_rebaseline.sql +615 -0
- package/drizzle/0294_preference_activation_authority.sql +237 -0
- package/drizzle/0295_retire_legacy_standing_memory_mode.sql +476 -0
- package/drizzle/0296_force_rls_backfill_noop_repair.sql +215 -0
- package/drizzle/0297_session_ownership_classification_and_backfill.sql +752 -0
- package/drizzle/0298_organization_tenancy_parity.sql +609 -0
- package/drizzle/0299_organization_membership_lock_order.sql +291 -0
- package/drizzle/0300_tenancy_backfill_ledger.sql +459 -0
- package/drizzle/0301_session_snapshot_and_pin_visibility.sql +181 -0
- package/drizzle/0302_personal_workspace_session_ownership.sql +303 -0
- package/drizzle/0303_session_tenancy_product_activation.sql +919 -0
- package/drizzle/0304_personal_workspace_private_session_reads.sql +97 -0
- package/drizzle/0305_personal_resource_grant_management.sql +584 -0
- package/drizzle/0306_atomic_personal_resource_attachments.sql +1374 -0
- package/drizzle/0307_session_attention_state.sql +51 -0
- package/drizzle/0308_session_archives.sql +35 -0
- package/drizzle/0309_channel_project_pins.sql +6 -0
- package/drizzle/0310_channel_project_order.sql +27 -0
- package/drizzle/0311_company_scope_and_private_session_create.sql +656 -0
- package/drizzle/0312_quiescent_session_tree_deletion.sql +39 -0
- package/drizzle/0313_private_child_session_authority.sql +365 -0
- package/drizzle/0314_unregistered_organization_invitations.sql +606 -0
- package/drizzle/0315_personal_github_repository_selection.sql +624 -0
- package/drizzle/0316_human_confirmed_activation_resumed_generation.sql +869 -0
- package/drizzle/0317_session_goal_continuation_hold.sql +64 -0
- package/drizzle/0318_session_turn_startup_milestones.sql +115 -0
- package/drizzle/0319_event_triggered_automations.sql +254 -0
- package/drizzle/0320_pr_review_pack.sql +113 -0
- package/drizzle/0321_slack_bot_environment_display_name.sql +15 -0
- package/drizzle/0322_session_turns_unclaimed_prompt_trigger_index.sql +5 -0
- package/drizzle/0323_organization_private_session_enablement.sql +489 -0
- package/drizzle/0324_human_confirmed_company_profile_agent_admin.sql +856 -0
- package/drizzle/0325_child_lifecycle_notices.sql +44 -0
- package/drizzle/0326_interaction_operation_error_codes.sql +62 -0
- package/drizzle/0327_slack_first_task_hint.sql +29 -0
- package/drizzle/0328_session_background_commands.sql +590 -0
- package/drizzle/0329_slack_orchestration_delivery_events.sql +91 -0
- package/drizzle/0330_api_key_descriptions.sql +20 -0
- package/drizzle/0331_managed_organization_creation.sql +163 -0
- package/drizzle/0332_organization_shared_workspace_control_plane.sql +539 -0
- package/drizzle/0333_session_turn_prompt_routing.sql +45 -0
- package/drizzle/0334_connected_machine_workspace_root.sql +99 -0
- package/drizzle/0335_slack_workspace_routing.sql +460 -0
- package/drizzle/0336_atomic_session_fork_visibility.sql +667 -0
- package/drizzle/0337_slack_routed_action_handles.sql +189 -0
- package/drizzle/0338_atomic_connected_machine_attachments.sql +410 -0
- package/drizzle/0339_document_authority_reclassification.sql +1153 -0
- package/drizzle/0340_tenancy_backfill_activation_evidence.sql +1347 -0
- package/drizzle/0341_slack_routing_probe_organization_fence.sql +109 -0
- package/package.json +10 -6
- package/src/attached-browser-devices.ts +233 -5
- package/src/automations.ts +911 -0
- package/src/browser-sessions.ts +10 -0
- package/src/capability-integrations.ts +175 -1
- package/src/child-lifecycle-notices.ts +241 -0
- package/src/codemode-operations.ts +1 -35
- package/src/company-brain-context-selection-schema.ts +100 -0
- package/src/company-brain-context-selection.ts +359 -0
- package/src/company-brain-governed-writes.ts +1170 -0
- package/src/company-brain.ts +309 -0
- package/src/company-profile-agent-admin.ts +225 -0
- package/src/company-profile-schema.ts +121 -1
- package/src/company-profile.ts +21 -0
- package/src/computer-sessions.ts +10 -1
- package/src/connection-authority.ts +290 -0
- package/src/connection-scopes.ts +20 -0
- package/src/connection-tenancy-backfill.ts +81 -0
- package/src/connection-token-resolver.ts +263 -31
- package/src/database.ts +75 -2
- package/src/editable-artifact-durable-export.ts +27 -0
- package/src/editable-artifacts-schema.ts +10 -5
- package/src/editable-artifacts.ts +21 -11
- package/src/governed-learning-activation-schema.ts +121 -0
- package/src/governed-learning-activation.ts +588 -0
- package/src/governed-learning-evaluator-schema.ts +72 -0
- package/src/governed-learning-evaluator.ts +217 -0
- package/src/index.ts +12001 -1699
- package/src/insights.ts +107 -0
- package/src/integration-bindings.ts +88 -6
- package/src/integration-facets.ts +287 -84
- package/src/interaction-placement-loss.ts +234 -0
- package/src/knowledge-source-sync-schema.ts +83 -0
- package/src/knowledge-source-sync.ts +530 -0
- package/src/managed-human-provisioning.ts +116 -0
- package/src/memory-domain.ts +27 -32
- package/src/migrate.ts +77 -1
- package/src/new-session-drafts.ts +229 -35
- package/src/organization-membership-backfill.ts +735 -0
- package/src/organization-membership-lifecycle.ts +985 -0
- package/src/pr-review.ts +890 -0
- package/src/preference-registry.ts +31 -1
- package/src/provision-roles.ts +931 -24
- package/src/runtime-posture-cli.ts +2 -0
- package/src/runtime-posture.ts +1315 -52
- package/src/schema.ts +3336 -438
- package/src/scoped-knowledge-schema.ts +16 -8
- package/src/scoped-knowledge.ts +1 -1
- package/src/session-background-commands.ts +759 -0
- package/src/session-control.ts +640 -74
- package/src/session-goal-pacing.ts +126 -0
- package/src/session-queue-commands.ts +450 -98
- package/src/session-realtime-context.ts +19 -3
- package/src/session-realtime-ledger.ts +75 -12
- package/src/session-realtime-mirror.ts +1 -1
- package/src/session-tenancy.ts +403 -49
- package/src/session-tool-call-settlement.ts +38 -29
- package/src/slack-routing-personal-workspace.ts +67 -0
- package/src/slack-routing.ts +469 -0
- package/src/slack-task-policy-schema.ts +5 -0
- package/src/slack-task-policy.ts +18 -0
- package/src/slack-user-link-access.ts +17 -1
- package/src/task-notes-schema.ts +74 -0
- package/src/task-notes.ts +124 -2
- package/src/turn-initiator.ts +8 -0
- package/src/user-resource-authority.ts +377 -0
- package/src/workspace-authority.ts +160 -0
- package/src/workspace-instruction-policies-schema.ts +53 -1
- package/src/workspace-instruction-policies.ts +528 -77
- package/src/workspace-learning-policy.ts +21 -5
- package/src/workspace-membership-permissions.ts +9 -0
- package/dist/chunk-5KTIEDX7.js.map +0 -1
- package/dist/chunk-FPVAD4CO.js +0 -117
- package/dist/chunk-FPVAD4CO.js.map +0 -1
- package/dist/chunk-HSOWSYOX.js.map +0 -1
- package/dist/chunk-SK7YYHBI.js.map +0 -1
- package/dist/chunk-VKLB2ZGI.js +0 -2389
- package/dist/chunk-VKLB2ZGI.js.map +0 -1
- package/dist/chunk-Z7VYMNPZ.js.map +0 -1
- /package/dist/{chunk-GYO7ED2Q.js.map → chunk-EULAN2NP.js.map} +0 -0
- /package/dist/{chunk-VTPRIXKG.js.map → chunk-NJVZPWXY.js.map} +0 -0
package/src/insights.ts
CHANGED
|
@@ -82,6 +82,20 @@ export type ModelCallFacetRow = {
|
|
|
82
82
|
model: string;
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
+
export type ModelContextContributionAggregate = {
|
|
86
|
+
estimatedTokens: number;
|
|
87
|
+
utf8Bytes: number;
|
|
88
|
+
coveredCalls: number;
|
|
89
|
+
totalCalls: number;
|
|
90
|
+
sources: Array<{
|
|
91
|
+
source: string;
|
|
92
|
+
items: number;
|
|
93
|
+
utf8Bytes: number;
|
|
94
|
+
estimatedTokens: number;
|
|
95
|
+
calls: number;
|
|
96
|
+
}>;
|
|
97
|
+
};
|
|
98
|
+
|
|
85
99
|
export type SessionDepthAggregate = {
|
|
86
100
|
depth: number;
|
|
87
101
|
sessions: number;
|
|
@@ -645,6 +659,99 @@ export async function listRecentModelCalls(
|
|
|
645
659
|
});
|
|
646
660
|
}
|
|
647
661
|
|
|
662
|
+
export async function aggregateModelContextContributions(
|
|
663
|
+
db: Database,
|
|
664
|
+
input: InsightsTimeWindow & {
|
|
665
|
+
workspaceId: string;
|
|
666
|
+
provider?: string | null;
|
|
667
|
+
model?: string | null;
|
|
668
|
+
},
|
|
669
|
+
): Promise<ModelContextContributionAggregate> {
|
|
670
|
+
const context = await rlsContextForWorkspace(db, input.workspaceId);
|
|
671
|
+
return await withRlsContext(db, context, async (scopedDb) => {
|
|
672
|
+
const clauses = [
|
|
673
|
+
eq(schema.modelCallFacts.workspaceId, input.workspaceId),
|
|
674
|
+
gte(schema.modelCallFacts.occurredAt, input.since),
|
|
675
|
+
lt(schema.modelCallFacts.occurredAt, input.until),
|
|
676
|
+
...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
|
|
677
|
+
...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
|
|
678
|
+
];
|
|
679
|
+
type ContributionRow = {
|
|
680
|
+
total_calls: number | string;
|
|
681
|
+
covered_calls: number | string;
|
|
682
|
+
source: string | null;
|
|
683
|
+
items: number | string | null;
|
|
684
|
+
utf8_bytes: number | string | null;
|
|
685
|
+
estimated_tokens: number | string | null;
|
|
686
|
+
calls: number | string | null;
|
|
687
|
+
};
|
|
688
|
+
const rows = (await scopedDb.execute(sql<ContributionRow>`
|
|
689
|
+
with filtered as (
|
|
690
|
+
select
|
|
691
|
+
${schema.modelCallFacts.id} as id,
|
|
692
|
+
${schema.modelCallFacts.contextContributions} as context_contributions
|
|
693
|
+
from ${schema.modelCallFacts}
|
|
694
|
+
where ${and(...clauses)}
|
|
695
|
+
), coverage as (
|
|
696
|
+
select
|
|
697
|
+
count(*)::bigint as total_calls,
|
|
698
|
+
count(context_contributions)::bigint as covered_calls
|
|
699
|
+
from filtered
|
|
700
|
+
), source_rows as (
|
|
701
|
+
select
|
|
702
|
+
filtered.id,
|
|
703
|
+
contribution->>'source' as source,
|
|
704
|
+
(contribution->>'items')::bigint as items,
|
|
705
|
+
(contribution->>'utf8Bytes')::bigint as utf8_bytes,
|
|
706
|
+
(contribution->>'estimatedTokens')::bigint as estimated_tokens
|
|
707
|
+
from filtered
|
|
708
|
+
cross join lateral jsonb_array_elements(filtered.context_contributions) contribution
|
|
709
|
+
), source_totals as (
|
|
710
|
+
select
|
|
711
|
+
source,
|
|
712
|
+
sum(items)::bigint as items,
|
|
713
|
+
sum(utf8_bytes)::bigint as utf8_bytes,
|
|
714
|
+
sum(estimated_tokens)::bigint as estimated_tokens,
|
|
715
|
+
count(distinct id)::bigint as calls
|
|
716
|
+
from source_rows
|
|
717
|
+
group by source
|
|
718
|
+
)
|
|
719
|
+
select
|
|
720
|
+
coverage.total_calls,
|
|
721
|
+
coverage.covered_calls,
|
|
722
|
+
source_totals.source,
|
|
723
|
+
source_totals.items,
|
|
724
|
+
source_totals.utf8_bytes,
|
|
725
|
+
source_totals.estimated_tokens,
|
|
726
|
+
source_totals.calls
|
|
727
|
+
from coverage
|
|
728
|
+
left join source_totals on true
|
|
729
|
+
order by source_totals.estimated_tokens desc nulls last, source_totals.source
|
|
730
|
+
`)) as ContributionRow[];
|
|
731
|
+
const first = rows[0];
|
|
732
|
+
const sources = rows.flatMap((row) =>
|
|
733
|
+
row.source
|
|
734
|
+
? [
|
|
735
|
+
{
|
|
736
|
+
source: row.source,
|
|
737
|
+
items: Number(row.items ?? 0),
|
|
738
|
+
utf8Bytes: Number(row.utf8_bytes ?? 0),
|
|
739
|
+
estimatedTokens: Number(row.estimated_tokens ?? 0),
|
|
740
|
+
calls: Number(row.calls ?? 0),
|
|
741
|
+
},
|
|
742
|
+
]
|
|
743
|
+
: [],
|
|
744
|
+
);
|
|
745
|
+
return {
|
|
746
|
+
estimatedTokens: sources.reduce((sum, row) => sum + row.estimatedTokens, 0),
|
|
747
|
+
utf8Bytes: sources.reduce((sum, row) => sum + row.utf8Bytes, 0),
|
|
748
|
+
coveredCalls: Number(first?.covered_calls ?? 0),
|
|
749
|
+
totalCalls: Number(first?.total_calls ?? 0),
|
|
750
|
+
sources,
|
|
751
|
+
};
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
|
|
648
755
|
export async function aggregateScheduleFacts(
|
|
649
756
|
db: Database,
|
|
650
757
|
input: InsightsTimeWindow & {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
|
|
3
3
|
import { stableJson } from "@opengeni/contracts";
|
|
4
|
-
import { and, asc, eq, or, sql } from "drizzle-orm";
|
|
4
|
+
import { and, asc, eq, inArray, or, sql } from "drizzle-orm";
|
|
5
5
|
|
|
6
6
|
import type { Database } from "./database";
|
|
7
7
|
import { effectiveCapabilityOwnerSql } from "./capability-components";
|
|
@@ -184,6 +184,7 @@ export async function upsertIntegrationFacetBinding(
|
|
|
184
184
|
await addIntegrationFacetBindingOwner(db, created.id, input);
|
|
185
185
|
return { row: created, changed: true };
|
|
186
186
|
}
|
|
187
|
+
await assertPersonalBindingConnectionRebindAuthority(db, existing, input);
|
|
187
188
|
if (existing.bindingKey !== input.bindingKey) {
|
|
188
189
|
throw new IntegrationFacetBindingOwnershipConflictError(
|
|
189
190
|
"Integration runtime identity is already assigned to another instance",
|
|
@@ -244,11 +245,70 @@ export async function upsertIntegrationFacetBinding(
|
|
|
244
245
|
return { row, changed };
|
|
245
246
|
}
|
|
246
247
|
|
|
248
|
+
async function assertPersonalBindingConnectionRebindAuthority(
|
|
249
|
+
db: Database,
|
|
250
|
+
existing: typeof schema.integrationFacetBindings.$inferSelect,
|
|
251
|
+
input: Pick<
|
|
252
|
+
UpsertIntegrationFacetBindingInput,
|
|
253
|
+
"accountId" | "workspaceId" | "connectionId" | "createdBySubjectId"
|
|
254
|
+
>,
|
|
255
|
+
): Promise<void> {
|
|
256
|
+
const nextConnectionId = input.connectionId ?? null;
|
|
257
|
+
if (!existing.connectionId || existing.connectionId === nextConnectionId) return;
|
|
258
|
+
// Personal Connections are visible through the app role only to their exact
|
|
259
|
+
// subject, so a missing current row is an authority failure, not absence.
|
|
260
|
+
const [currentConnection] = await db
|
|
261
|
+
.select({ subjectId: schema.connections.subjectId })
|
|
262
|
+
.from(schema.connections)
|
|
263
|
+
.where(
|
|
264
|
+
and(
|
|
265
|
+
eq(schema.connections.id, existing.connectionId),
|
|
266
|
+
eq(schema.connections.accountId, input.accountId),
|
|
267
|
+
eq(schema.connections.workspaceId, input.workspaceId),
|
|
268
|
+
),
|
|
269
|
+
)
|
|
270
|
+
.limit(1);
|
|
271
|
+
if (!currentConnection) {
|
|
272
|
+
throw new IntegrationFacetBindingOwnershipConflictError(
|
|
273
|
+
"Personal Integration instance belongs to another subject and cannot be changed in place",
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
if (!currentConnection.subjectId) return;
|
|
277
|
+
if (currentConnection.subjectId !== input.createdBySubjectId || nextConnectionId === null) {
|
|
278
|
+
throw new IntegrationFacetBindingOwnershipConflictError(
|
|
279
|
+
"Personal Integration instance belongs to another subject and cannot be changed in place",
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
const [nextConnection] = await db
|
|
283
|
+
.select({ subjectId: schema.connections.subjectId })
|
|
284
|
+
.from(schema.connections)
|
|
285
|
+
.where(
|
|
286
|
+
and(
|
|
287
|
+
eq(schema.connections.id, nextConnectionId),
|
|
288
|
+
eq(schema.connections.accountId, input.accountId),
|
|
289
|
+
eq(schema.connections.workspaceId, input.workspaceId),
|
|
290
|
+
),
|
|
291
|
+
)
|
|
292
|
+
.limit(1);
|
|
293
|
+
if (!nextConnection || nextConnection.subjectId !== currentConnection.subjectId) {
|
|
294
|
+
throw new IntegrationFacetBindingOwnershipConflictError(
|
|
295
|
+
"Personal Integration instance Connection ownership cannot be changed",
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
247
300
|
export async function listIntegrationFacetBindingOwners(
|
|
248
301
|
db: Database,
|
|
249
302
|
bindingId: string,
|
|
250
303
|
): Promise<IntegrationFacetBindingOwner[]> {
|
|
251
|
-
return await
|
|
304
|
+
return (await listIntegrationFacetBindingOwnersForBindings(db, [bindingId])).get(bindingId) ?? [];
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export async function listIntegrationFacetBindingOwnersForBindings(
|
|
308
|
+
db: Database,
|
|
309
|
+
bindingIds: string[],
|
|
310
|
+
): Promise<Map<string, IntegrationFacetBindingOwner[]>> {
|
|
311
|
+
return await loadIntegrationFacetBindingOwnersForBindings(db, bindingIds, true);
|
|
252
312
|
}
|
|
253
313
|
|
|
254
314
|
async function loadIntegrationFacetBindingOwners(
|
|
@@ -256,8 +316,26 @@ async function loadIntegrationFacetBindingOwners(
|
|
|
256
316
|
bindingId: string,
|
|
257
317
|
effectiveOnly: boolean,
|
|
258
318
|
): Promise<IntegrationFacetBindingOwner[]> {
|
|
319
|
+
return (
|
|
320
|
+
(await loadIntegrationFacetBindingOwnersForBindings(db, [bindingId], effectiveOnly)).get(
|
|
321
|
+
bindingId,
|
|
322
|
+
) ?? []
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function loadIntegrationFacetBindingOwnersForBindings(
|
|
327
|
+
db: Database,
|
|
328
|
+
bindingIds: string[],
|
|
329
|
+
effectiveOnly: boolean,
|
|
330
|
+
): Promise<Map<string, IntegrationFacetBindingOwner[]>> {
|
|
331
|
+
const uniqueBindingIds = [...new Set(bindingIds)];
|
|
332
|
+
const ownersByBindingId = new Map(
|
|
333
|
+
uniqueBindingIds.map((bindingId) => [bindingId, [] as IntegrationFacetBindingOwner[]]),
|
|
334
|
+
);
|
|
335
|
+
if (uniqueBindingIds.length === 0) return ownersByBindingId;
|
|
259
336
|
const rows = await db
|
|
260
337
|
.select({
|
|
338
|
+
bindingId: schema.integrationFacetBindingOwners.bindingId,
|
|
261
339
|
kind: schema.integrationFacetBindingOwners.ownerKind,
|
|
262
340
|
id: schema.integrationFacetBindingOwners.ownerId,
|
|
263
341
|
removable: schema.integrationFacetBindingOwners.removable,
|
|
@@ -265,7 +343,7 @@ async function loadIntegrationFacetBindingOwners(
|
|
|
265
343
|
.from(schema.integrationFacetBindingOwners)
|
|
266
344
|
.where(
|
|
267
345
|
and(
|
|
268
|
-
|
|
346
|
+
inArray(schema.integrationFacetBindingOwners.bindingId, uniqueBindingIds),
|
|
269
347
|
effectiveOnly
|
|
270
348
|
? effectiveCapabilityOwnerSql(
|
|
271
349
|
schema.integrationFacetBindingOwners.ownerKind,
|
|
@@ -275,10 +353,11 @@ async function loadIntegrationFacetBindingOwners(
|
|
|
275
353
|
),
|
|
276
354
|
)
|
|
277
355
|
.orderBy(
|
|
356
|
+
asc(schema.integrationFacetBindingOwners.bindingId),
|
|
278
357
|
asc(schema.integrationFacetBindingOwners.ownerKind),
|
|
279
358
|
asc(schema.integrationFacetBindingOwners.ownerId),
|
|
280
359
|
);
|
|
281
|
-
|
|
360
|
+
for (const row of rows) {
|
|
282
361
|
if (
|
|
283
362
|
row.kind !== "direct" &&
|
|
284
363
|
row.kind !== "plugin" &&
|
|
@@ -287,8 +366,11 @@ async function loadIntegrationFacetBindingOwners(
|
|
|
287
366
|
) {
|
|
288
367
|
throw new Error(`Unknown Integration instance owner kind: ${row.kind}`);
|
|
289
368
|
}
|
|
290
|
-
|
|
291
|
-
|
|
369
|
+
ownersByBindingId
|
|
370
|
+
.get(row.bindingId)
|
|
371
|
+
?.push({ kind: row.kind, id: row.id, removable: row.removable });
|
|
372
|
+
}
|
|
373
|
+
return ownersByBindingId;
|
|
292
374
|
}
|
|
293
375
|
|
|
294
376
|
export async function removeIntegrationFacetBindingOwner(
|