docs: Introduce initial docs for service module (Preview)#2350
docs: Introduce initial docs for service module (Preview)#2350TomCools wants to merge 13 commits into
Conversation
triceo
left a comment
There was a problem hiding this comment.
Some notes after a first quick look.
| :sectnums: | ||
| :icons: font | ||
| :relevance: both | ||
| :notes: Relevant, needs some rewrites. Also should include the "Getting Started" for Quarkus (raw) and Spring |
There was a problem hiding this comment.
Is this a third thing? "core", "service" and "raw"?
There was a problem hiding this comment.
raw => Core + Quarkus plugin integration. That should be clarified. It's the weird double right now.
| @@ -0,0 +1,28 @@ | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
There was a problem hiding this comment.
I never much liked copy-pasting stuff from production code. Gets quickly outdated and forgotten about, until some user points it out.
Any chance we could have a live mechanism to point to an authoritative piece of source code, such as one in the quickstarts repo?
There was a problem hiding this comment.
Under investigation ;) We have a similar problem for all of the quickstarts btw.
|
|
||
| * **Knowledge** | ||
| ** Java (Basic) | ||
| ** Quarkus (Basic) |
There was a problem hiding this comment.
This is IMO where you immediately lose Spring people.
We can only keep Spring people if we treat the service as a black box that uses no technology which the user needs to care about.
There was a problem hiding this comment.
Q: What is the exact quarkus knowledge that is needed?
There was a problem hiding this comment.
Until we fully abstract Quarkus away and it is a black box, the reference should stay. It's just being up-front of what is needed.
| Open the http://localhost:8080/q/swagger-ui/[Swagger OpenAPI Viewer] to inspect the generated API Endpoints: | ||
| http://localhost:8080/q/swagger-ui/ | ||
|
|
||
| image:quickstart/mdk/openapi.png[Screenshot of the Swagger OpenAPI UI showing the automatically generated REST API endpoints] |
There was a problem hiding this comment.
Folder name "mdk" to be updated?
| :sectnums: | ||
| :icons: font | ||
|
|
||
| :relevance: both |
There was a problem hiding this comment.
:relevance: is just something internal? an annotation? or does it trigger something automatically?
There was a problem hiding this comment.
Doesn't trigger anything, just metadata for me while refactoring the docs, so i don't have to keep a separate file with this info.
|
|
||
| include::_preview-note.adoc[] | ||
|
|
||
| Run optimization as a fully isolated service. |
There was a problem hiding this comment.
PP: Dataset optimization
| "name": "run name", | ||
| "termination": { | ||
| "spentLimit": "PT5M", | ||
| "unimprovedSpentLimit": "PT10S" |
There was a problem hiding this comment.
Q: There probably are more terminations now? stepCount?
There was a problem hiding this comment.
I will make an issue to tackle this. Describing the terminations would be a new section.
#2359
External loading doesn't work in Antora, at least not close to the source.
35dd6f5 to
631a585
Compare
|
Moving this to a full PR (no longer draft). I have added tickets for most tasks, still left a few TODOs in the code (which doesn't get rendered. |
|
I remembered I still need to update some of the maven dependencies and links after the final merge, so making it draft again. |
There was a problem hiding this comment.
Pull request overview
This draft PR introduces initial documentation for the new “Service” module (Preview), adds navigation and quickstart content for running Timefold Solver as an isolated optimization service, and annotates existing docs pages with metadata intended to guide future service-vs-library refactoring.
Changes:
- Add a new “Building a service (Preview)” documentation section covering REST API, model enrichment, constraint weight overrides, demo data, and metrics.
- Introduce a new “Run as a service (Preview)” quickstart and restructure the quickstart overview/navigation to distinguish library embedding vs service deployment.
- Add
:relevance:/:notes:metadata to a number of existing pages to flag future content splits/rework.
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/src/modules/ROOT/pages/using-timefold-solver/running-the-solver.adoc | Adds service-vs-core relevance metadata to the “Running the solver” page. |
| docs/src/modules/ROOT/pages/using-timefold-solver/overview.adoc | Adds relevance metadata to indicate shared applicability across library/service. |
| docs/src/modules/ROOT/pages/using-timefold-solver/modeling-planning-problems.adoc | Adds relevance metadata and notes about shared vs service-specific modeling. |
| docs/src/modules/ROOT/pages/using-timefold-solver/configuration.adoc | Marks configuration docs as core-only via relevance metadata. |
| docs/src/modules/ROOT/pages/using-timefold-solver/benchmarking-and-tweaking.adoc | Adds relevance metadata to indicate partial applicability in service mode. |
| docs/src/modules/ROOT/pages/service/rest-api.adoc | New service REST API documentation (generated endpoints, request/response envelope, OpenAPI, validation, etc.). |
| docs/src/modules/ROOT/pages/service/overview.adoc | New top-level “Building a service (Preview)” landing page tying service docs to core concepts. |
| docs/src/modules/ROOT/pages/service/modeling-changes.adoc | New documentation on service-specific modeling concepts (SolverModel, enrichers, enrichment director). |
| docs/src/modules/ROOT/pages/service/exposing-metrics.adoc | New documentation for exposing input/output metrics via the service REST API. |
| docs/src/modules/ROOT/pages/service/demo-data.adoc | New documentation for exposing demo data endpoints via a DemoDataGenerator. |
| docs/src/modules/ROOT/pages/service/constraint-weights.adoc | New documentation describing ModelConfigOverrides and constraint weight overrides in service mode. |
| docs/src/modules/ROOT/pages/service/_preview-note.adoc | Adds a shared preview note included by service pages. |
| docs/src/modules/ROOT/pages/responding-to-change/responding-to-change.adoc | Adds relevance metadata noting service-vs-library differences. |
| docs/src/modules/ROOT/pages/quickstart/shared/school-timetabling/_school-timetabling-solution.adoc | Refactors repeated content into shared include files to reduce duplication. |
| docs/src/modules/ROOT/pages/quickstart/shared/school-timetabling/_school-timetabling-solution-value-range-providers.adoc | New shared include covering value range providers. |
| docs/src/modules/ROOT/pages/quickstart/shared/school-timetabling/_school-timetabling-solution-facts-and-entities.adoc | New shared include covering problem facts vs planning entities. |
| docs/src/modules/ROOT/pages/quickstart/shared/school-timetabling/_school-timetabling-model.adoc | Updates quickstart model docs (including switching Room example to a Java record). |
| docs/src/modules/ROOT/pages/quickstart/shared/school-timetabling/_school-timetabling-constraints.adoc | Updates constraint intro and links for the quickstart. |
| docs/src/modules/ROOT/pages/quickstart/shared/_whatyoubuild.adoc | Rewords “What you will build” to be less REST/service-specific. |
| docs/src/modules/ROOT/pages/quickstart/service/getting-started.adoc | New quickstart for building and running a service-based optimization model (Preview). |
| docs/src/modules/ROOT/pages/quickstart/overview.adoc | Reworks quickstart overview to compare “library” vs “service” approaches and introduce the new service quickstart. |
| docs/src/modules/ROOT/pages/optimization-algorithms/overview.adoc | Adds relevance metadata indicating applicability to both library and service usage. |
| docs/src/modules/ROOT/pages/introduction.adoc | Adds relevance metadata and notes to support future library-vs-service clarification. |
| docs/src/modules/ROOT/pages/integration/integration.adoc | Adds relevance metadata and notes about needed updates for service integration. |
| docs/src/modules/ROOT/pages/frequently-asked-questions.adoc | Adds relevance metadata. |
| docs/src/modules/ROOT/pages/design-patterns/design-patterns.adoc | Adds relevance metadata and internal notes about future restructuring. |
| docs/src/modules/ROOT/pages/constraints-and-score/overview.adoc | Adds relevance metadata for shared applicability. |
| docs/src/modules/ROOT/pages/constraints-and-score/constraint-configuration.adoc | Adds relevance metadata and notes about service-specific patterns. |
| docs/src/modules/ROOT/nav.adoc | Updates navigation to introduce “Run as a service (Preview)” and a library/service split in Getting Started, plus a new service docs subtree. |
| == Request and response structure | ||
|
|
||
| The generated endpoints do not accept/return the pure `ModelInput`/`ModelOutput` objects as JSON. | ||
| Instead, a fixed envelop is used for both the requests and responses of solver actions. |
| "modelOutput": <ModelOutput class as JSON>, | ||
| "inputMetrics": { |
| @ApplicationScoped | ||
| public class TimetableConvertor implements ModelConvertor<HardSoftLongScore, TimetableDto, Timetable, EmptyModelConfigOverrides, EmptyModelInputMetrics, EmptyModelOutputMetrics, Timetable> { | ||
|
|
||
| @Override | ||
| public Timetable toSolverModel(TimetableDto modelInput, TimetableDto previousModelOutput, ModelConfig<EmptyModelConfigOverrides> modelConfig) { | ||
| return // Mapping logic | ||
| } | ||
|
|
||
| @Override | ||
| public Timetable toSolverModel(TimetableDto modelInput, ModelConfig<EmptyModelConfigOverrides> modelConfig) { | ||
| return // Mapping logic | ||
| } | ||
|
|
||
| @Override | ||
| public TimetableDto toModelOutput(Timetable solverModel) { | ||
| return // Mapping logic | ||
| } | ||
| } |
| `GET /v1/timetables/+{id}+/validation-result` | ||
|
|
||
| Assuming the xref:timetableValidatorExample[example TimetableValidator], the endpoint provides the following response: | ||
|
|
||
| .Validation result available via `GET /v1/timetables/+{id}+/validation-result`. |
| To showcase that the model is now ready for use we only need 2 of those endpoints: | ||
|
|
||
| - `POST /v1/timetables`: To request a problem to be solved. This returns a unique identifier which can be used to request the resulting schedule. | ||
| - `GET /v1/timetables/+{id}+`: Get the calculated schedule with the given identifier. |
| To calculate the score, implement a `TimetableConstraintProvider` class. | ||
| It uses Timefold Solver's xref:https://docs.timefold.ai/timefold-solver/latest/constraints-and-score/score-calculation[Constraint Streams API] | ||
| which is inspired by Java Streams and SQL: |
| Your application will assign `Lessons` to `Timeslots` and `Rooms` automatically | ||
| by using AI to adhere to hard and soft scheduling _constraints_, for example: |
| :sectnums: | ||
| :icons: font | ||
| :relevance: core-only | ||
| :notes: Too much things service module does automatically or with 1 single configuration. |
| ConstraintWeightOverrides<HardMediumSoftLongScore> constraintWeightOverrides = ConstraintWeightOverrides.none(); | ||
| constraintWeightOverrides = ConstraintWeightOverrides.of( | ||
| Map.ofEntries( | ||
| Map.entry(TEACHER_CONFLICT, | ||
| HardMediumSoftLongScore.ofHard(modelConfigOverrides.getTeacherConflictWeight())), | ||
| Map.entry(ROOM_COMFLICT, | ||
| HardMediumSoftLongScore | ||
| .ofSoft(modelConfigOverrides.getRoomConflictWeight())); | ||
|
|
||
| solverModel.setConstraintWeightOverrides(constraintWeightOverrides); |
|



Currently providing this PR in DRAFT as a preview of the changes to come. Some content still needs validation and review from my side: e.g. going through the quickstart guide myself again and updating some references, after the service module has been officially released.
We have introduced the "Service" module, but this did not contain any documentation yet.
This PR will: