Skip to content

docs(solution-architect): ISSUE-84 fix -- correct fictional NewSolutionElementRequestBody/initialStatus docstrings - #337

Closed
dwolfson wants to merge 7 commits into
odpi:mainfrom
dwolfson:main
Closed

docs(solution-architect): ISSUE-84 fix -- correct fictional NewSolutionElementRequestBody/initialStatus docstrings#337
dwolfson wants to merge 7 commits into
odpi:mainfrom
dwolfson:main

Conversation

@dwolfson

@dwolfson dwolfson commented Sep 3, 2026

Copy link
Copy Markdown
Member

Summary

SolutionArchitect.create_solution_blueprint/create_solution_component (async + sync, 4 docstrings total) documented a NewSolutionElementRequestBody body class with a top-level initialStatus field as the way to set Draft status at creation. Confirmed that class and field appear in zero .http ground-truth files anywhere in this repo — never a real Egeria API surface, not merely an unmodeled one.

Following the documented shape either:

  • hard-failed client-side pydantic validation (create_solution_blueprintclass literal mismatch, raising PyegeriaInvalidParameterException that reads exactly like a server-side rejection), or
  • silently dropped the field and always created the element ACTIVE regardless of intent (create_solution_component — its example already used the real NewElementRequestBody class, so PyegeriaModel's extra='ignore' swallowed initialStatus with no error at all).

Also found and fixed while walking these: create_solution_blueprint's first ("no lifecycle") example body carried leftover userDefinedStatus/lifecycleStatus fields with a missing comma — invalid JSON even as a copy-paste example.

Fix: all four docstrings now document contentStatus inside properties instead — confirmed against Egeria-api-solution-architect.http's own updateSolutionBlueprintStatus example, and content_status is already a real field on ReferenceableProperties, the base class both SolutionBlueprintProperties and SolutionComponentProperties derive from. No model change needed — NewElementRequestBody.properties is a bare dict, so contentStatus already passes through untouched to the outgoing JSON.

Found via a live consumer report — trellis/Resource Explorer's BlueprintMaterializer (docs/blueprint-materialization-plan.md Phase A), tracked as egeria-python ISSUE-84 in PYEGERIA_ISSUES.md.

Testing

Verified locally (no live Egeria server access from this environment): the original repro's TypeAdapter(NewElementRequestBody).validate_python(...) call with the old shape still fails as expected; the corrected shape ({"class": "NewElementRequestBody", "properties": {..., "contentStatus": "DRAFT"}}) validates cleanly with contentStatus preserved through to the serialized JSON. Full tests/micro-tests/ suite passes clean (exit 0), no regressions.

Not live-verified against a real Egeria server — the original reporter (trellis/Resource Explorer) has live access and is best placed to confirm contentStatus: "DRAFT" at creation actually takes effect server-side before switching BlueprintMaterializer off its current ACTIVE-only workaround.

🤖 Generated with Claude Code

Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
… bug

get_technology_type_elements(get_templates=True) built
skipClassifiedElements as [skip_templates] where skip_templates was ""
when get_templates=True -- sending a one-element list containing an
empty string, not an empty list. Egeria correctly rejects the empty
classification name (OMAG-COMMON-400-018 "The type name  ... is not
recognized"), so every call with get_templates=True fails outright.

Found via a user report: a known live RelationalDatabase asset didn't
appear browsing Technology Types -> Postgres Relational Databases in
egeria-workspaces' Tech Catalog, even though it was directly
retrievable by GUID and correctly tagged
(deployedImplementationType: "PostgreSQL Relational Database"). The
failure is masked downstream -- egeria-workspaces' tech_catalog_handler.py
calls this with get_templates=True unconditionally and treats any "400"
in the error message as "no elements found," so the whole listing
silently renders empty instead of erroring.

Fix: skip_classified_elements = [] if get_templates else ["Template"].
Also corrected the method's docstring sample body, which showed the
same [""] value as if it were correct usage.

Live-verified end-to-end, not just unit-tested: live-patched into
quickstart-pyegeria-web's installed pyegeria (docker cp + restart,
diff-confirmed), then curled the actual production route -- it now
returns the previously-missing asset correctly (15 items with
templates included vs. 14 without, consistent).

Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
…#336 superseded

Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
…ot yet upstream

Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
…onElementRequestBody/initialStatus docstrings

create_solution_blueprint/create_solution_component (async+sync, 4
docstrings total) documented a NewSolutionElementRequestBody body class
with an initialStatus field as the way to set Draft status at creation.
That class and field appear in zero .http ground-truth files anywhere in
this repo -- never a real Egeria API surface, not merely unmodeled -- so
following the documented shape either hard-failed client-side validation
(create_solution_blueprint, class literal mismatch) or silently dropped
the field and created the element ACTIVE regardless of intent
(create_solution_component, NewElementRequestBody's extra='ignore').

Also found and fixed while walking these: create_solution_blueprint's
first example body carried leftover userDefinedStatus/lifecycleStatus
fields with a missing comma, invalid JSON even as a copy-paste example.

Fix: all four docstrings now document contentStatus inside properties
instead -- confirmed against Egeria-api-solution-architect.http's own
updateSolutionBlueprintStatus example, and content_status is already a
real field on ReferenceableProperties, the base class both
SolutionBlueprintProperties and SolutionComponentProperties derive from.
No model change needed; NewElementRequestBody.properties is a bare dict
so contentStatus already passes through untouched.

Verified locally: the old shape still fails validation as expected, the
corrected shape validates cleanly with contentStatus preserved through to
serialized JSON. Not live-verified against a real Egeria server (no
access from this environment) -- reported by dwolfson-1b/trellis via
ISSUE-84, who has live access to confirm contentStatus=DRAFT actually
takes effect server-side at creation time.

Full detail in PYEGERIA_ISSUES.md ISSUE-84.

Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
@dwolfson

dwolfson commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

Closing in favor of a clean PR — this one was opened from dwolfson:main, which drags in unrelated fork history and conflicts with PYEGERIA_ISSUES.md edits already merged upstream via #335/#336. Reopening the same fix as a dedicated branch off current upstream/main.

@dwolfson dwolfson closed this Sep 3, 2026
dwolfson added a commit to dwolfson/trellis that referenced this pull request Sep 3, 2026
…og item 6)

materialize_blueprint_element sent class: "NewSolutionElementRequestBody"
with initialStatus: "DRAFT", per SolutionArchitect.create_solution_blueprint's
own docstring — but that class was never a real pydantic model. pyegeria
validates every create-blueprint body against a bare
TypeAdapter(NewElementRequestBody), whose class field is
Literal["NewElementRequestBody"], so this failed local pydantic validation
before any HTTP call — a PyegeriaInvalidParameterException that read like
an Egeria-side rejection but wasn't one. Confirmed live 2026-09-03
accepting a real candidate blueprint against sqlglot.

Root cause was worse than the missing model, per egeria-python's own
review (ISSUE-84, egeria-python-65, PR odpi/egeria-python#337):
NewSolutionElementRequestBody/initialStatus never appeared in any .http
ground-truth file either — the real, already-modeled mechanism is
contentStatus inside properties (ReferenceableProperties, base of
SolutionBlueprintProperties/SolutionComponentProperties). That fix isn't
adopted here yet — needs live confirmation that contentStatus at creation
time actually takes effect server-side, blocked right now by unrelated
platform instability. This commit ships the immediate, verified-safe fix:
class: "NewElementRequestBody", no initialStatus — the same body shape
ComponentMaterializer already uses successfully. Blueprints materialize
ACTIVE, not Draft, same pre-existing gap ComponentMaterializer already has.

Two new/replaced tests in test_blueprint_materializer.py, including one
that validates the actual body against pyegeria's real
TypeAdapter(NewElementRequestBody) rather than only asserting the mock
call shape — the kind of test that would have caught this before it
reached a live accept.

Backlog.md item 6 updated with the fix and the deferred contentStatus
follow-up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
dwolfson added a commit to dwolfson/trellis that referenced this pull request Sep 3, 2026
…us materialization)

Follow-up to the previous commit's ACTIVE-only fallback. egeria-python-65
reviewed ISSUE-84 and found the real mechanism (odpi/egeria-python#337):
contentStatus is a plain field on ReferenceableProperties (base of
SolutionBlueprintProperties), settable inside properties on the existing
NewElementRequestBody — no separate request-body class was ever needed.

Confirmed live, twice, each independently read back by guid rather than
trusted from the create call's own return:
- Standalone probe (guid 1c6550a9-77cd-49ac-a791-ffb9fa56f3fc, then
  8755a5ac-7941-4880-a735-72010d779a73 to check the properties-block
  shape) — properties.contentStatus == "DRAFT" via
  get_solution_blueprint_by_guid.
- A real accept through the actual Curate UI's own API endpoint
  (POST /api/curate/blueprint-verdicts/repo/sqlglot, not a direct library
  call) materialized guid 809025b5-cca9-4e9a-a2f7-3a5104138f67,
  independently re-queried and confirmed the same.

Both checks: properties.contentStatus round-trips as "DRAFT" correctly;
elementHeader.status stays "ACTIVE" — a separate, unrelated instance-status
axis (OMRS soft-delete/active at the repository level), not the same thing
as the content-maturity axis contentStatus represents. The design doc's
own wording ("ContentStatus = Draft") names the field this now sends.

architecture-recovery.md §10 Phase 2's "All at ContentStatus = Draft" is
now achieved for blueprints. ComponentMaterializer's identical gap (still
NewElementRequestBody with no contentStatus) is NOT fixed here — separate,
still-open follow-up, out of scope for this module.

One new regression test (test_content_status_draft). Full suite: 3653
passed, 92 skipped, 1 deselected (a pre-existing, unrelated live-Egeria
test flaky only during the platform's connection-pool-exhaustion window
this session also found and reported), 0 failed.

Backlog.md item 6 updated with the full resolution.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Dan Wolfson <dan.wolfson@pdr-associates.com>
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.

1 participant