borinquenkid commented on code in PR #16725:
URL: https://github.com/apache/grails-core/pull/16725#discussion_r4365055527


##########
.agents/skills/mongodb-developer/SKILL.md:
##########
@@ -0,0 +1,122 @@
+---
+name: mongodb-developer
+description: Guide for working in the grails-data-mongodb module (GORM for 
MongoDB) — codec-based document mapping, GeoJSON, embedded documents, TTL 
indexes, multi-tenancy, and Testcontainers-backed tests. Use this when changing 
code or tests under grails-data-mongodb.
+license: Apache-2.0
+---
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor 
license agreements; and to You under the Apache License, Version 2.0.
+-->
+
+## What I Do
+
+- Provide repository-specific guidance for the `grails-data-mongodb` project 
(GORM for MongoDB — a document-database GORM implementation, not a relational 
one; do not bring Hibernate/binder mental models here).
+- Guide changes around `MongoMappingContext`, 
`BsonPersistentEntityCodec`/`PersistentEntityCodec`, and the 
codec-registry-based encode/decode pipeline.
+- Keep changes aligned with the Testcontainers-backed testing pattern this 
module actually uses.
+
+## When to Use Me
+
+Activate this skill when working on the MongoDB module, especially for:
+
+- Changes under `grails-data-mongodb/**` (any of its 9 subprojects — see 
Module Structure).
+- Document/collection mapping, codec, or GeoJSON-type work.
+- Index (including TTL) creation/reconciliation logic.
+- Multi-tenancy or multi-connection MongoDB work.
+
+## Module Context
+
+`grails-data-mongodb` has no `settings.gradle` of its own — it's part of the 
root aggregate build, same as `grails-data-hibernate7`. All of root 
`AGENTS.md`'s rules (jakarta, `@GrailsCompileStatic`, 
CodeNarc/Checkstyle/PMD/SpotBugs, `dependencies.gradle`/BOM) apply here 
unmodified.
+
+Nine Gradle projects live under this directory, mapped to real Gradle project 
names (not always `grails-data-mongodb-<dirname>` — check before assuming):
+
+| Directory | Gradle project | Role |
+|---|---|---|
+| `core/` | `:grails-data-mongodb-core` | The actual GORM-for-MongoDB 
implementation: `MongoDatastore`, `MongoMappingContext`, `MongoQuery`, GeoJSON 
types |
+| `bson/` | `:grails-data-mongodb-bson` | Low-level, GORM-independent BSON 
codec machinery (`BsonPersistentEntityCodec`, per-type property codecs, 
hand-rolled JSON tokenizer) |
+| `ext/` | `:grails-data-mongodb-ext` | A single file, Groovy extension 
methods on the raw MongoDB driver (`distinct`, `watch`/change streams, 
`deleteMany`) |
+| `boot-plugin/` | `:grails-data-mongodb-spring-boot` | Spring Boot 
auto-configuration (`MongoDbGormAutoConfiguration`) |
+| `spring-data/` | `:grails-data-mongodb-spring-data` | Lets GORM-for-MongoDB 
and Spring Data MongoDB share a `MongoClient`/codecs/transaction |
+| `grails-plugin/` | `:grails-data-mongodb` (note: not `-grails-plugin` 
suffixed) | Classic Grails plugin descriptor (`MongodbGrailsPlugin`); also 
ships the app-facing `grails.test.mongodb.MongoSpec` test base via 
`testFixtures` |
+| `gson-templates/` | `:grails-data-mongodb-gson-templates` | JSON Views 
(`.gson`) for `ObjectId` and GeoJSON types |
+| `embedded/` | `:grails-data-mongodb-embedded` | Starts a real `mongod` 
(Flapdoodle, a `compileOnly` dependency the application adds itself) before the 
application context refreshes and publishes its URL into the configured 
properties; for applications, not for this module's own tests |

Review Comment:
   Fixed in e08436b6ad: the row names both backends (`InMemoryMongoBackend` 
over the `api` mongo-java-server, `FlapdoodleMongoBackend`, `compileOnly`), the 
default (Flapdoodle when it is on the classpath, otherwise in-memory) and 
`embedded.mongodb.backend`.



