Repository navigation
feat(timeline): read the documents GLPI links to a followup (0.6.4) - #43
Merged
Merged
Conversation
…TIMELINE for position -1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…links Reads <Itemtype>/<id>/Document_Item over the legacy v1 session and returns GetDocumentItem rows. The itemtype and id are validated before any call, the range 0-999 is sent, an empty body reads as no rows, any other non-list answer raises, and a full page of 1000 rows or more raises rather than returning a possibly truncated list. The followup route is the one measured live. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wups for their document links Lists each followup's Document_Item links through list_item_documents and returns one FollowupDocuments (the followup and its links) per kept followup, in ascending followup id. By default private and flag-less followups are dropped and never queried; include_private=True keeps them, so a caller can classify every link from followup.is_private. Link rows that do not name the followup are dropped, a followup without an id raises, and a failed read propagates rather than returning a partial list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… followup (0.6.4) Bumps the version in pyproject.toml, the package and every skill, adds the CHANGELOG entry, and describes list_item_documents, list_ticket_followup_documents and NO_TIMELINE in the user guide. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d reflow the model list list_ticket_followup_documents builds (id, followup) pairs with an explicit None check, so mypy narrows the id instead of passing through Any. Its docstring states one v1 request per kept followup. The user guide lists GetDocumentItem and FollowupDocuments apart from the models with post / patch / delete variants, the timeline skill points to the new method, and a test pins that GlpiTimelinePosition(-1) still names INVALID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #43 +/- ##
==========================================
+ Coverage 97.92% 97.96% +0.03%
==========================================
Files 90 91 +1
Lines 3476 3536 +60
==========================================
+ Hits 3404 3464 +60
Misses 72 72 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
GLPI's editor links an image pasted into a followup to the followup (
ITILFollowup), not to the ticket.list_ticket_timeline_documentsuses the v2 timeline route, which returns only the ticket's ownDocument_Itemlinks, so it never returns such an image. A caller that mirrors a ticket's followups therefore cannot resolve the images inside them. Measured on a live server: a description paste is linked to the ticket, and a followup paste is linked to the followup only.The v1 sub-item route
ITILFollowup/<id>/Document_Itemdoes return those links. This release reads it.What
list_item_documents(itemtype, items_id)lists one item's v1Document_Itemlinks asGetDocumentItemrows.v1_base_url,v1_user_token) and raisesRuntimeErrorwithout one.itemtypemust match^[A-Za-z][A-Za-z0-9_]*$and the id must be positive, because both go into the URL path. Otherwise it raisesGlpiValidationErrorbefore any call.range=0-999. GLPI was checked to honourrangeon a sub-item route. An answer of 1000 rows or more raisesGlpiValidationError, because the page may be truncated, so a partial list is never returned.{}, the v1 helper's empty-body result, gives[]. Any other non-list answer raises.list_ticket_followup_documents(ticket_id, *, include_private=False)walks a ticket's followups and returns oneFollowupDocumentsper kept followup: the followup itself and its links.is_privateflag is missing, are dropped and never queried by default.include_private=Truekeeps every followup, andfollowup.is_privatelets the caller classify each link.gather: concurrent on the async surface, sequential on the sync one.GetDocumentItemis the v1 link row:id,documents_id,itemtype,items_id,entities_id, the three dates (localised) andtimeline_position. Other keys (users_id,is_recursive,links) stay inextra_payload.GlpiTimelinePosition.NO_TIMELINEis GLPI's own name for-1, an alias ofINVALID. Existing uses are unchanged, andGlpiTimelinePosition(-1).nameis still"INVALID". GLPI's editor writes-1on the link of an image it embeds, and such a link is hidden from the ticket's Documents tab. An attachment upload is linked at1.FollowupDocumentsandGetDocumentItemare exported from the package root.__version__, skills).Tasks and solutions are not walked, and their routes are not measured.
Verification
{}handling, the session guard, the privacy default, the flag-less followup, the row filter, ordering, empty followups and failure propagation.unasync_build.py --checkandsphinx -Wall clean.example.invalidURLs.🤖 Generated with Claude Code