docs: collect refreshed mongo-ops wiki site (API-correct overhaul, v0.1.5)

This commit is contained in:
2026-09-14 13:46:11 +05:30
parent bbd9863d23
commit f406aa2f21
24 changed files with 2880 additions and 1525 deletions

View File

@@ -454,7 +454,7 @@
<span class="md-ellipsis">
02 components
Core Components
</span>
@@ -860,6 +860,8 @@
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
@@ -892,6 +894,8 @@
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
@@ -900,9 +904,54 @@
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#best-practices" class="md-nav__link">
<a href="#layering" class="md-nav__link">
<span class="md-ellipsis">
Best Practices
🏗️ Layering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#lifecycle" class="md-nav__link">
<span class="md-ellipsis">
🔄 Lifecycle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#data-performance" class="md-nav__link">
<span class="md-ellipsis">
🗄️ Data &amp; Performance
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#transactions-errors" class="md-nav__link">
<span class="md-ellipsis">
🔁 Transactions &amp; Errors
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#testing" class="md-nav__link">
<span class="md-ellipsis">
🧪 Testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#related" class="md-nav__link">
<span class="md-ellipsis">
Related
</span>
</a>
@@ -998,20 +1047,46 @@
<h1>Best Practices</h1>
<h2 id="best-practices">Best Practices</h2>
<h1 id="best-practices">Best Practices</h1>
<p>Team-wide conventions for building fast, testable MongoDB services with <code>mongo-ops</code>.</p>
<hr />
<h2 id="layering">🏗️ Layering</h2>
<ol>
<li><strong>Always use ModelRegistry.register()</strong> before initializing the database connection</li>
<li><strong>Use lifespan context manager</strong> for proper connection lifecycle</li>
<li><strong>Inherit from BaseDocument</strong> for all models to get auto-timestamps</li>
<li><strong>Create custom repository classes</strong> for business logic instead of mixing it with models</li>
<li><strong>Use transactions</strong> for operations that modify multiple documents</li>
<li><strong>Add indexes</strong> during model registration for frequently queried fields</li>
<li><strong>Implement pagination</strong> for list endpoints to avoid performance issues</li>
<li><strong>Use type hints</strong> for better IDE support and type checking</li>
<li><strong>One repository per collection.</strong> Encapsulate every query the domain needs behind repository methods; keep Mongo details (<code>$regex</code>, <code>$inc</code>, projections) inside the repository.</li>
<li><strong>Keep models thin.</strong> <code>BaseDocument</code> for the shape; use Pydantic <code>Field</code> constraints for validation; never put business rules in the model.</li>
<li><strong>Use services for cross-repository logic.</strong> A <code>Service</code> composes multiple repositories (and <code>TransactionManager</code>) — routes stay thin.</li>
<li><strong>Expose <code>get_many(filter=..., skip=..., limit=..., sort=...)</code></strong> instead of raw <code>find</code> for list endpoints — you get controlled pagination for free.</li>
</ol>
<h2 id="lifecycle">🔄 Lifecycle</h2>
<ol>
<li><strong>Connect once, in the lifespan.</strong> <code>MongoConnectionManager.lifespan(...)</code> (or explicit <code>connect</code>/<code>disconnect</code>) — never lazily per request.</li>
<li><strong>Construct repositories after <code>connect()</code>.</strong> Module-level <code>Repo()</code> before connection raises <code>RuntimeError("Database not connected...")</code>. Use dependencies or construct inside the lifespan/request.</li>
<li><strong>Order the cache lifecycle strictly:</strong> <code>set_cache_backend(backend)</code><code>initialize_cache()</code> (after connect, before use) → <code>shutdown_cache()</code> on exit.</li>
<li><strong>Register all models up front</strong> via <code>ModelRegistry.register(...)</code> and let <code>initialize_all()</code> create indexes once at startup (idempotent).</li>
</ol>
<h2 id="data-performance">🗄️ Data &amp; Performance</h2>
<ol>
<li><strong>Declare indexes for every hot query.</strong> Single-field, composite, and optioned (unique/TTL) specs all work via <code>ModelRegistry.register</code> — see <a href="../03_use_cases/13_index_creation/">use case 13</a>.</li>
<li><strong>Cache only hot, low-write <code>_id</code> reads.</strong> Use <code>CachedBaseRepository</code> for lookups-by-id; invalidate (<code>update</code>/<code>delete</code> handle it) and pick a sensible <code>default_ttl</code>.</li>
<li><strong>Populate at the repository boundary.</strong> <code>PopulatingRepository</code> resolves refs on read and depopulates on write; do not hand-roll joins in endpoints.</li>
<li><strong>Respect the populate invariants:</strong> rules name the field that <em>holds</em> the reference and that <em>is replaced</em>; <code>patch()</code> cannot touch FK fields — use <code>update()</code>.</li>
</ol>
<h2 id="transactions-errors">🔁 Transactions &amp; Errors</h2>
<ol>
<li><strong>Use transactions for multi-document writes.</strong> <code>TransactionManager.start_session</code> (inline) or <code>execute_transaction</code> (list of ops) — and pass <code>session=</code> to <strong>every</strong> collection call inside.</li>
<li><strong>Handle the library's real exceptions</strong> at the edges: <code>DuplicateKeyError</code> → 409, <code>InvalidId</code> → 400, <code>CircularReferenceError</code> → 409, <code>ValueError</code> guides → 400/422 (see <a href="../06_error_handling/">Error Handling</a>).</li>
</ol>
<h2 id="testing">🧪 Testing</h2>
<ol>
<li><strong>Default to mock-based unit tests.</strong> Patch <code>MongoConnectionManager.get_database</code>, use <code>AsyncMock</code> collections and cursor chains — the whole suite runs without MongoDB (<a href="../03_use_cases/14_testing_guide/">use case 14</a>).</li>
<li><strong>Mirror the library tests.</strong> <code>tests/test_{repository,populating_repository,cache,registry,transactions}.py</code> are canonical examples of every pattern above.</li>
<li><strong>Use type hints end-to-end</strong> — mypy-gated CI (see pyproject) catches drift early.</li>
</ol>
<hr />
<h2 id="related">Related</h2>
<ul>
<li><a href="../01_overview/">Overview</a> · <a href="../02_components/">Core Components</a> · <a href="../#documentation-structure">Use Cases</a></li>
</ul>