## ADDED Requirements ### Requirement: Layer 0 dep-graph isolation The `@suaveplan/testing-integration-mongodb` package's `dependencies` MUST be exactly `@suaveplan/testing-integration` (`workspace:^`) and `testcontainers` (`catalog:integration`). No other `@suaveplan/*` runtime dep is permitted. `devDependencies` MAY include `@suaveplan/testing` for the package's own tests. #### Scenario: Runtime closure clean - **WHEN** `bunx turbo ls --filter=@suaveplan/testing-integration-mongodb...` is run - **THEN** the only `@suaveplan/*` package in the runtime closure is `@suaveplan/testing-integration` ### Requirement: Image-pinning policy The default image MUST be `mongo:7.0`. The `constants/index.ts` file MUST carry a `# TODO: replace with sha256:` comment until the digest is recorded. #### Scenario: Pinned tag - **WHEN** the constants file is read - **THEN** the image string equals `mongo:7.0` AND a sha256 TODO line is present ### Requirement: Env-bridge passthrough The fixture MUST consult `MONGODB_URL` and `MONGODB_DATABASE`. When both are present and non-empty, `start()` MUST skip container creation and return a handle whose config points at the live MongoDB. #### Scenario: Live MongoDB present - **WHEN** both env vars are set - **THEN** `start()` returns without invoking `containerFactory` AND the returned config's `url` equals `MONGODB_URL` #### Scenario: Partial env triggers container - **WHEN** `MONGODB_URL` is set but `MONGODB_DATABASE` is empty - **THEN** `start()` falls back to container mode ### Requirement: Healthcheck The fixture MUST run `mongosh --eval "db.runCommand('ping')"` in-container via the injectable `execFn` and treat exit code `0` with stdout containing `ok` as ready. The default `healthTimeoutMs` MUST be `60000`. Callers MAY override. #### Scenario: Healthcheck succeeds - **WHEN** the in-container `mongosh` ping returns exit code 0 with `{ ok: 1 }` stdout - **THEN** `start()` resolves #### Scenario: Healthcheck times out - **WHEN** the ping never succeeds within `healthTimeoutMs` - **THEN** `start()` rejects with code `INTEGRATION.MONGODB.HEALTHCHECK_TIMEOUT` ### Requirement: Replica-set initialisation When `replicaSet: true` is supplied, the fixture MUST start `mongod` with `--replSet rs0` and run `rs.initiate()` via `execFn` after the ping healthcheck passes. The fixture MUST NOT resolve `start()` until `rs.status().ok === 1`. #### Scenario: Replica-set ready - **WHEN** `start({ database: 'app', replicaSet: true })` resolves - **THEN** a subsequent `rs.status()` call reports `ok: 1` AND a multi-document transaction succeeds against the returned `url` ### Requirement: Authentication mode When `authentication: { username, password }` is supplied, the fixture MUST start `mongod` with `--auth`, create the supplied user via `execFn` against the `admin` database, and embed the credentials in the returned `url` (`mongodb://user:pass@host:port/database`). #### Scenario: Auth rejects bad credentials - **WHEN** the fixture starts in auth mode and a client connects with an incorrect password - **THEN** the connection fails with a MongoDB authentication error ### Requirement: Config shape The exported `MongoDbConfig` interface MUST include `database`, optional `replicaSet?: boolean`, optional `authentication?: { username: string; password: string }`, and the resolved `url`. A sibling `mongodb-fixture.schemas.ts` MUST export a Zod `MongoDbConfigSchema` that validates the same shape. #### Scenario: Schema parity - **WHEN** `MongoDbConfigSchema.safeParse` is run against a `MongoDbConfig` value - **THEN** valid configs parse OK AND missing required fields fail with `ZodError` ### Requirement: Error-code prefix All errors thrown from the fixture MUST carry a `code` matching `^INTEGRATION\.MONGODB\.[A-Z_]+$`. #### Scenario: Coded error - **WHEN** any fixture method throws - **THEN** `code` starts with `INTEGRATION.MONGODB.` ### Requirement: Injectable fakes The fixture constructor MUST accept `containerFactory?: () => GenericContainer` and `execFn?: (cmd: string[]) => Promise<{ stdout: string; stderr: string; exitCode: number }>`. Unit tests MUST be able to drive 100% Istanbul branch coverage without Docker. #### Scenario: Fake injection - **WHEN** the fixture is constructed with both fakes - **THEN** real Docker is never invoked during the test ### Requirement: Plugin scenarios The fixture MUST support, end-to-end against a real container, the following flows in its smoke test: #### Scenario: Plain mode write/read round-trip - **WHEN** the fixture is started in plain mode and an `insertOne` followed by a `findOne` is performed - **THEN** the inserted document is read back unchanged #### Scenario: Replica-set transaction round-trip - **WHEN** the fixture is started with `replicaSet: true` and a multi-document transaction is committed - **THEN** all inserts are visible after `commitTransaction()` AND none are visible if `abortTransaction()` is called instead