##########
.agents/skills/mongodb-developer/SKILL.md:
##########
@@ -0,0 +1,122 @@
+---
+name: mongodb-developer
+description: Guide for working in the grails-data-mongodb module (GORM for 
MongoDB) — codec-based document mapping, GeoJSON, embedded documents, TTL 
indexes, multi-tenancy, and Testcontainers-backed tests. Use this when changing 
code or tests under grails-data-mongodb.
+license: Apache-2.0
+---
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor 
license agreements; and to You under the Apache License, Version 2.0.
+-->
+
+## What I Do
+
+- Provide repository-specific guidance for the `grails-data-mongodb` project 
(GORM for MongoDB — a document-database GORM implementation, not a relational 
one; do not bring Hibernate/binder mental models here).
+- Guide changes around `MongoMappingContext`, 
`BsonPersistentEntityCodec`/`PersistentEntityCodec`, and the 
codec-registry-based encode/decode pipeline.
+- Keep changes aligned with the Testcontainers-backed testing pattern this 
module actually uses.
+
+## When to Use Me
+
+Activate this skill when working on the MongoDB module, especially for:
+
+- Changes under `grails-data-mongodb/**` (any of its 9 subprojects — see 
Module Structure).
+- Document/collection mapping, codec, or GeoJSON-type work.
+- Index (including TTL) creation/reconciliation logic.
+- Multi-tenancy or multi-connection MongoDB work.
+
+## Module Context
+
+`grails-data-mongodb` has no `settings.gradle` of its own — it's part of the 
root aggregate build, same as `grails-data-hibernate7`. All of root 
`AGENTS.md`'s rules (jakarta, `@GrailsCompileStatic`, 
CodeNarc/Checkstyle/PMD/SpotBugs, `dependencies.gradle`/BOM) apply here 
unmodified.
+
+Nine Gradle projects live under this directory, mapped to real Gradle project 
names (not always `grails-data-mongodb-<dirname>` — check before assuming):
+
+| Directory | Gradle project | Role |
+|---|---|---|
+| `core/` | `:grails-data-mongodb-core` | The actual GORM-for-MongoDB 
implementation: `MongoDatastore`, `MongoMappingContext`, `MongoQuery`, GeoJSON 
types |
+| `bson/` | `:grails-data-mongodb-bson` | Low-level, GORM-independent BSON 
codec machinery (`BsonPersistentEntityCodec`, per-type property codecs, 
hand-rolled JSON tokenizer) |
+| `ext/` | `:grails-data-mongodb-ext` | A single file, Groovy extension 
methods on the raw MongoDB driver (`distinct`, `watch`/change streams, 
`deleteMany`) |
+| `boot-plugin/` | `:grails-data-mongodb-spring-boot` | Spring Boot 
auto-configuration (`MongoDbGormAutoConfiguration`) |
+| `spring-data/` | `:grails-data-mongodb-spring-data` | Lets GORM-for-MongoDB 
and Spring Data MongoDB share a `MongoClient`/codecs/transaction |
+| `grails-plugin/` | `:grails-data-mongodb` (note: not `-grails-plugin` 
suffixed) | Classic Grails plugin descriptor (`MongodbGrailsPlugin`); also 
ships the app-facing `grails.test.mongodb.MongoSpec` test base via 
`testFixtures` |
+| `gson-templates/` | `:grails-data-mongodb-gson-templates` | JSON Views 
(`.gson`) for `ObjectId` and GeoJSON types |
+| `embedded/` | `:grails-data-mongodb-embedded` | Starts a real `mongod` 
(Flapdoodle, a `compileOnly` dependency the application adds itself) before the 
application context refreshes and publishes its URL into the configured 
properties; for applications, not for this module's own tests |
+| `docs/` | `:grails-data-mongodb-docs` | Asciidoc manual + groovydoc 
aggregation only, no source |
+
+## Key Classes and Responsibilities
+
+There is no single `GrailsDomainBinder`-equivalent class — the responsibility 
splits across three cooperating layers:
+
+### Mapping (the binder equivalent)
+
+- `MongoMappingContext` (`core/.../mongo/config/MongoMappingContext.java`) — 
owns the private inner `MongoDocumentMappingFactory extends 
AbstractGormMappingFactory<MongoCollection, MongoAttribute>`, which is the 
actual binder: forces the `_id` field name, applies the global 
`stringIdDefaultStoredAs` default, wires codec-registry-backed custom types, 
and registers all GeoJSON custom types.
+- `MongoCollection` (`core/.../config/MongoCollection.groovy`) — entity-level 
mapping (collection name, database, `writeConcern`, indices, sort).
+- `MongoAttribute` (`core/.../config/MongoAttribute.groovy`) — property-level 
mapping (`reference` for DBRef vs. plain identifier, `field`, `geoIndex`, 
`index`, `indexAttributes`).
+- `MappingBuilder.document { ... }` 
(`core/.../grails/mongodb/mapping/MappingBuilder.groovy`) — the programmatic 
DSL entry point.
+
+### Codec pipeline (the runtime read/write engine)
+
+- `BsonPersistentEntityCodec` (`bson/.../BsonPersistentEntityCodec.groovy`) 
and its Mongo subclass `PersistentEntityCodec` 
(`core/.../engine/codecs/PersistentEntityCodec.groovy`) — a static 
`ENCODERS`/`DECODERS` registry keyed by `PersistentProperty` subtype 
(`Identity`, `TenantId`, `Simple`, `Embedded`, `EmbeddedCollection`, `Custom`, 
`Basic`, plus Mongo-specific `OneToOne`/`ManyToOne`/`OneToMany`/`ManyToMany`). 
`encode`/`decode` walk `entity.persistentProperties` and dispatch per property 
kind. `PersistentEntityCodec` also implements MongoDB's partial-update path 
(`encodeUpdate`) via `DirtyCheckable`, producing `$set`/`$unset` documents 
directly rather than rewriting the whole document.
+
+### Datastore
+
+- `MongoDatastore` (`core/.../mongo/MongoDatastore.java`) — owns index 
creation/reconciliation against live MongoDB and transaction-capability 
detection based on cluster topology.
+
+## Confirmed MongoDB-Specific Concepts (implemented — don't assume beyond this 
list)
+
+- **Embedded documents & embedded collections** — 
`Embedded`/`EmbeddedCollection` property kinds, with dedicated in-place 
`$set`/`$unset` update logic distinct from top-level property updates.
+- **GeoJSON types** — 
`grails.mongodb.geo.{Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection,Box,Circle,Sphere,Shape}`,
 each with a custom-type marshaller. Query support: `near`, `nearSphere`, 
