Skip to content

feat: report unique resources - #2779

Open
rsynek wants to merge 3 commits into
TimefoldAI:mainfrom
rsynek:feat/json-path-resource-reporting
Open

rsynek wants to merge 3 commits into
TimefoldAI:mainfrom
rsynek:feat/json-path-resource-reporting

Conversation

@rsynek

@rsynek rsynek commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

@rsynek
rsynek requested a review from mswiderski October 26, 2026 13:49

@mswiderski mswiderski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice work, especially around the Resolver

@rsynek
rsynek force-pushed the feat/json-path-resource-reporting branch from 7668b6b to 41b2343 Compare October 27, 2026 13:44
@rsynek
rsynek marked this pull request as ready for review October 27, 2026 13:45
@rsynek
rsynek requested a review from a team October 27, 2026 13:45
@rsynek
rsynek requested a review from triceo as a code owner October 27, 2026 13:45
Copilot AI balanced review requested due to automatic review settings October 27, 2026 13:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The immutable image list breaks descriptor generation, and valid input structures can produce missing or incorrect resource paths.

5 open issues
What changed in this PR

This PR adds unique-resource metadata to service model descriptors. It derives resource types and JSONPath expressions from model-input annotations for downstream resource reporting.

Changes:

  • Adds @UniqueResourceId and descriptor storage for resource types and paths.
  • Integrates build-time path discovery into Quarkus descriptor generation.
  • Adds resolver tests and an end-to-end descriptor test.
File Description
service/​definition/​src/​main/​java/​ai/​timefold/​solver/​service/​definition/​api/​ModelDescriptor.java Stores and copies resource metadata; changes collection defaults.
service/​definition/​src/​main/​java/​ai/​timefold/​solver/​service/​definition/​api/​usage/​UniqueResourceId.java Defines the resource-ID annotation.
service/​definition/​src/​main/​java/​ai/​timefold/​solver/​service/​definition/​internal/​descriptor/​usage/​UniqueResource.java Pairs a resource type with its JSONPath.
service/​quarkus/​deployment/​src/​main/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​TimefoldModelDescriptorProcessor.java Adds resource metadata during descriptor generation.
service/​quarkus/​deployment/​src/​main/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​descriptor/​ResourceIdPathResolver.java Traverses indexed input fields to derive resource paths.
service/​quarkus/​deployment/​src/​test/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​ModelDescriptorUniqueResourcesTest.java Checks generated descriptor resource entries.
service/​quarkus/​deployment/​src/​test/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​descriptor/​UniqueResourceIdPathResolverTest.java Tests traversal, field annotations, and blank resource types.
service/​quarkus/​deployment/​src/​test/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​testdata/​uniqueresource/​TestdataVisit.java Provides an annotated visit ID.
service/​quarkus/​deployment/​src/​test/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​testdata/​uniqueresource/​TestdataVehicle.java Provides an annotated vehicle ID and nested visits.
service/​quarkus/​deployment/​src/​test/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​testdata/​uniqueresource/​TestdataSolution.java Provides the test model input structure.
service/​quarkus/​deployment/​src/​test/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​testdata/​uniqueresource/​TestdataRest.java Supplies the test model REST interface.
service/​quarkus/​deployment/​src/​test/​java/​ai/​timefold/​solver/​service/​quarkus/​deployment/​testdata/​uniqueresource/​TestdataConstraintProvider.java Supplies a constraint for the test deployment.

Review effort: Balanced

Comment on lines +148 to +149
private static String jsonName(FieldInfo field) {
var jsonProperty = field.declaredAnnotation(JSON_PROPERTY);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and other problems. E.g. handling @JsonBackReference and other Jackson advanced features.

Also, we don't check the super classes or interfaces where the user can define the ID.

Given these complications, I am not sure if I like it more than the original proposal @mswiderski .

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not over-engineer this - it is only for our models and we know we can do it reliably.

@timefold-automations

timefold-automations Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

This pull request, as it stands, would leave the Solver documentation stale in the places below. An automated check found them and can be wrong.

  1. Code change: TimefoldAI/timefold-solver, service/definition/src/main/java/ai/timefold/solver/service/definition/api/usage/UniqueResourceId.java:8-19 — adds the public @UniqueResourceId annotation and its required type() element (added public API).
    Docs location: no mention found in timefold-solver/docs/src/modules/ROOT/.
    Confidence: high.
    Suggested edit: add a service documentation section, for example in pages/deploying-to-platform/model-metadata.adoc, explaining how to annotate resource ID fields and how the service uses the annotation:
[#uniqueResourceIds]
== Unique resource IDs

Annotate each resource identifier that must be unique within its resource type with `@UniqueResourceId` from `ai.timefold.solver.service.definition.api.usage`.

[source,java]
----
@UniqueResourceId(type = "vehicle")
private String id;
----

The service uses the annotation to report the resource type and the JSONPath to the identifier in the model input.
  1. Code change: TimefoldAI/timefold-solver, service/definition/src/main/java/ai/timefold/solver/service/definition/api/ModelDescriptor.java:70, 280-288 — adds the public uniqueResources model-descriptor property and its getUniqueResources()/setUniqueResources(...) accessors, exposing resource types and JSONPath expressions in generated service metadata (added public API).
    Docs location: no mention found in timefold-solver/docs/src/modules/ROOT/.
    Confidence: high.
    Suggested edit: in the same section, state that generated model metadata contains the discovered resource type and JSONPath for each annotated identifier, for example:
The generated model descriptor exposes these resources through `uniqueResources`.
Each entry contains `resourceType` and `resourceIdJsonPath`, such as `vehicle` and `$.vehicles[*].id`.

The fix goes into this timefold-solver pull request. A new commit on the branch updates this comment, and drift that is still there when the group merges gets a docs pull request against main.

Generated by Solver Docs Drift Review · copilot · gpt56 · 10.1 AIC · ⌖ 3.02 AIC · ⊞ 25.2K · ◷

@rsynek
rsynek force-pushed the feat/json-path-resource-reporting branch from 41b2343 to 060e71e Compare October 27, 2026 16:07
Copilot AI balanced review requested due to automatic review settings October 27, 2026 16:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private static void visitType(IndexView index, Type type, String path, Set<DotName> visitingSet,
List<UniqueResource> resourceList) {
switch (type.kind()) {
case ARRAY -> visitType(index, type.asArrayType().elementType(), path + "[*]", visitingSet, resourceList);

This branch was successfully deployed

1 active deployment
internal — 060e71ef Deployed Oct 27, 2026 by rsynek via approval_required #1122
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants