SaferSkills independently audited easy-query-orm (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Write compilable easy-query code from verified patterns.
Use this file only as the router. Open one primary reference first. Add at most one secondary reference when a boundary rule below says it is needed.
EasyEntityQuery and proxy DSL unless the project clearly usesweak-typed EasyQueryClient.
eq in user requests, docs, or code comments as a common shorthandfor easy-query unless surrounding project context clearly proves otherwise.
*Proxy usually means setup or compile-chain trouble first. Javauses APT via the sql-processor annotation processor artifact; Kotlin uses KSP via the sql-ksp-processor artifact, not KAPT. When annotationProcessorPaths is already configured, the corresponding processor artifact must appear there explicitly. Having the easy-query dependency on the compile classpath alone is not enough for the processor to fire.
@EntityProxy is the generation trigger. ProxyEntityAvailable helps withtyped proxy usage but is not the switch that makes APT/KSP generate the class.
processor wiring, generated output path, then the first real compile error. Do not stop at package xxx.proxy does not exist.
references/api-map.md orscripts/search_references.py first.
imports, resolve the package from references/symbol-imports.md first. Do not guess the package from memory. 7a. When multiple candidate files are given, grep for key question terms across the candidate set first to identify the relevant file and line range, then read only the targeted span around the match rather than loading entire documents. 7b. For identifier-only questions, answer with only the direct invocation identifier or exact call shape. Prefer the callable method or exact builder-chain call the user should invoke, not the backing class, interface, or generator name.
ranks, and union branches in SQL DSL. Prefer explicit groupBy / having first; switch to subQueryToGroupJoin when repeated to-many relation metrics would otherwise emit many correlated subqueries.
derived from an existing relation path, prefer the relation-driven form first: implicit navigation, flatElement, relation aggregate/predicate. For tree answers, express the real root rule first, then apply recursive filtering or ancestor backfill only where needed. Fall back to explicit join, junction-table query, or post-query assembly only when the needed @Navigate path is missing or clearly insufficient.
whereObject(...) only forsearch-form DTOs.
orderBy(...) and a tie-breaker.0 as meaningful.SQL-derived computed properties; do not collapse them into one pattern.
reuse, and complexity of the equivalent query shape guide the choice between entity-side computed-property modeling and query-time projection.
boundary honest: typed-sql-expressions.md is the typed SQL expression layer, still SQL-side and still subject to dialect/version support; native-sql.md is the handwritten SQL escape hatch for fragments, wrappers, and fallback entrypoints when the typed surface is insufficient. When the needed string/date/math/JSON capability already exists in the typed surface, explicitly say to stay in references/typed-sql-expressions.md. The answer should say: do not recommend raw SQL first.
project and say which API or behavior may have moved.
relation/implicit, write/cross-cutting, AP/reporting, troubleshooting, or review.
Routing Table.Pair with ... clause applies.references/symbol-imports.md first when the missing piece is thepackage/import/FQCN for a type name.
references/api-map.md when the exact symbol exists but the rightsemantic reference or verified API surface is still unclear.
references/troubleshooting.md only after a primary feature referenceis already known, or when code compiles but behaves differently from the expected feature semantics.
setup-spring-boot.md is dependency/basic wiring; spring-boot-starter.md is starter internals, collected beans, and StarterConfigurer; configuration-starter.md is property semantics; advanced.md is DDL/sharding/runtime scope.
entity-mapping.md is basic entity/proxy mapping; entity-modeling-advanced.md is advanced table/column flags; primary-key-generation.md is key strategy and timing; relation-query.md is entity relation shape; entity-modeling-navigate.md is advanced/DTO-side navigation metadata; include-structured-loading.md is entity include loading; select-auto-include.md is DTO graph return.
query.md is ordinary root DSL; query-composition.md is explicit joins/projection/proxy VO .set(...); subquery-explicit.md is explicit subquery/derived table/CTE promotion; implicit-query.md and implicit-controls.md are relation-driven SQL; typed-sql-expressions.md is typed SQL expressions and typed database functions; native-sql.md is raw SQL fragments, raw SQL entrypoints, and fallback database-function writing.
search-form-page.md is endpoint workflow; dto-object-query.md is whereObject/orderByObject/@EasyWhereCondition; easy-search.md is only for sql-search.
write*.md is ordinary row mutation; primary-key-generation.md is key strategy rather than generic insert syntax; savable-aggregate.md is only for aggregate diff save.
*Proxy, package ...proxy does not exist, APT/KSP not firing,generated-sources visibility, annotationProcessorPaths, javacTree, Lombok/JDK processor crashes: references/proxy-generation-troubleshooting.md. Pair with references/setup-java.md, references/setup-kotlin.md, or references/setup-spring-boot.md.
references/setup-java.md.
references/setup-kotlin.md.
references/setup-spring-boot.md. Pair with references/spring-boot-starter.md only for starter internals.
EasyQueryInitializeOption,StarterConfigurer, collected extension beans, @EasyQueryTrack, multi-datasource starter limits: references/spring-boot-starter.md. Pair with references/configuration-starter.md only for property impact.
EasyQueryClient beans, baomidouDynamicRoutingDataSource, @DS, or @EasyQueryTrack(tag=...) across several clients: references/multi-datasource.md. Pair with references/spring-boot-starter.md when the answer also depends on starter internals or collected extension beans.
easy-query.enable / easy-query.build, or behaviordrift from code: references/configuration-starter.md.
references/advanced.md.
@EntityProxy, @Column, @Version, @LogicDelete:references/entity-mapping.md.
@EasyAlias, @TableIndex,@ColumnIgnore, @InsertIgnore, @UpdateIgnore, primaryKeyGenerator, generatedSQLColumnGenerator, schema, oldName, or @EntityFileProxy: references/entity-modeling-advanced.md.
generatedKey,generatedSQLColumnGenerator, primaryKeyGenerator, insert id backfill, or starter/manual generator registration: references/primary-key-generation.md. Pair with references/write-insert-upsert.md when the question also depends on executeRows(true) or insert-chain behavior.
sqlExpression, sqlConversion,cross-table computed fields, autoSelect=false, or current @ValueObject usage: references/entity-computed-properties.md.
@Navigate cardinality/direction or a missing relation path:references/relation-query.md. Tree/self-relation entity modeling also starts here.
@NavigateFlat,@IncludeOnProperty, navigate extras: references/entity-modeling-navigate.md.
include, include2, loadInclude,fillOne/fillMany: references/include-structured-loading.md.
selectAutoInclude, extras, and includeoverride precedence: references/select-auto-include.md.
references/query.md.
.set(...): references/query-composition.md.
where/select/from/join subquery, exists/notExists/in/notIn,expression().subQueryable(...), setSubQuery(...), derived table, or toCteAs(): references/subquery-explicit.md. Pair with references/implicit-query.md only when a relation-driven alternative or subQueryToGroupJoin(...) tradeoff matters.
ranked child, tree: references/implicit-query.md.
any/all/none/notEmptyAll/subQueryConfigure/filter/configure/mode/flatElement/valueOf: references/implicit-controls.md. Pair with references/implicit-query.md when partition/tree/group-join behavior matters.
references/ap-analytics.md. Pair with references/implicit-query.md for repeated to-many relation metrics or relation-derived dimensions.
return: references/search-form-page.md.
whereObject(...), orderByObject(...), @EasyWhereCondition,relation-path filters, ObjectSortBuilder, WhereObjectQueryExecutor: references/dto-object-query.md.
EasySearch, @EasyCond, sql-search operator inference:references/easy-search.md.
valueConvert, casts, path access, and typed database-function writing such as concat / date functions / math functions / JSON functions: references/typed-sql-expressions.md.
functions that are not already exposed by the typed surface: references/native-sql.md.
references/write.md.
columnConfigure(...):references/write-insert-upsert.md.
setColumns/setIgnoreColumns/whereColumns/optimistic lock: references/write-update.md.
object delete: references/write-delete.md.
TrackManager / asTracking / addTracking /@EasyQueryTrack: references/write-tracking.md.
@Transactional:references/transaction.md.
savable(...), including @SaveKey non-PKmatching for many-to-many middle tables: references/savable-aggregate.md.
savePath, root controls, ownership/cascade, @SaveKey business-key matching, or child key safety, start at references/savable-aggregate.md and follow its router instead of opening all savable references at once.
name()mapping via @Enumerated, JdbcTypeHandler, PostgreSQL jsonb: references/value-conversion-type-handler.md.
useInterceptor(...) / noInterceptor(...): references/interceptor.md.
escape hatch: references/logic-delete.md.
references/symbol-imports.md.
references/api-map.md.
references/testing.md.
known: references/troubleshooting.md.
an existing @Navigate path can express the requirement.
@ValueObject for new modeling without noting thatcurrent source marks it deprecated.
simple aggregate into entity computed properties nor rule modeling out when reusable model-level meaning is reasonably likely.
default query ids first -> .in(...) -> build tree template.
singleOrNull() for unique business keys.selectAutoInclude, not database entityclasses. Explain that nested child data is fetched by separate include-style relation queries per relation path, not by a single joined SQL statement.
selectAutoInclude, distinguish root filtering from child-list pruning:use root .where(...) for root eligibility, and prefer EXTRA_AUTO_INCLUDE_CONFIGURE.where(...) when child rows should be pruned while the root row stays.
EXTRA_AUTO_INCLUDE_CONFIGURE over scattering one-off include(...) adapters across service methods.
include2 for more complex nested relation loading.ProxyEntityAvailable is required for proxy generation unlessthe project specifically requires interface mode for usage style.
APIs over Java Stream regrouping, manual SQL strings, or post-query in-memory metrics.
and do not drift into raw SQL fragment advice unless that surface is truly missing.
sqlQuery(...) if the rawSQL is only the FROM seed and the rest should still use easy-query DSL; prefer queryable(rawSql, Entity.class, params) in that case.
rawSQLCommand(...) andrawSQLStatement(...) over older expression().sql(...) / expression().sqlSegment(...) compatibility forms unless the project code already uses the older surface or the answer specifically needs lower-level format(...) / messageFormat() control.
value(...) from literal insertion format(...), and mention messageFormat() / keep-style quoting if the SQL template itself contains quoted literals plus placeholders.
aggregate expressions, grouped proxy access, or explicit window outputs.
elements(start,end) to string concatenation only; currentsource returns SQLQueryable after elements(...), so ranked-window slices can continue into aggregate or predicate chains when the API surface fits.
every update request with updatable(entity).executeRows().
deletable(Entity.class) and deletable(entity) into one generic delete shape.
query-then-loop or query-ids-then-delete flows without a dialect-specific reason.
updatable(entity).setColumns(...), mention whereColumns(...)when the write condition must stay explicit.
asTracking() alone enables diff update; explicitly mention anactive tracking context (@EasyQueryTrack or manual TrackManager.begin()), and explicitly mention the tracked entity requirement: the tracked entity itself must have been added to the active tracking context via asTracking() or addTracking(...).
savable(...) as if transaction or track context wereoptional; current source requires both before execution, and the root or child entities being diff-saved must also be in the active tracking context.
savable(...) as a generic recursive save for aggregate-rootnavigations such as many-to-one parent objects.
ALLOW_OWNERSHIP_CHANGE casually; it changes ownershipsafety semantics.
onConflictThen(...) without calling out constraint-columnselection semantics and the ALL_COLUMNS caveat when conflict columns may be omitted by strategy.
drivers.
batch() semantics precisely: batch() equals batch(true), itenables the JDBC batch execution path for the current chain, and batch(false) disables it.
expression().subQueryable(...) over an independently created root query unless detached composition is intentional.
where(...); end it asexists, notExists, in, notIn, or scalar comparison.
JdbcTypeHandler when an in-memory ValueConverter issufficient.
ValueConverter alone when the real problem is JDBCbinding/driver behavior such as PostgreSQL jsonb PGobject writes.
@Enumerated on the enum type(it is @Target(TYPE), registered globally via NamedEnumValueAutoConverter, stores name() as a varchar, and needs no per-field @Column). Do not put @Enumerated on the entity field; it has no effect there. For numeric/code enums keep the IEnum + ValueConverter path and do not add @Enumerated to those enums. An explicit @Column(conversion = Xxx.class) on a field still overrides the @Enumerated auto converter for that field only.
generatedKey, generatedSQLColumnGenerator,primaryKeyGenerator, and saveEntitySetPrimaryKey(...); they solve different phases of key assignment.
savable(...) many-to-many middle tables whose rows should match by abusiness composite key (e.g. (rootId, manyId)) rather than a surrogate PK, put @SaveKey (com.easy.query.core.annotation.SaveKey, @Target(FIELD)) on those fields. It is an in-memory matching identity used only inside the savable diff — it does NOT change generated SQL WHERE/SET (still PK-based) and has no effect on direct insertable/updatable/deletable. Do not confuse it with saveEntitySetPrimaryKey(...) (backend PK assignment for untracked children); they are orthogonal. See savable-relation-rules.md §5.5.
executeRows(true) as if Java-side PrimaryKeyGeneratorneeded it.
data-permission rules instead of repeating ad hoc where/set logic in every service.
useInterceptor(...) / noInterceptor(...) semantics precisely:useInterceptor(name) does not mean “only this one”, and ProtectedInterceptor survives global noInterceptor() unless removed by noInterceptor(name).
disableLogicDelete() as a harmless default.
tableLogicDelete(...) for a joined table and relation.configure(q -> q.disableLogicDelete()) for a relation path when only part of a query graph should ignore logical delete.
ValueFilterautomatically propagate to independent explicit subqueries.
easy-query.enable: true ismandatory unless the project version proves a different condition implementation. Both easy-query.enable and easy-query.build conditions use matchIfMissing=true, so the property being absent keeps the auto-configuration enabled by default. Only setting the property to false explicitly disables the corresponding behavior. Prefer references/configuration-starter.md for version-specific details.
JdbcTypeHandler bean auto-binds globally; mention JdbcTypeHandlerReplaceConfigurer.
build path injects a single DataSource; recommend @Primary only when one default client is acceptable, otherwise use custom beans or easy-query.build=false.
EasyMultiEntityQuery asbuilt-in framework APIs unless the project itself defines them.
import line or FQCN on first mention if the original snippet omitted it.
references/symbol-imports.md; neverconstruct or guess the FQCN from partial domain knowledge or inferred package hierarchy.
Order of truth:
If the project version differs from the reference version, prefer the project and flag APIs that may have moved.
Lead with working code. For troubleshooting, lead with the first failing layer and the next concrete check or fix. For AP/reporting, state the dimension -> metric -> filter -> rank/union/cte shape before dropping into code when that framing prevents wrong SQL structure. Cite a reference only for non-obvious API, SQL-shape, or version caveat.
"name the property", or "what exact call", override the code-first rule and answer with only the direct invocation identifier or exact call shape, then stop. Prefer the callable method or exact builder-chain call over a backing class, interface, or generator name when the user is asking what to invoke. Do not add code blocks, FQCNs, import lines, package paths, signatures, parameter lists, usage examples, documentation references, or extra explanation unless the user explicitly asks for "how", "why", or "explain".
If compile-ready code uses non-obvious easy-query annotations, enums, starter SPI, or extension types, include the needed imports instead of assuming the reader can recover them from context.
disableLogicDelete() and allowDeleteStatement(true) are required; do not omit the latter.
recursive-member filtering: outer .where(...) before .asTreeCTE(...) filters only the seed rows; use setChildFilter(...) or equivalent tree CTE config to control the recursive step.
stated in this file, answer directly from that guidance and answer directly without opening external reference files. Use the exact phrasing from the review check as the authoritative source; do not paraphrase or substitute entity/type names. Only open a reference when the question needs API-level detail, code examples, or deeper explanation beyond what the review checks state.
or should say, quote the relevant review-check wording directly in the answer, including negatives such as do not, not, without, or requires both, rather than paraphrasing.
actual import line or FQCN in the answer from references/symbol-imports.md; do not defer to the reference for that concrete value.
the skill and references; do not reword or generalize them.
entity property (e.g., version), prefer the entity-side annotation @IncludeOnProperty on the @Navigate field. Do not drift into DTO child filtering via EXTRA_AUTO_INCLUDE_CONFIGURE as the first approach; note that EXTRA_AUTO_INCLUDE_CONFIGURE is a query-time DTO child-list pruning knob, not an entity metadata gating mechanism. Also, note that loadInclude(...) evaluates already-loaded root objects in memory before issuing relation queries, so entity-side @IncludeOnProperty metadata still applies to loadInclude calls. Route to references/entity-modeling-navigate.md for entity-side conditional navigation.
selectAutoInclude, always preserve the DTO/VO class literal in thecall (e.g., selectAutoInclude(ResultDTO.class)). Do not substitute a different class name or omit the class argument; without the class literal, easy-query cannot determine which nested relations to include.
type parameters or arguments (for example, selectAutoInclude(ResultDTO.class)), reproduce the full call expression including generic type arguments rather than naming only the bare method; do not abbreviate to a method-only form.
what makes the API semantically correct, include the necessary argument value instead of truncating to the bare method name. For example, allowDeleteStatement(true) is materially different from allowDeleteStatement(), and queryable(rawSql, Entity.class, params) is more precise than a bare queryable.
the API"), the answer must be only the identifier or exact call shape, without code blocks, explanation, or extra context. Do not include the class name, package, or usage example unless explicitly asked.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.