`withinCircle`, `withinBox`, `withinPolygon`, `geoWithin`, `geoIntersects`. 
Legacy `2d`/`2dsphere` indexes via `MongoAttribute.geoIndex(String)`.
+- **TTL indexes** — property-level `indexAttributes: [expireAfterSeconds: N]` 
materializes a MongoDB TTL index, reconciled in place via `collMod` rather than 
drop/rebuild (see Pitfalls).
+- **DBRef vs. plain identifier** — `MongoAttribute.reference` selects how a 
`ToOne`/`ToMany` association is stored: `true` writes a `com.mongodb.DBRef`, 
`false` (the default) writes the associated identifier. It does not embed; 
embedding is `static embedded = [...]`, a different property kind (see the 
first bullet). An agent that sets `reference: false` to embed a document will 
store an id instead.
+- **Schemaless/dynamic attributes** — `DynamicAttributes` trait support baked 
into `BsonPersistentEntityCodec` and `MongoEntity`.
+- **Change streams** — `MongoExtensions.watch(...)`, a thin Groovy-extension 
wrapper over the driver's native `watch()`, not a GORM-level abstraction.
+- **Multi-document transactions** — opt-in via `grails.mongodb.transactional`, 
gated on cluster topology (`REPLICA_SET`/`SHARDED`/`LOAD_BALANCED` supported; 
`STANDALONE` falls back with a one-time warning).
+- **Multi-tenancy / multiple named connections** — supported 
(discriminator-based multi-tenancy, `grails.mongodb.connections`).

Review Comment:
   Fixed in e08436b6ad: the three modes are listed with where `MongoDatastore` 
handles each, and the `DATABASE` example and `database-per-tenant` are named.



##########
.agents/skills/mongodb-developer/SKILL.md:
##########
@@ -0,0 +1,122 @@
+---
+name: mongodb-developer
+description: Guide for working in the grails-data-mongodb module (GORM for 
MongoDB) — codec-based document mapping, GeoJSON, embedded documents, TTL 
indexes, multi-tenancy, and Testcontainers-backed tests. Use this when changing 
code or tests under grails-data-mongodb.
+license: Apache-2.0
+---
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor 
license agreements; and to You under the Apache License, Version 2.0.
+-->
+
+## What I Do
+
+- Provide repository-specific guidance for the `grails-data-mongodb` project 
(GORM for MongoDB — a document-database GORM implementation, not a relational 
one; do not bring Hibernate/binder mental models here).
+- Guide changes around `MongoMappingContext`, 
`BsonPersistentEntityCodec`/`PersistentEntityCodec`, and the 
codec-registry-based encode/decode pipeline.
+- Keep changes aligned with the Testcontainers-backed testing pattern this 
module actually uses.
+
+## When to Use Me
+
+Activate this skill when working on the MongoDB module, especially for:
+
+- Changes under `grails-data-mongodb/**` (any of its 9 subprojects — see 
Module Structure).
+- Document/collection mapping, codec, or GeoJSON-type work.
+- Index (including TTL) creation/reconciliation logic.
+- Multi-tenancy or multi-connection MongoDB work.
+
+## Module Context
+
+`grails-data-mongodb` has no `settings.gradle` of its own — it's part of the 
root aggregate build, same as `grails-data-hibernate7`. All of root 
`AGENTS.md`'s rules (jakarta, `@GrailsCompileStatic`, 
CodeNarc/Checkstyle/PMD/SpotBugs, `dependencies.gradle`/BOM) apply here 
unmodified.
+
+Nine Gradle projects live under this directory, mapped to real Gradle project 
names (not always `grails-data-mongodb-<dirname>` — check before assuming):
+
+| Directory | Gradle project | Role |
+|---|---|---|
+| `core/` | `:grails-data-mongodb-core` | The actual GORM-for-MongoDB 
implementation: `MongoDatastore`, `MongoMappingContext`, `MongoQuery`, GeoJSON 
types |
+| `bson/` | `:grails-data-mongodb-bson` | Low-level, GORM-independent BSON 
codec machinery (`BsonPersistentEntityCodec`, per-type property codecs, 
hand-rolled JSON tokenizer) |
+| `ext/` | `:grails-data-mongodb-ext` | A single file, Groovy extension 
methods on the raw MongoDB driver (`distinct`, `watch`/change streams, 
`deleteMany`) |
+| `boot-plugin/` | `:grails-data-mongodb-spring-boot` | Spring Boot 
auto-configuration (`MongoDbGormAutoConfiguration`) |
+| `spring-data/` | `:grails-data-mongodb-spring-data` | Lets GORM-for-MongoDB 
and Spring Data MongoDB share a `MongoClient`/codecs/transaction |
+| `grails-plugin/` | `:grails-data-mongodb` (note: not `-grails-plugin` 
suffixed) | Classic Grails plugin descriptor (`MongodbGrailsPlugin`); also 
ships the app-facing `grails.test.mongodb.MongoSpec` test base via 
`testFixtures` |
+| `gson-templates/` | `:grails-data-mongodb-gson-templates` | JSON Views 
(`.gson`) for `ObjectId` and GeoJSON types |
+| `embedded/` | `:grails-data-mongodb-embedded` | Starts a real `mongod` 
(Flapdoodle, a `compileOnly` dependency the application adds itself) before the 
application context refreshes and publishes its URL into the configured 
properties; for applications, not for this module's own tests |
+| `docs/` | `:grails-data-mongodb-docs` | Asciidoc manual + groovydoc 
aggregation only, no source |
+
+## Key Classes and Responsibilities
+
+There is no single `GrailsDomainBinder`-equivalent class — the responsibility 
splits across three cooperating layers:
+
+### Mapping (the binder equivalent)
+
+- `MongoMappingContext` (`core/.../mongo/config/MongoMappingContext.java`) — 
owns the private inner `MongoDocumentMappingFactory extends 
AbstractGormMappingFactory<MongoCollection, MongoAttribute>`, which is the 
actual binder: forces the `_id` field name, applies the global 
`stringIdDefaultStoredAs` default, wires codec-registry-backed custom types, 
and registers all GeoJSON custom types.
+- `MongoCollection` (`core/.../config/MongoCollection.groovy`) — entity-level 
mapping (collection name, database, `writeConcern`, indices, sort).
+- `MongoAttribute` (`core/.../config/MongoAttribute.groovy`) — property-level 
mapping (`reference` for DBRef vs. plain identifier, `field`, `geoIndex`, 
`index`, `indexAttributes`).
+- `MappingBuilder.document { ... }` 
(`core/.../grails/mongodb/mapping/MappingBuilder.groovy`) — the programmatic 
DSL entry point.
+
+### Codec pipeline (the runtime read/write engine)
+
+- `BsonPersistentEntityCodec` (`bson/.../BsonPersistentEntityCodec.groovy`) 
and its Mongo subclass `PersistentEntityCodec` 
(`core/.../engine/codecs/PersistentEntityCodec.groovy`) — a static 
`ENCODERS`/`DECODERS` registry keyed by `PersistentProperty` subtype 
(`Identity`, `TenantId`, `Simple`, `Embedded`, `EmbeddedCollection`, `Custom`, 
`Basic`, plus Mongo-specific `OneToOne`/`ManyToOne`/`OneToMany`/`ManyToMany`). 
`encode`/`decode` walk `entity.persistentProperties` and dispatch per property 
kind. `PersistentEntityCodec` also implements MongoDB's partial-update path 
(`encodeUpdate`) via `DirtyCheckable`, producing `$set`/`$unset` documents 
directly rather than rewriting the whole document.
+
+### Datastore
+
+- `MongoDatastore` (`core/.../mongo/MongoDatastore.java`) — owns index 
creation/reconciliation against live MongoDB and transaction-capability 
detection based on cluster topology.
+
+## Confirmed MongoDB-Specific Concepts (implemented — don't assume beyond this 
list)
+
+- **Embedded documents & embedded collections** — 
`Embedded`/`EmbeddedCollection` property kinds, with dedicated in-place 
`$set`/`$unset` update logic distinct from top-level property updates.
+- **GeoJSON types** — 
`grails.mongodb.geo.{Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection,Box,Circle,Sphere,Shape}`,
 each with a custom-type marshaller. Query support: `near`, `nearSphere`, 
