# monSQLize v2.0.7 (unpublished archive)

> Prepared date: 2026-06-16
> Release status: Never published; superseded by v3.0.0
> Type: Withdrawn patch candidate
> Compatibility: Contains compatibility-impacting behavior changes; see below

This candidate must not be tagged or published. Its accumulated public additions and compatibility-impacting changes require a major release, so the canonical release inventory and upgrade guidance moved to [v3.0.0](./v3.0.0.md). The detail below is retained only as historical review evidence.

## Summary

The withdrawn v2.0.7 candidate collected release-readiness work after v2.0.6: model optimistic concurrency, transaction cache invalidation, Change Stream sync ordering, soft-delete read visibility, MongoDB driver option forwarding, batch-write retry behavior, distributed invalidation, and bounded production data tasks.

## Compatibility-impacting changes

- Versioned Model single-document writes now enforce true optimistic concurrency control: stale writes throw `WRITE_CONFLICT`, and writes without `expectedVersion`, `version`, or a direct `_id` automatic lookup path may throw `INVALID_ARGUMENT`.
- Versioned `updateMany()` defaults to `counter`, which increments version counters without optimistic locking. Use `versionMode: 'strict'` for per-document conditional updates or `versionMode: 'off'` for compatibility behavior.
- `find()` now defaults to `findLimit: 500`; explicit positive `limit` and `skip` values are bounded by `findMaxLimit` and `findMaxSkip`. `limit(0)` intentionally keeps MongoDB's unlimited cursor semantics.
- Change Stream resume token persistence is strict by default: token save/load failures stop synchronization unless `strictSave: false` / `strictLoad: false` is configured for legacy best-effort behavior.
- `updateBatch({ upsert: true })` is rejected because `updateBatch` walks existing matching `_id` values and cannot express MongoDB's single-document `updateMany(..., { upsert: true })` insert semantics. Use `upsertOne()` or native `updateMany(..., { upsert: true })` instead.
- `dropDatabase()` treats `NODE_ENV=production`, `prod`, and `live` as production-like environments that require `allowProduction: true`.
- Soft-delete filtering now covers the standard Model read surface including `findPage`, ID reads, `distinct`, `aggregate`, `stream`, and `explain`.
- Populate `skip` / `limit` for has-many relations is applied per parent document, and nested populate is capped by `maxDepth` (default `5`).
- `ConnectionPoolManager.addPool()` now applies the same strict pool config validation as the public validator before opening a client.
- Change Stream `collections: ['*']` now means all collections rather than a literal collection named `*`.

## Changed

- Package metadata now describes monSQLize as a database-native TypeScript data runtime and no longer promotes business locks or Saga orchestration as primary package capabilities.
- Business lock and Saga documentation remains available for existing callers, but hidden compatibility pages now state the current runtime boundaries and recommend application/framework-level orchestration for new payment/order flows.
- `npm run test:unit` now delegates to `test/run-tests.cjs unit`, matching the maintained unit suite instead of a stale hand-written file list.
- Validation ledgers now reflect the current 56 runnable TypeScript documentation examples.
- `initializeModelV1Methods()` now reports factory failures through the runtime logger when available instead of writing directly to `console.warn`.
- Versioned models now enforce true optimistic concurrency control for single-document writes: direct `_id` filters automatically read the current version, callers may override with `expectedVersion` / `version`, and stale writes throw `WRITE_CONFLICT`.
- Versioned `updateMany()` now supports explicit modes: `counter` for native batch version counters, `strict` for per-document conditional updates, and `off` for compatibility escape hatches.
- Transaction cache invalidations are recorded during the transaction and replayed only after a successful commit; commit retry now handles `UnknownTransactionCommitResult`.
- Change Stream sync events are processed serially so target writes and resume token persistence stay ordered; resume token files use atomic replacement, strict load validation, and backup files in file mode; unexpected stream close events now mark sync as stopped in stats.
- Soft-delete filters now cover the standard model read surface, including `findPage`, ID reads, `distinct`, `aggregate`, `stream`, and `explain`.
- MongoDB read paths now forward driver options such as `session`, `readConcern`, `readPreference`, `collation`, `hint`, `maxTimeMS`, and aggregation options instead of dropping them through a narrow whitelist.
- Query caches now avoid session-scoped reads and build stable cache keys only from result-shaping options.
- Distributed cache invalidation now uses separate Redis publish/subscribe connections when a Redis instance is provided and reports subscription failures.
- Batch insert retry now retries only the failed unordered subset after partial success instead of replaying the full chunk.
- `find()` now defaults to `findLimit: 500`, validates explicit `limit`/`skip` values against configurable `findMaxLimit` and `findMaxSkip` caps, and documents that `limit(0)` intentionally keeps MongoDB's unlimited semantics.
- `findPage().offsetJump.maxSkip` is now enforced against the runtime `findMaxSkip` cap before using skip-based page jumps.
- `dropDatabase()` now treats `NODE_ENV=production`, `prod`, and `live` as production-like environments that require `allowProduction: true`.
- Aggregate pipelines ending in `$out` or `$merge` now bypass aggregate result caching and invalidate the target collection's read caches after successful execution.
- Fire-and-forget distributed cache invalidation and transaction timeout abort paths now catch/log failures instead of leaving unhandled rejections.
- `findPage` cursor anchors now read nested dot-path sort fields correctly, query read helpers accept `project` as a projection alias, and documentation clarifies ObjectId `maxDepth` conversion limits plus process-level Model registration.
- `updateMany(..., { upsert: true })` documentation now states MongoDB's native no-match branch inserts only one derived document, so it is not a per-input bulk upsert replacement for `updateBatch`.
- Added `msq.dataTasks` for bounded production tasks: `plan`, `dryRun`, `run`, `verify`, plus helper methods for explicit index sync, filtered data sync, field transforms, affected-document snapshots, and verification.
- Added the `monsqlize data-task` CLI with `plan`, `dry-run`, `run`, and `verify` actions. Production writes require `--confirm-production`.
- Added data task docs, production rollout guidance, API index entries, and a runnable `examples/docs/data-tasks.ts` example.

## Verification

- `npm run lint`
- `npm run check:docs-examples`
- `npm run type-check`
- `npm run check:sizes:strict`
- `npm run test:unit`
- `npm test`
- `npm run test:audit`
- `npm pack --dry-run --json`
