feat(standards): fix F11-F16 and rebuild bundle (43 components) + trial findings

- F11 PopulateRule field_name/collection_name corrections
- F12 service adaptor update handles PopulatingRepository
- F13 nested-references section; F14 authless /users/me guidance
- F15 template ruff-clean; F16 stop vendoring .ruff_cache, ship .gitignore
- document --template-style in build_recipe/spec_first_routing; refresh collected
  openapi-first + standards bundle (12 modules, 43 components)
- add trial.md and trial_findings.md (F1-F16, re-trial A/B evidence)
This commit is contained in:
2026-10-13 19:35:12 +05:30
parent fced40af59
commit 6c0d859a1e
56 changed files with 521 additions and 165 deletions

View File

@@ -772,6 +772,13 @@ can resolve <code>operationId</code> across the whole app:</p>
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2"></a> <span class="n">svc</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">app</span><span class="o">.</span><span class="n">state</span><span class="o">.</span><span class="n">db_resources</span><span class="p">[</span><span class="s2">&quot;item_svc&quot;</span><span class="p">]</span>
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3"></a> <span class="k">return</span> <span class="k">await</span> <span class="n">svc</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">Item</span><span class="o">.</span><span class="n">model_validate</span><span class="p">(</span><span class="n">body</span><span class="p">))</span>
</span></code></pre></div></td></tr></table></div>
<p><strong>Generated stubs.</strong> <code>openapi-first routes</code> emits this exact shape (<code>async def</code>
handlers taking <code>body</code>) when given <code>--template-style</code>; without that flag the
stub is <code>def create_item(payload: ItemInput)</code> — sync, with a <code>payload</code>
parameter. Both shapes bind identically: the router resolves handlers by
<code>operationId</code> and introspects the FastAPI signature, and it never inspects the
request body. Pass <code>--template-style</code> so the generated signatures match the
handlers you keep in <code>interfaces/</code>.</p>
<h2 id="conventions">Conventions</h2>
<ul>
<li><code>operationId</code> naming: <code>list_&lt;resource&gt;</code>, <code>create_&lt;resource&gt;</code>,
@@ -794,6 +801,10 @@ just omit the security keys:</p>
global <code>security</code> block exists. Leaving every operation without a <code>security</code>
key is the cleanest authless spec.</li>
</ul>
<p>Profile endpoints (<code>/users/me</code>) and profile headers (<code>x-profile</code>) still exist in
an authless app. Define a stand-in identity in the composition root — for
example <code>get_current_user</code> returns or lazily creates a fixed "Demo User" — so
handlers stay auth-agnostic and only the wiring changes when real auth arrives.</p>
<p>The handlers, services, and composition root are unchanged. When auth is needed
later, add the global <code>security</code> block and an introspecting dependency; only
handlers that must opt out get <code>security: []</code>.</p>
@@ -804,7 +815,7 @@ handlers that must opt out get <code>security: []</code>.</p>
<span class="normal"><a href="#__codelineno-4-2">2</a></span>
<span class="normal"><a href="#__codelineno-4-3">3</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1"></a>openapi-first<span class="w"> </span>models<span class="w"> </span>openapi.yaml<span class="w"> </span>-o<span class="w"> </span>_gen/models.py
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2"></a>openapi-first<span class="w"> </span>routes<span class="w"> </span>openapi.yaml<span class="w"> </span>-o<span class="w"> </span>_gen/routes<span class="w"> </span><span class="se">\</span>
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3"></a><span class="w"> </span>--use-models<span class="w"> </span>--models-module<span class="w"> </span>_gen.models<span class="w"> </span>--inject-request<span class="w"> </span>--package
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3"></a><span class="w"> </span>--use-models<span class="w"> </span>--models-module<span class="w"> </span>_gen.models<span class="w"> </span>--inject-request<span class="w"> </span>--package<span class="w"> </span>--template-style
</span></code></pre></div></td></tr></table></div>
<p>Prefer codegen over hand-writing boilerplate. The result is the wire contract
and a set of <code>operationId</code>-named signatures — not the canonical handlers.</p>