`withinCircle`, `withinBox`, `withinPolygon`, `geoWithin`, `geoIntersects`. 
Legacy `2d`/`2dsphere` indexes via `MongoAttribute.geoIndex(String)`.
+- **TTL indexes** — property-level `indexAttributes: [expireAfterSeconds: N]` 
materializes a MongoDB TTL index, reconciled in place via `collMod` rather than 
drop/rebuild (see Pitfalls).
+- **DBRef vs. plain identifier** — `MongoAttribute.reference` selects how a 
`ToOne`/`ToMany` association is stored: `true` writes a `com.mongodb.DBRef`, 
`false` (the default) writes the associated identifier. It does not embed; 
embedding is `static embedded = [...]`, a different property kind (see the 
first bullet). An agent that sets `reference: false` to embed a document will 
store an id instead.
+- **Schemaless/dynamic attributes** — `DynamicAttributes` trait support baked 
into `BsonPersistentEntityCodec` and `MongoEntity`.
+- **Change streams** — `MongoExtensions.watch(...)`, a thin Groovy-extension 
wrapper over the driver's native `watch()`, not a GORM-level abstraction.
+- **Multi-document transactions** — opt-in via `grails.mongodb.transactional`, 
gated on cluster topology (`REPLICA_SET`/`SHARDED`/`LOAD_BALANCED` supported; 
`STANDALONE` falls back with a one-time warning).
+- **Multi-tenancy / multiple named connections** — supported 
(discriminator-based multi-tenancy, `grails.mongodb.connections`).
+
+### Not implemented — do not document or rely on these
+
+- **`shard "name"` in the mapping DSL is a no-op.** There is no `shard` method 
on `Collection`/`MongoCollection`. The call silently falls through to the 
generic `Entity.methodMissing` catch-all, which just records it as an ad hoc 
property config — it never issues a MongoDB `shardCollection` command. 
Verified: zero `shardCollection` calls anywhere in `core/src/main`. If you see 
`shard "..."` in a mapping block, treat it as dead syntax, not a real feature.
+- **Capped collections** — not implemented anywhere in this module.

Review Comment:
   Fixed in e08436b6ad: narrowed to the mapping DSL, and the bullet says 
`createAndGetCollection` on the raw driver extension creates a capped 
collection (`MongoExtensionsSpec`). The `ext/` row mentions the method too.



