@opengeni/db 1.0.2 → 1.2.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/artifact-catalog.d.ts +12 -0
- package/dist/canonical-human-identities.js +3 -3
- package/dist/capability-reconciliation.js +2 -2
- package/dist/{chunk-KH3TYDGY.js → chunk-3GAR5UN3.js} +2 -2
- package/dist/{chunk-UEQQ2WWU.js → chunk-3TGYFFZR.js} +3 -26
- package/dist/chunk-3TGYFFZR.js.map +1 -0
- package/dist/{chunk-F3YMVRF4.js → chunk-6EIEGHPK.js} +4 -4
- package/dist/{chunk-OQZOGCLG.js → chunk-CONWNUSL.js} +2 -2
- package/dist/{chunk-7S53WLPI.js → chunk-CYP72JTQ.js} +11 -4
- package/dist/{chunk-7S53WLPI.js.map → chunk-CYP72JTQ.js.map} +1 -1
- package/dist/{chunk-LDTQGYD2.js → chunk-FWQNHNOU.js} +54 -2
- package/dist/chunk-FWQNHNOU.js.map +1 -0
- package/dist/{chunk-KEDWSSNP.js → chunk-GDN5TSZP.js} +2 -2
- package/dist/{chunk-PQGTWFRF.js → chunk-JICUP7ZR.js} +2 -2
- package/dist/{chunk-NLSG7GGA.js → chunk-JLVWBIEM.js} +3 -3
- package/dist/{chunk-Y77PVZZD.js → chunk-LXPFNG4L.js} +2 -2
- package/dist/{chunk-56MYWKQV.js → chunk-O2Y5E5M3.js} +68 -32
- package/dist/chunk-O2Y5E5M3.js.map +1 -0
- package/dist/{chunk-7POTLB24.js → chunk-QFJNEXFL.js} +2 -2
- package/dist/{chunk-MACELCXG.js → chunk-UCIMHNII.js} +101 -21
- package/dist/chunk-UCIMHNII.js.map +1 -0
- package/dist/{chunk-OMHBVHX7.js → chunk-VDPCIFKL.js} +5 -5
- package/dist/{chunk-N5QCKHYL.js → chunk-YOYILDLY.js} +87 -19
- package/dist/chunk-YOYILDLY.js.map +1 -0
- package/dist/connect-attempts.js +3 -3
- package/dist/credit-balances.d.ts +18 -0
- package/dist/credit-promotion-policy.d.ts +10 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +35 -10
- package/dist/index.js +2432 -2255
- package/dist/index.js.map +1 -1
- package/dist/managed-auth-session-sets.js +3 -3
- package/dist/managed-user-setup.d.ts +1 -0
- package/dist/mcp-operations.js +2 -2
- package/dist/organization-integration-policy.js +3 -3
- package/dist/organization-membership-lifecycle.d.ts +1 -0
- package/dist/persistence-errors.d.ts +9 -6
- package/dist/provision-roles.js +1 -1
- package/dist/retained-provider-commands.js +6 -6
- package/dist/runtime-posture.d.ts +7 -6
- package/dist/schema.d.ts +214 -2
- package/dist/schema.js +5 -1
- package/dist/session-background-commands.js +4 -4
- package/dist/session-command-output.js +5 -5
- package/dist/session-event-slices.js +3 -3
- package/dist/session-mcp-credential-rotation.js +5 -5
- package/dist/session-tenancy.d.ts +6 -1
- package/dist/session-tenancy.js +3 -5
- package/dist/video-generation.js +3 -3
- package/dist/workspace-tool-defaults.js +4 -4
- package/drizzle/0610_artifact_catalog_pins.sql +165 -0
- package/drizzle/0611_universal_session_tenancy_activation.sql +166 -0
- package/drizzle/0612_scheduled_model_unavailable_refusal.sql +21 -0
- package/drizzle/0613_model_scoped_promotional_credits.sql +238 -0
- package/drizzle/0614_quiescence_command_containment.sql +7 -0
- package/drizzle/0615_credit_promotion_policy_validation.sql +63 -0
- package/package.json +7 -7
- package/src/artifact-catalog.ts +31 -5
- package/src/credit-balances.ts +109 -0
- package/src/credit-promotion-policy.ts +12 -0
- package/src/database.ts +81 -42
- package/src/index.ts +295 -79
- package/src/managed-user-setup.ts +8 -0
- package/src/organization-membership-lifecycle.ts +8 -0
- package/src/persistence-errors.ts +17 -6
- package/src/provision-roles.ts +25 -0
- package/src/runtime-posture-cli.ts +0 -2
- package/src/runtime-posture.ts +86 -27
- package/src/schema.ts +57 -1
- package/src/session-tenancy.ts +9 -31
- package/src/video-generation.ts +2 -7
- package/dist/chunk-56MYWKQV.js.map +0 -1
- package/dist/chunk-LDTQGYD2.js.map +0 -1
- package/dist/chunk-MACELCXG.js.map +0 -1
- package/dist/chunk-N5QCKHYL.js.map +0 -1
- package/dist/chunk-UEQQ2WWU.js.map +0 -1
- /package/dist/{chunk-KH3TYDGY.js.map → chunk-3GAR5UN3.js.map} +0 -0
- /package/dist/{chunk-F3YMVRF4.js.map → chunk-6EIEGHPK.js.map} +0 -0
- /package/dist/{chunk-OQZOGCLG.js.map → chunk-CONWNUSL.js.map} +0 -0
- /package/dist/{chunk-KEDWSSNP.js.map → chunk-GDN5TSZP.js.map} +0 -0
- /package/dist/{chunk-PQGTWFRF.js.map → chunk-JICUP7ZR.js.map} +0 -0
- /package/dist/{chunk-NLSG7GGA.js.map → chunk-JLVWBIEM.js.map} +0 -0
- /package/dist/{chunk-Y77PVZZD.js.map → chunk-LXPFNG4L.js.map} +0 -0
- /package/dist/{chunk-7POTLB24.js.map → chunk-QFJNEXFL.js.map} +0 -0
- /package/dist/{chunk-OMHBVHX7.js.map → chunk-VDPCIFKL.js.map} +0 -0
package/src/database.ts
CHANGED
|
@@ -6,6 +6,8 @@ import { drizzle } from "drizzle-orm/postgres-js";
|
|
|
6
6
|
import postgres from "postgres";
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
+
DatabaseTransactionError,
|
|
10
|
+
isDatabasePersistenceFailure,
|
|
9
11
|
runIdempotentPersistenceTransaction,
|
|
10
12
|
type IdempotentPersistenceTransactionOptions,
|
|
11
13
|
} from "./persistence-errors";
|
|
@@ -521,6 +523,39 @@ async function restoreRlsContextSettings(
|
|
|
521
523
|
}
|
|
522
524
|
}
|
|
523
525
|
|
|
526
|
+
/** Attribute only failures outside the application callback to our transaction
|
|
527
|
+
* driver. BEGIN/COMMIT/ROLLBACK can throw raw postgres.js errors, unlike ORM
|
|
528
|
+
* queries. This supplies provenance, never transaction retry permission. */
|
|
529
|
+
async function withDatabaseTransactionProvenance<T>(
|
|
530
|
+
db: Database,
|
|
531
|
+
fn: (db: Database) => Promise<T>,
|
|
532
|
+
transactionConfig?: PgTransactionConfig,
|
|
533
|
+
): Promise<T> {
|
|
534
|
+
let entered = false;
|
|
535
|
+
let callbackFailure: { error: unknown } | undefined;
|
|
536
|
+
try {
|
|
537
|
+
return await db.transaction(async (tx) => {
|
|
538
|
+
entered = true;
|
|
539
|
+
try {
|
|
540
|
+
return await fn(tx as unknown as Database);
|
|
541
|
+
} catch (error) {
|
|
542
|
+
callbackFailure = { error };
|
|
543
|
+
throw error;
|
|
544
|
+
}
|
|
545
|
+
}, transactionConfig);
|
|
546
|
+
} catch (error) {
|
|
547
|
+
// A provider/tool rejection propagated by a successful rollback is still
|
|
548
|
+
// the provider/tool's error, even if it has a connection-looking code.
|
|
549
|
+
if (callbackFailure && callbackFailure.error === error) throw error;
|
|
550
|
+
if (!isDatabasePersistenceFailure(error)) throw error;
|
|
551
|
+
throw new DatabaseTransactionError(
|
|
552
|
+
entered ? "settlement" : "admission",
|
|
553
|
+
error,
|
|
554
|
+
callbackFailure?.error,
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
524
559
|
export async function withRlsContext<T>(
|
|
525
560
|
db: Database,
|
|
526
561
|
context: RlsContext,
|
|
@@ -535,49 +570,53 @@ export async function withRlsContext<T>(
|
|
|
535
570
|
restoreParentScope ? "savepoint_admission" : "transaction_admission",
|
|
536
571
|
);
|
|
537
572
|
try {
|
|
538
|
-
return await
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
parentScope
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
await scoped
|
|
548
|
-
|
|
549
|
-
|
|
573
|
+
return await withDatabaseTransactionProvenance(
|
|
574
|
+
db,
|
|
575
|
+
async (tx) => {
|
|
576
|
+
admission("completed");
|
|
577
|
+
const setup = startDatabaseTiming("rls_setup");
|
|
578
|
+
const scoped = tx as unknown as Database;
|
|
579
|
+
let parentScope: RlsContextSettings | null;
|
|
580
|
+
try {
|
|
581
|
+
parentScope = restoreParentScope ? await readRlsContextSettings(scoped) : null;
|
|
582
|
+
await setRlsContext(scoped, context);
|
|
583
|
+
if (context.workspaceId && sessionTenancyFence === "shared") {
|
|
584
|
+
await scoped.execute(
|
|
585
|
+
sql`select pg_advisory_xact_lock_shared(hashtextextended(${`session-tenancy:${context.workspaceId}`}, 0))`,
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
// Defense-in-depth: read the LOCAL GUC back on THIS backend BEFORE running
|
|
589
|
+
// the scoped query. The set_config and this read share one db.transaction,
|
|
590
|
+
// which a transaction pooler pins to a single backend — so a mismatch here
|
|
591
|
+
// means the context was genuinely lost (a torn transaction / pooler backend
|
|
592
|
+
// swap), not normal operation. Without this guard such an event runs the
|
|
593
|
+
// scoped read with an empty account_id and returns zero RLS-visible rows,
|
|
594
|
+
// manufacturing a phantom "no active subscription" from a credential that is
|
|
595
|
+
// in fact active. Convert that silent false into a loud, root-cause-bearing
|
|
596
|
+
// error so the caller can retry rather than permanently mis-decide.
|
|
597
|
+
await assertRlsContextApplied(scoped, context);
|
|
598
|
+
setup("completed");
|
|
599
|
+
} catch (error) {
|
|
600
|
+
setup("failed");
|
|
601
|
+
throw error;
|
|
550
602
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
try {
|
|
569
|
-
value = await fn(scoped);
|
|
570
|
-
callback("completed");
|
|
571
|
-
} catch (error) {
|
|
572
|
-
callback("failed");
|
|
573
|
-
throw error;
|
|
574
|
-
}
|
|
575
|
-
// A nested transaction is a savepoint, and SET LOCAL survives successful
|
|
576
|
-
// savepoint release. Restore the parent tenant and actor proof together;
|
|
577
|
-
// writer/protocol capabilities intentionally remain transaction-wide.
|
|
578
|
-
if (parentScope) await restoreRlsContextSettings(scoped, parentScope);
|
|
579
|
-
return value;
|
|
580
|
-
}, transactionConfig);
|
|
603
|
+
const callback = startDatabaseTiming("scoped_callback");
|
|
604
|
+
let value: T;
|
|
605
|
+
try {
|
|
606
|
+
value = await fn(scoped);
|
|
607
|
+
callback("completed");
|
|
608
|
+
} catch (error) {
|
|
609
|
+
callback("failed");
|
|
610
|
+
throw error;
|
|
611
|
+
}
|
|
612
|
+
// A nested transaction is a savepoint, and SET LOCAL survives successful
|
|
613
|
+
// savepoint release. Restore the parent tenant and actor proof together;
|
|
614
|
+
// writer/protocol capabilities intentionally remain transaction-wide.
|
|
615
|
+
if (parentScope) await restoreRlsContextSettings(scoped, parentScope);
|
|
616
|
+
return value;
|
|
617
|
+
},
|
|
618
|
+
transactionConfig,
|
|
619
|
+
);
|
|
581
620
|
} catch (error) {
|
|
582
621
|
// No-op after callback entry; only admission failures are counted here.
|
|
583
622
|
admission("failed");
|