From 38723c108bb1ca99bd9b6ad9e8d3e67f6a80cdaf Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 17 Jul 2026 18:01:11 +0300 Subject: [PATCH 1/3] feat(database): disable eager collection creation for all schemas --- .../src/adapters/mongoose-adapter/MongooseSchema.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/database/src/adapters/mongoose-adapter/MongooseSchema.ts b/modules/database/src/adapters/mongoose-adapter/MongooseSchema.ts index 70e20e0b5..c6a089cba 100644 --- a/modules/database/src/adapters/mongoose-adapter/MongooseSchema.ts +++ b/modules/database/src/adapters/mongoose-adapter/MongooseSchema.ts @@ -65,12 +65,8 @@ export class MongooseSchema extends SchemaAdapter> { this.schemaLevelReadPreference = schemaRp; const mongooseSchema = new Schema(cloneDeep(schema.fields as Indexable), { ...mo, - ...(isView - ? { - autoCreate: false, - autoIndex: false, - } - : {}), + autoCreate: false, + autoIndex: false, }); this.model = mongoose.model(cloneDeep(schema.name), mongooseSchema); } From 1c284aa5bab0437efb10caa8c420d6f6f05ebca6 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 23 Jul 2026 11:53:58 +0300 Subject: [PATCH 2/3] fix(database): explicitly create mongoose field indexes With autoIndex disabled, field-level unique/index definitions and single-field indexes moved onto fields by SchemaConverter were not being created on fresh databases. Create them explicitly from the compiled Mongoose schema while skipping the default _id index so schemas without other indexes remain lazy. Co-authored-by: Cursor --- .../src/adapters/mongoose-adapter/index.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/modules/database/src/adapters/mongoose-adapter/index.ts b/modules/database/src/adapters/mongoose-adapter/index.ts index ac5ee694d..a2ef4dd74 100644 --- a/modules/database/src/adapters/mongoose-adapter/index.ts +++ b/modules/database/src/adapters/mongoose-adapter/index.ts @@ -640,6 +640,39 @@ export class MongooseAdapter extends DatabaseAdapter { return 'Indexes created!'; } + private async createMongooseFieldIndexes(schemaName: string): Promise { + const model = this.models[schemaName]; + if (!model) throw new GrpcError(status.NOT_FOUND, 'Requested schema not found'); + if (model.isView) return; + + const declaredIndexes = model.model.schema.indexes(); + if (!declaredIndexes.length) return; + + const collection = this.mongoose.model(schemaName).collection; + for (const [keys, rawOptions] of declaredIndexes) { + if (this.isDefaultIdIndex(keys)) continue; + + const options = this.sanitizeMongooseIndexOptions(rawOptions); + await collection.createIndex(keys, options).catch((e: Error) => { + throw new GrpcError(status.INTERNAL, e.message); + }); + } + } + + private isDefaultIdIndex(keys: Record): boolean { + const entries = Object.entries(keys); + return entries.length === 1 && entries[0][0] === '_id' && entries[0][1] === 1; + } + + private sanitizeMongooseIndexOptions( + options?: Record, + ): Record | undefined { + if (!options) return undefined; + const sanitized = { ...options }; + delete sanitized._autoIndex; + return Object.keys(sanitized).length > 0 ? sanitized : undefined; + } + async getIndexes(schemaName: string): Promise { if (!this.models[schemaName]) throw new GrpcError(status.NOT_FOUND, 'Requested schema not found'); @@ -806,6 +839,9 @@ export class MongooseAdapter extends DatabaseAdapter { if (indexes && !isInstanceSync) { await this.createIndexes(schema.name, indexes, schema.ownerModule); } + if (!isInstanceSync) { + await this.createMongooseFieldIndexes(schema.name); + } return this.models[schema.name]; } From 8b6cbc9b6f8fb9343cb71b312e165529cf42a915 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 23 Jul 2026 12:08:26 +0300 Subject: [PATCH 3/3] fix(database): cast mongoose field index keys for createIndex Align explicit field-index creation with MongoDB IndexSpecification typing so the database module builds on v0.16.x. Co-authored-by: Cursor --- .../src/adapters/mongoose-adapter/index.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/database/src/adapters/mongoose-adapter/index.ts b/modules/database/src/adapters/mongoose-adapter/index.ts index a2ef4dd74..7d5362f57 100644 --- a/modules/database/src/adapters/mongoose-adapter/index.ts +++ b/modules/database/src/adapters/mongoose-adapter/index.ts @@ -1,4 +1,5 @@ import { ConnectOptions, Mongoose, Types } from 'mongoose'; +import type { IndexSpecification } from 'mongodb'; import { MongooseSchema } from './MongooseSchema.js'; import { schemaConverter } from './SchemaConverter.js'; import { @@ -650,17 +651,21 @@ export class MongooseAdapter extends DatabaseAdapter { const collection = this.mongoose.model(schemaName).collection; for (const [keys, rawOptions] of declaredIndexes) { - if (this.isDefaultIdIndex(keys)) continue; + const indexKeys = keys as IndexSpecification; + if (this.isDefaultIdIndex(indexKeys)) continue; - const options = this.sanitizeMongooseIndexOptions(rawOptions); - await collection.createIndex(keys, options).catch((e: Error) => { + const options = this.sanitizeMongooseIndexOptions( + rawOptions as Record, + ); + await collection.createIndex(indexKeys, options).catch((e: Error) => { throw new GrpcError(status.INTERNAL, e.message); }); } } - private isDefaultIdIndex(keys: Record): boolean { - const entries = Object.entries(keys); + private isDefaultIdIndex(keys: IndexSpecification): boolean { + if (!keys || typeof keys !== 'object' || Array.isArray(keys)) return false; + const entries = Object.entries(keys as Record); return entries.length === 1 && entries[0][0] === '_id' && entries[0][1] === 1; }