##########
.agents/skills/mongodb-developer/SKILL.md:
##########
@@ -0,0 +1,122 @@
+---
+name: mongodb-developer
+description: Guide for working in the grails-data-mongodb module (GORM for 
MongoDB) — codec-based document mapping, GeoJSON, embedded documents, TTL 
indexes, multi-tenancy, and Testcontainers-backed tests. Use this when changing 
code or tests under grails-data-mongodb.
+license: Apache-2.0
+---
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor 
license agreements; and to You under the Apache License, Version 2.0.
+-->
+
+## What I Do
+
+- Provide repository-specific guidance for the `grails-data-mongodb` project 
(GORM for MongoDB — a document-database GORM implementation, not a relational 
one; do not bring Hibernate/binder mental models here).
+- Guide changes around `MongoMappingContext`, 
`BsonPersistentEntityCodec`/`PersistentEntityCodec`, and the 
codec-registry-based encode/decode pipeline.
+- Keep changes aligned with the Testcontainers-backed testing pattern this 
module actually uses.
+
+## When to Use Me
+
+Activate this skill when working on the MongoDB module, especially for:
+
+- Changes under `grails-data-mongodb/**` (any of its 9 subprojects — see 
Module Structure).
+- Document/collection mapping, codec, or GeoJSON-type work.
+- Index (including TTL) creation/reconciliation logic.
+- Multi-tenancy or multi-connection MongoDB work.
+
+## Module Context
+
+`grails-data-mongodb` has no `settings.gradle` of its own — it's part of the 
root aggregate build, same as `grails-data-hibernate7`. All of root 
`AGENTS.md`'s rules (jakarta, `@GrailsCompileStatic`, 
CodeNarc/Checkstyle/PMD/SpotBugs, `dependencies.gradle`/BOM) apply here 
unmodified.
+
+Nine Gradle projects live under this directory, mapped to real Gradle project 
names (not always `grails-data-mongodb-<dirname>` — check before assuming):
+
+| Directory | Gradle project | Role |
+|---|---|---|
+| `core/` | `:grails-data-mongodb-core` | The actual GORM-for-MongoDB 
implementation: `MongoDatastore`, `MongoMappingContext`, `MongoQuery`, GeoJSON 
types |
+| `bson/` | `:grails-data-mongodb-bson` | Low-level, GORM-independent BSON 
codec machinery (`BsonPersistentEntityCodec`, per-type property codecs, 
hand-rolled JSON tokenizer) |
+| `ext/` | `:grails-data-mongodb-ext` | A single file, Groovy extension 
methods on the raw MongoDB driver (`distinct`, `watch`/change streams, 
`deleteMany`) |
+| `boot-plugin/` | `:grails-data-mongodb-spring-boot` | Spring Boot 
auto-configuration (`MongoDbGormAutoConfiguration`) |
+| `spring-data/` | `:grails-data-mongodb-spring-data` | Lets GORM-for-MongoDB 
and Spring Data MongoDB share a `MongoClient`/codecs/transaction |
+| `grails-plugin/` | `:grails-data-mongodb` (note: not `-grails-plugin` 
suffixed) | Classic Grails plugin descriptor (`MongodbGrailsPlugin`); also 
ships the app-facing `grails.test.mongodb.MongoSpec` test base via 
`testFixtures` |
+| `gson-templates/` | `:grails-data-mongodb-gson-templates` | JSON Views 
(`.gson`) for `ObjectId` and GeoJSON types |
+| `embedded/` | `:grails-data-mongodb-embedded` | Starts a real `mongod` 
(Flapdoodle, a `compileOnly` dependency the application adds itself) before the 
application context refreshes and publishes its URL into the configured 
properties; for applications, not for this module's own tests |
+| `docs/` | `:grails-data-mongodb-docs` | Asciidoc manual + groovydoc 
aggregation only, no source |
+
+## Key Classes and Responsibilities
+
+There is no single `GrailsDomainBinder`-equivalent class — the responsibility 
splits across three cooperating layers:
+
+### Mapping (the binder equivalent)
+
+- `MongoMappingContext` (`core/.../mongo/config/MongoMappingContext.java`) — 
owns the private inner `MongoDocumentMappingFactory extends 
AbstractGormMappingFactory<MongoCollection, MongoAttribute>`, which is the 
actual binder: forces the `_id` field name, applies the global 
`stringIdDefaultStoredAs` default, wires codec-registry-backed custom types, 
and registers all GeoJSON custom types.
+- `MongoCollection` (`core/.../config/MongoCollection.groovy`) — entity-level 
mapping (collection name, database, `writeConcern`, indices, sort).
+- `MongoAttribute` (`core/.../config/MongoAttribute.groovy`) — property-level 
mapping (`reference` for DBRef vs. plain identifier, `field`, `geoIndex`, 
`index`, `indexAttributes`).
+- `MappingBuilder.document { ... }` 
(`core/.../grails/mongodb/mapping/MappingBuilder.groovy`) — the programmatic 
DSL entry point.
+
+### Codec pipeline (the runtime read/write engine)
+
+- `BsonPersistentEntityCodec` (`bson/.../BsonPersistentEntityCodec.groovy`) 
and its Mongo subclass `PersistentEntityCodec` 
(`core/.../engine/codecs/PersistentEntityCodec.groovy`) — a static 
`ENCODERS`/`DECODERS` registry keyed by `PersistentProperty` subtype 
(`Identity`, `TenantId`, `Simple`, `Embedded`, `EmbeddedCollection`, `Custom`, 
`Basic`, plus Mongo-specific `OneToOne`/`ManyToOne`/`OneToMany`/`ManyToMany`). 
`encode`/`decode` walk `entity.persistentProperties` and dispatch per property 
kind. `PersistentEntityCodec` also implements MongoDB's partial-update path 
(`encodeUpdate`) via `DirtyCheckable`, producing `$set`/`$unset` documents 
directly rather than rewriting the whole document.
+
+### Datastore
+
+- `MongoDatastore` (`core/.../mongo/MongoDatastore.java`) — owns index 
creation/reconciliation against live MongoDB and transaction-capability 
detection based on cluster topology.
+
+## Confirmed MongoDB-Specific Concepts (implemented — don't assume beyond this 
list)
+
+- **Embedded documents & embedded collections** — 
`Embedded`/`EmbeddedCollection` property kinds, with dedicated in-place 
`$set`/`$unset` update logic distinct from top-level property updates.
+- **GeoJSON types** — 
`grails.mongodb.geo.{Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection,Box,Circle,Sphere,Shape}`,
 each with a custom-type marshaller. Query support: `near`, `nearSphere`, 
