Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/node-type-registry/src/blueprint-types.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1207,8 +1207,10 @@ export interface BlueprintBucketSeed {
/** CORS allowed origins for this bucket. */
allowed_origins?: string[];
}
/** Storage configuration for an entity type. Seeds initial buckets, overrides module-level settings (expiry times, file size limits, CORS), and provides per-table provisioning overrides via provisions. */
/** Storage configuration with optional scope. When used at the top level of a blueprint, the scope field controls whether storage is app-level ("app", default) or org-level ("org"). Seeds initial buckets, overrides module-level settings (expiry times, file size limits, CORS), and provides per-table provisioning overrides via provisions. */
export interface BlueprintStorageConfig {
/** Storage scope. "app" (default) creates app-level storage (no owner_id). "org" creates per-org/user storage (owner_id = org entity id, buckets seeded per-entity via AFTER INSERT trigger). Only "app" and "org" are allowed — child entity types get storage via entity_types[].storage. */
scope?: 'app' | 'org';
/** Discriminator for multi-module storage. Defaults to "default" (omitted from table names). Non-default keys appear as an infix: {prefix}_{storage_key}_buckets. Max 16 chars, lowercase snake_case. */
storage_key?: string;
/** Initial bucket seed entries. Each creates a row in {prefix}_buckets during provisioning. */
Expand Down Expand Up @@ -1595,7 +1597,7 @@ export interface BlueprintDefinition {
unique_constraints?: BlueprintUniqueConstraint[];
/** Entity types to provision in Phase 0 (before tables). Each entry creates an entity table with membership modules and security. */
entity_types?: BlueprintEntityType[];
/** App-level storage configuration (array-only). Creates storage_module(s) (membership_type = NULL), seeds initial buckets, and overrides module-level settings. Each entry creates a separate storage module. For entity-scoped storage, use entity_types[].storage instead. */
/** Top-level storage configuration array. Each entry has an optional scope ("app" or "org"). App-scoped (default) creates storage_module with membership_type = NULL. Org-scoped creates per-org/user storage with owner_id and AFTER INSERT bucket seeding. When infra is installed, a private "functions" bucket is auto-injected into org-scoped entries. For child entity type storage, use entity_types[].storage instead. */
storage?: BlueprintStorageConfig[];
/** Achievement definitions. Each entry creates a level with requirements and optional rewards in the events_module. Requires events_module to be provisioned (e.g., via entity_types[].has_levels = true or modules includes events_module). */
achievements?: BlueprintAchievement[];
Expand Down
14 changes: 12 additions & 2 deletions packages/node-type-registry/src/codegen/generate-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,16 @@ function buildBlueprintBucketSeed(): t.ExportNamedDeclaration {
function buildBlueprintStorageConfig(): t.ExportNamedDeclaration {
return addJSDoc(
exportInterface('BlueprintStorageConfig', [
addJSDoc(
optionalProp(
'scope',
t.tsUnionType([
t.tsLiteralType(t.stringLiteral('app')),
t.tsLiteralType(t.stringLiteral('org'))
])
),
'Storage scope. "app" (default) creates app-level storage (no owner_id). "org" creates per-org/user storage (owner_id = org entity id, buckets seeded per-entity via AFTER INSERT trigger). Only "app" and "org" are allowed — child entity types get storage via entity_types[].storage.'
),
addJSDoc(
optionalProp('storage_key', t.tsStringKeyword()),
'Discriminator for multi-module storage. Defaults to "default" (omitted from table names). Non-default keys appear as an infix: {prefix}_{storage_key}_buckets. Max 16 chars, lowercase snake_case.'
Expand Down Expand Up @@ -844,7 +854,7 @@ function buildBlueprintStorageConfig(): t.ExportNamedDeclaration {
'Per-table overrides for storage tables. Each key targets a specific storage table (files, buckets) and uses the same shape as table_provision: { nodes, fields, grants, use_rls, policies }. Fanned out to secure_table_provision targeting the corresponding table. When a key includes policies[], those REPLACE the default storage policies for that table; tables without a key still get defaults.'
)
]),
'Storage configuration for an entity type. Seeds initial buckets, overrides module-level settings (expiry times, file size limits, CORS), and provides per-table provisioning overrides via provisions.'
'Storage configuration with optional scope. When used at the top level of a blueprint, the scope field controls whether storage is app-level (\"app\", default) or org-level (\"org\"). Seeds initial buckets, overrides module-level settings (expiry times, file size limits, CORS), and provides per-table provisioning overrides via provisions.'
);
}

Expand Down Expand Up @@ -1194,7 +1204,7 @@ function buildBlueprintDefinition(): t.ExportNamedDeclaration {
t.tsTypeReference(t.identifier('BlueprintStorageConfig'))
)
),
'App-level storage configuration array. Each entry creates a storage_module (membership_type = NULL) with its own tables and settings. For entity-scoped storage, use entity_types[].storage instead.'
'Top-level storage configuration array. Each entry has an optional scope ("app" or "org"). App-scoped (default) creates storage_module with membership_type = NULL. Org-scoped creates per-org/user storage with owner_id and AFTER INSERT bucket seeding. When infra is installed, a private "functions" bucket is auto-injected into org-scoped entries. For child entity type storage, use entity_types[].storage instead.'
),
addJSDoc(
optionalProp(
Expand Down
Loading