Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add tarlepp/symfony-flex-backend --skill add-doctrine-querygit clone --depth 1 https://github.com/tarlepp/symfony-flex-backendWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/tarlepp/symfony-flex-backend/add-doctrine-query)<a href="https://agentmods.dev/skills/tarlepp/symfony-flex-backend/add-doctrine-query"><img src="https://agentmods.dev/badge/skills/tarlepp/symfony-flex-backend/add-doctrine-query/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/tarlepp/symfony-flex-backend/add-doctrine-query"><img src="https://agentmods.dev/badge/skills/tarlepp/symfony-flex-backend/add-doctrine-query.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00031 | $0.01637 |
| Opus 5.5 | $0.00012 | $0.00655 |
| Sonnet 5.5 | $0.00006 | $0.00327 |
| Haiku 4.5 | $0.00003 | $0.00164 |
Grade A, and why
add-doctrine-query scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 136 lines — stays where its author put it; the contents beside it link to each section on GitHub.
What is this?
Use this skill when adding or changing repository queries, query criteria,
searchable fields, joins, sorting, pagination, counts, or ID lookups. For entity
mapping or index changes, also follow
.github/skills/add-doctrine-entity/SKILL.md. For a full endpoint change, also
follow .github/skills/add-rest-resource/SKILL.md.
Follow the shared skill guidance, including
.github/copilot-instructions.md and doc/AI_RULES.md.
Table of Contents ᐞ
Workflow ᐞ
- Read
composer.jsonfor supported PHP, Doctrine ORM, and DBAL versions,symfony.lockfor recipes, andconfig/packages/doctrine.yamlfor mappings and database types. Inspect the target entity, repository, resource, callers, and nearby tests. Trace request criteria throughRequestHandler, controller processing, and resource normalization when API query parameters are affected. Do not assume that raw HTTP input and repository arguments have the same shape. - Establish the expected result type, matching rules, relationship semantics,
ordering, pagination, and missing-result behavior. Distinguish no filter
from an empty list,
null, zero, or an empty string. Ask when these choices change an unspecified API contract or access boundary. Preserve existing authorization and data-visibility restrictions; user-provided criteria must not replace mandatory restrictions. - Keep data access in repositories under
src/Repository/, followingBaseRepository<TEntity>,$entityName, and local dependency-injection conventions. Keep business orchestration in resources or services. First checkRepositoryMethodsTrait,RepositoryWrappersTrait,RepositoryHelper, andSearchTermfor reusable behavior rather than duplicating a generic query or introducing a parallel repository pattern. - Choose the narrowest existing method that meets the need. Standard
findBy()andfindOneBy()delegate to Doctrine's entity repository; advanced methods use this project's criteria/search helpers and queued query customizations. These paths are not interchangeable. For a custom query, use the existingcreateQueryBuilder()wrapper, whose default alias isentity, and declare entity, scalar, list, or array-shape return types accurately. Preserve single-result cardinality errors instead of masking them with an arbitrary first row or an empty result. - Bind untrusted values with query parameters and the appropriate DBAL type.
Parameters do not protect field names, aliases, operators, or sort
directions: resolve dynamic identifiers through validated, intended choices
rather than interpolating arbitrary request strings into DQL or SQL.
Preserve the existing criteria grammar and error handling. Reuse
UuidHelperand nearby UUID-binding patterns for binary UUID fields, and check configured enum and date/time types. For lists, verify the installed DBAL's supported array binding and UUID conversion rather than assuming a scalar type converts every element. - Keep filtering and search consistent with
RepositoryHelperand the repository's$searchColumns. Verify AND/OR grouping, null comparisons, empty-list behavior, and relationship aliases. Preserve existing search tokenization, LIKE wildcard behavior, and database collation semantics unless the requested contract changes them. Do not silently ignore an invalid new filter, widen the matching set, or catch query failures and return success-shaped empty results. - Choose joins deliberately: an inner join excludes roots without a match;
a left join may preserve them until a WHERE predicate excludes them.
Select joined associations only when fetching them is needed. Check for
duplicate root rows, lazy-loading/N+1 queries, and changed result shapes.
When using
addLeftJoin(),addInnerJoin(), oraddCallback(), inspectBaseRepository::processQueryBuilder(): queued customizations are consumed during processing, not automatically applied by every repository method. Ensure required restrictions reach each related list, count, and ID query; do not assume one queued callback persists across those calls. - Preserve sorting and pagination contracts.
RepositoryHelper::processOrderBy()handles string directions andSortDirection; resource normalization may affect what reaches it.findByAdvanced()currently returns an empty array for a non-positive limit, uses no paginator when the limit is absent, and usesOffsetPaginatorwith aWindowwhen a limit is supplied. Do not replace this with row-level limits on collection fetch joins, which can truncate pages or associations. Use deterministic ordering for new paged queries, with a stable tie-breaker where needed, without changing existing ordering implicitly. - Keep count and ID results aligned with the matching root entities.
countAdvanced()counts distinct root IDs andfindIds()selects distinct IDs; joins must not inflate totals. For custom aggregates or grouped queries, verify the intended count explicitly instead of copying the list query blindly. Review generated SQL and query plans when a performance claim matters. Add an index only when justified, through entity mapping and a reviewed migration using the entity skill; never change a live schema with ad hoc SQL ordoctrine:schema:update. - Follow
.github/skills/write-tests/SKILL.md. Use real-database Functional tests such astests/Functional/Repository/UserRepositoryTest.phpto prove query results; mock QueryBuilder expectations alone cannot verify SQL semantics. Inspect existing repository test helpers before adding setup. Cover matching and excluded entities, no matches, relevant null/empty inputs, relation duplicates or missing relations, search combinations, ordering ties, and pagination boundaries. Assert exact IDs and order, not only row counts, and verify count/ID consistency where affected. For shared helper changes, extendtests/Integration/Rest/RepositoryHelperTest.phportests/Unit/Rest/SearchTermTest.phpas appropriate. For API query changes, also exercise the real HTTP boundary and its authorization, validation, response shape, and paging behavior. - Update existing query-parameter documentation or API metadata when accepted filters, search, ordering, pagination, or results change. A query-only change does not require a migration unless persisted mapping changes.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- yesterday First seen · 136 lines · 31 tokens per session scan A d672246574bf
add-doctrine-query is a skill published in the GitHub repository tarlepp/symfony-flex-backend (288 stars, last pushed today), licensed MIT. It adds 31 tokens to every session and 1,637 once invoked, about $0.0001 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-10-21.
Other skills, from other repositories
horse-database-pooling
Guide for setting up thread-safe database connection pooling (FireDAC / UniDAC) in multithreaded Horse applications.
api-platform-performance
Tune API Platform 4.3 + Doctrine + Symfony performance — recognize the 4.x default trap eagerloading.forceeager: true (often counter-productive, switch to false + targeted join fetches), use EXTRALAZY for large collections, project DTOs in DQL (NEW App\\Dto\\PostListItem(...)) to avoid hydrating full entities for list…
doctrine-batch-processing
Process large-volume Doctrine datasets (million-row imports, mass updates, ETL) without memory blowup. Use toIterable() + EntityManager::clear() per batch, partial hydration with DQL projection (NEW App\Dto\X(...)), HINTREADONLY when entities aren't mutated, MEMORYPEAKUSAGE tracking. Trigger on "iterate over all…
doctrine-fetch-modes
Tune Doctrine fetch modes to eliminate N+1 and over-hydration — LAZY (default), EXTRALAZY for huge collections (count(), contains() without load), EAGER per-property only with justification, partial hydration with addSelect(), IndexBy for O(1) lookups, HINTREADONLY. Covers the API Platform 4.x eagerloading.forceeager…
doctrine-transactions
Handle Doctrine transactions correctly — EntityManager::wrapInTransaction() for atomic multi-entity writes, doctrinetransaction Messenger middleware for command-bus atomicity, Doctrine\ORM\OptimisticLockException handling with #[Version] column, isolation levels, flush strategies (per-request vs explicit). Trigger…
api-integration-architect
Design, implement, debug, and optimize API integrations with expert-level patterns for REST, GraphQL, webhooks, and authentication flows.