`withinCircle`, `withinBox`, `withinPolygon`, `geoWithin`, `geoIntersects`. 
Legacy `2d`/`2dsphere` indexes via `MongoAttribute.geoIndex(String)`.
+- **TTL indexes** — property-level `indexAttributes: [expireAfterSeconds: N]` 
materializes a MongoDB TTL index, reconciled in place via `collMod` rather than 
drop/rebuild (see Pitfalls).
+- **DBRef vs. plain identifier** — `MongoAttribute.reference` selects how a 
`ToOne`/`ToMany` association is stored: `true` writes a `com.mongodb.DBRef`, 
`false` (the default) writes the associated identifier. It does not embed; 
embedding is `static embedded = [...]`, a different property kind (see the 
first bullet). An agent that sets `reference: false` to embed a document will 
store an id instead.
+- **Schemaless/dynamic attributes** — `DynamicAttributes` trait support baked 
into `BsonPersistentEntityCodec` and `MongoEntity`.
+- **Change streams** — `MongoExtensions.watch(...)`, a thin Groovy-extension 
wrapper over the driver's native `watch()`, not a GORM-level abstraction.
+- **Multi-document transactions** — opt-in via `grails.mongodb.transactional`, 
gated on cluster topology (`REPLICA_SET`/`SHARDED`/`LOAD_BALANCED` supported; 
`STANDALONE` falls back with a one-time warning).
+- **Multi-tenancy / multiple named connections** — supported 
(discriminator-based multi-tenancy, `grails.mongodb.connections`).
+
+### Not implemented — do not document or rely on these
+
+- **`shard "name"` in the mapping DSL is a no-op.** There is no `shard` method 
on `Collection`/`MongoCollection`. The call silently falls through to the 
generic `Entity.methodMissing` catch-all, which just records it as an ad hoc 
property config — it never issues a MongoDB `shardCollection` command. 
Verified: zero `shardCollection` calls anywhere in `core/src/main`. If you see 
`shard "..."` in a mapping block, treat it as dead syntax, not a real feature.
+- **Capped collections** — not implemented anywhere in this module.
+
+## Testing Rules
+
+The module's own tests use a real MongoDB via Testcontainers; the `embedded` 
subproject is a runtime feature for applications, not a test fallback. Docker 
or Podman must be running on the host.
+
+- **`GrailsDataTckSpec<GrailsDataMongoTckManager>`** is the dominant pattern 
(111+ specs) — the same shared TCK harness the Hibernate modules use 
(`grails-datamapping-tck`), parameterized with `GrailsDataMongoTckManager` 
(`core/src/test/groovy/.../GrailsDataMongoTckManager.groovy`), which starts a 
real `MongoDBContainer` in `setupSpec()`/stops it in `cleanupSpec()`. Its 
`destroy()` after each feature deletes the documents of every non-system 
database but keeps the collections and their indexes, so a later feature in the 
same fork can inherit an index an earlier one created; a spec that creates an 
index has to drop it itself.
+  ```groovy
+  class DocumentMappingSpec extends 
GrailsDataTckSpec<GrailsDataMongoTckManager> {
+      void setupSpec() {
+          manager.registerDomainClasses(CustomMapping)
+      }
+      void "test custom document mapping"() { ... }
+  }
+  ```
+  Domain classes are top-level classes in the same spec file, registered via 
`manager.registerDomainClasses(...)` in `setupSpec()` — same convention as 
`HibernateGormDatastoreSpec`.
+- **`AutoStartedMongoSpec`** (`grails-testing-support-mongodb`) — a 
lighter-weight base used by a handful of specs; a Spock global extension 
auto-injects `@Shared MongoDBContainer dbContainer` and auto-constructs a 
`@Shared MongoDatastore` field if present.

Review Comment:
   Fixed in e08436b6ad: 44 specs (41 in `core`, 3 in `boot-plugin`), roughly a 
quarter of core's 181.



##########
.agents/skills/mongodb-developer/SKILL.md:
##########
@@ -0,0 +1,122 @@
+---
+name: mongodb-developer
+description: Guide for working in the grails-data-mongodb module (GORM for 
MongoDB) — codec-based document mapping, GeoJSON, embedded documents, TTL 
indexes, multi-tenancy, and Testcontainers-backed tests. Use this when changing 
code or tests under grails-data-mongodb.
+license: Apache-2.0
+---
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor 
license agreements; and to You under the Apache License, Version 2.0.
+-->
+
+## What I Do
+
+- Provide repository-specific guidance for the `grails-data-mongodb` project 
(GORM for MongoDB — a document-database GORM implementation, not a relational 
one; do not bring Hibernate/binder mental models here).
+- Guide changes around `MongoMappingContext`, 
`BsonPersistentEntityCodec`/`PersistentEntityCodec`, and the 
codec-registry-based encode/decode pipeline.
+- Keep changes aligned with the Testcontainers-backed testing pattern this 
module actually uses.
+
+## When to Use Me
+
+Activate this skill when working on the MongoDB module, especially for:
+
+- Changes under `grails-data-mongodb/**` (any of its 9 subprojects — see 
Module Structure).
+- Document/collection mapping, codec, or GeoJSON-type work.
+- Index (including TTL) creation/reconciliation logic.
+- Multi-tenancy or multi-connection MongoDB work.
+
+## Module Context
+
+`grails-data-mongodb` has no `settings.gradle` of its own — it's part of the 
root aggregate build, same as `grails-data-hibernate7`. All of root 
`AGENTS.md`'s rules (jakarta, `@GrailsCompileStatic`, 
CodeNarc/Checkstyle/PMD/SpotBugs, `dependencies.gradle`/BOM) apply here 
unmodified.
+
+Nine Gradle projects live under this directory, mapped to real Gradle project 
names (not always `grails-data-mongodb-<dirname>` — check before assuming):
+
+| Directory | Gradle project | Role |
+|---|---|---|
+| `core/` | `:grails-data-mongodb-core` | The actual GORM-for-MongoDB 
implementation: `MongoDatastore`, `MongoMappingContext`, `MongoQuery`, GeoJSON 
types |
+| `bson/` | `:grails-data-mongodb-bson` | Low-level, GORM-independent BSON 
codec machinery (`BsonPersistentEntityCodec`, per-type property codecs, 
hand-rolled JSON tokenizer) |
+| `ext/` | `:grails-data-mongodb-ext` | A single file, Groovy extension 
methods on the raw MongoDB driver (`distinct`, `watch`/change streams, 
`deleteMany`) |
+| `boot-plugin/` | `:grails-data-mongodb-spring-boot` | Spring Boot 
auto-configuration (`MongoDbGormAutoConfiguration`) |
+| `spring-data/` | `:grails-data-mongodb-spring-data` | Lets GORM-for-MongoDB 
and Spring Data MongoDB share a `MongoClient`/codecs/transaction |
+| `grails-plugin/` | `:grails-data-mongodb` (note: not `-grails-plugin` 
suffixed) | Classic Grails plugin descriptor (`MongodbGrailsPlugin`); also 
ships the app-facing `grails.test.mongodb.MongoSpec` test base via 
`testFixtures` |
+| `gson-templates/` | `:grails-data-mongodb-gson-templates` | JSON Views 
(`.gson`) for `ObjectId` and GeoJSON types |
+| `embedded/` | `:grails-data-mongodb-embedded` | Starts a real `mongod` 
(Flapdoodle, a `compileOnly` dependency the application adds itself) before the 
application context refreshes and publishes its URL into the configured 
properties; for applications, not for this module's own tests |
+| `docs/` | `:grails-data-mongodb-docs` | Asciidoc manual + groovydoc 
aggregation only, no source |
+
+## Key Classes and Responsibilities
+
+There is no single `GrailsDomainBinder`-equivalent class — the responsibility 
splits across three cooperating layers:
+
+### Mapping (the binder equivalent)
+
+- `MongoMappingContext` (`core/.../mongo/config/MongoMappingContext.java`) — 
owns the private inner `MongoDocumentMappingFactory extends 
AbstractGormMappingFactory<MongoCollection, MongoAttribute>`, which is the 
actual binder: forces the `_id` field name, applies the global 
`stringIdDefaultStoredAs` default, wires codec-registry-backed custom types, 
and registers all GeoJSON custom types.
+- `MongoCollection` (`core/.../config/MongoCollection.groovy`) — entity-level 
mapping (collection name, database, `writeConcern`, indices, sort).
+- `MongoAttribute` (`core/.../config/MongoAttribute.groovy`) — property-level 
mapping (`reference` for DBRef vs. plain identifier, `field`, `geoIndex`, 
`index`, `indexAttributes`).
+- `MappingBuilder.document { ... }` 
(`core/.../grails/mongodb/mapping/MappingBuilder.groovy`) — the programmatic 
DSL entry point.
+
+### Codec pipeline (the runtime read/write engine)
+
+- `BsonPersistentEntityCodec` (`bson/.../BsonPersistentEntityCodec.groovy`) 
and its Mongo subclass `PersistentEntityCodec` 
(`core/.../engine/codecs/PersistentEntityCodec.groovy`) — a static 
`ENCODERS`/`DECODERS` registry keyed by `PersistentProperty` subtype 
(`Identity`, `TenantId`, `Simple`, `Embedded`, `EmbeddedCollection`, `Custom`, 
`Basic`, plus Mongo-specific `OneToOne`/`ManyToOne`/`OneToMany`/`ManyToMany`). 
`encode`/`decode` walk `entity.persistentProperties` and dispatch per property 
kind. `PersistentEntityCodec` also implements MongoDB's partial-update path 
(`encodeUpdate`) via `DirtyCheckable`, producing `$set`/`$unset` documents 
directly rather than rewriting the whole document.
+
+### Datastore
+
+- `MongoDatastore` (`core/.../mongo/MongoDatastore.java`) — owns index 
creation/reconciliation against live MongoDB and transaction-capability 
detection based on cluster topology.
+
+## Confirmed MongoDB-Specific Concepts (implemented — don't assume beyond this 
list)
+
+- **Embedded documents & embedded collections** — 
`Embedded`/`EmbeddedCollection` property kinds, with dedicated in-place 
`$set`/`$unset` update logic distinct from top-level property updates.
+- **GeoJSON types** — 
`grails.mongodb.geo.{Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection,Box,Circle,Sphere,Shape}`,
 each with a custom-type marshaller. Query support: `near`, `nearSphere`, 
`withinCircle`, `withinBox`, `withinPolygon`, `geoWithin`, `geoIntersects`. 
Legacy `2d`/`2dsphere` indexes via `MongoAttribute.geoIndex(String)`.
+- **TTL indexes** — property-level `indexAttributes: [expireAfterSeconds: N]` 
materializes a MongoDB TTL index, reconciled in place via `collMod` rather than 
drop/rebuild (see Pitfalls).
+- **DBRef vs. plain identifier** — `MongoAttribute.reference` selects how a 
`ToOne`/`ToMany` association is stored: `true` writes a `com.mongodb.DBRef`, 
`false` (the default) writes the associated identifier. It does not embed; 
embedding is `static embedded = [...]`, a different property kind (see the 
first bullet). An agent that sets `reference: false` to embed a document will 
store an id instead.
+- **Schemaless/dynamic attributes** — `DynamicAttributes` trait support baked 
into `BsonPersistentEntityCodec` and `MongoEntity`.
+- **Change streams** — `MongoExtensions.watch(...)`, a thin Groovy-extension 
wrapper over the driver's native `watch()`, not a GORM-level abstraction.
+- **Multi-document transactions** — opt-in via `grails.mongodb.transactional`, 
gated on cluster topology (`REPLICA_SET`/`SHARDED`/`LOAD_BALANCED` supported; 
`STANDALONE` falls back with a one-time warning).
+- **Multi-tenancy / multiple named connections** — supported 
(discriminator-based multi-tenancy, `grails.mongodb.connections`).
+
+### Not implemented — do not document or rely on these
+
+- **`shard "name"` in the mapping DSL is a no-op.** There is no `shard` method 
on `Collection`/`MongoCollection`. The call silently falls through to the 
generic `Entity.methodMissing` catch-all, which just records it as an ad hoc 
property config — it never issues a MongoDB `shardCollection` command. 
Verified: zero `shardCollection` calls anywhere in `core/src/main`. If you see 
`shard "..."` in a mapping block, treat it as dead syntax, not a real feature.
+- **Capped collections** — not implemented anywhere in this module.
+
+## Testing Rules
+
+The module's own tests use a real MongoDB via Testcontainers; the `embedded` 
subproject is a runtime feature for applications, not a test fallback. Docker 
or Podman must be running on the host.
+
+- **`GrailsDataTckSpec<GrailsDataMongoTckManager>`** is the dominant pattern 
(111+ specs) — the same shared TCK harness the Hibernate modules use 
(`grails-datamapping-tck`), parameterized with `GrailsDataMongoTckManager` 
(`core/src/test/groovy/.../GrailsDataMongoTckManager.groovy`), which starts a 
real `MongoDBContainer` in `setupSpec()`/stops it in `cleanupSpec()`. Its 
`destroy()` after each feature deletes the documents of every non-system 
database but keeps the collections and their indexes, so a later feature in the 
same fork can inherit an index an earlier one created; a spec that creates an 
index has to drop it itself.
+  ```groovy
+  class DocumentMappingSpec extends 
GrailsDataTckSpec<GrailsDataMongoTckManager> {
+      void setupSpec() {
+          manager.registerDomainClasses(CustomMapping)
+      }
+      void "test custom document mapping"() { ... }
+  }
+  ```
+  Domain classes are top-level classes in the same spec file, registered via 
`manager.registerDomainClasses(...)` in `setupSpec()` — same convention as 
`HibernateGormDatastoreSpec`.
+- **`AutoStartedMongoSpec`** (`grails-testing-support-mongodb`) — a 
lighter-weight base used by a handful of specs; a Spock global extension 
auto-injects `@Shared MongoDBContainer dbContainer` and auto-constructs a 
`@Shared MongoDatastore` field if present.
+- **`grails.test.mongodb.MongoSpec`** — a separate, *app-facing* base class 
shipped via `testFixtures` in `grails-plugin/`, for Grails-application-level 
Mongo integration tests. Don't confuse it with the two internal patterns above 
— a spec being both a `MongoSpec` and an `AutoStartedMongoSpec` is explicitly 
forbidden.
+- The MongoDB image version comes from `-PmongodbContainerVersion`, which CI 
always passes; see `gradle/mongodb-forked-test-config.gradle`.
+- `core` applies `gradle/mongodb-forked-test-config.gradle` (`maxParallelForks 
= rootProject.ext.configuredTestParallel`, the forked, parallel layout); every 
other subproject (`bson`, `ext`, `embedded`, `spring-data`, `boot-plugin`, 
`grails-plugin`, `gson-templates`) applies `gradle/mongodb-test-config.gradle`, 
which runs serially (`maxParallelForks = 1`). Check which file a subproject 
applies before changing its parallelism.
+- `-PskipMongodbTests` / `-PonlyMongodbTests` gate these tests at the root, 
matching the `Container missing` row in root `AGENTS.md`'s Common Issues table 
— use `-PskipMongodbTests` when Docker isn't available.

Review Comment:
   Fixed in e08436b6ad: it now says root `AGENTS.md` names `-PskipTests` and 
that `-PskipMongodbTests` is the narrower switch.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to