targetprocess-py 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. targetprocess_py-0.1.0/.coderabbit.yaml +147 -0
  2. targetprocess_py-0.1.0/.commitlintrc.json +35 -0
  3. targetprocess_py-0.1.0/.env.example +25 -0
  4. targetprocess_py-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +80 -0
  5. targetprocess_py-0.1.0/.github/ISSUE_TEMPLATE/config.yml +9 -0
  6. targetprocess_py-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +66 -0
  7. targetprocess_py-0.1.0/.github/dependabot.yml +107 -0
  8. targetprocess_py-0.1.0/.github/labels.yml +56 -0
  9. targetprocess_py-0.1.0/.github/pull_request_template.md +62 -0
  10. targetprocess_py-0.1.0/.github/workflows/ci.yml +106 -0
  11. targetprocess_py-0.1.0/.github/workflows/commit-message.yml +30 -0
  12. targetprocess_py-0.1.0/.github/workflows/release.yml +137 -0
  13. targetprocess_py-0.1.0/.gitignore +61 -0
  14. targetprocess_py-0.1.0/.jscpd.json +15 -0
  15. targetprocess_py-0.1.0/.pre-commit-config.yaml +97 -0
  16. targetprocess_py-0.1.0/.python-version +1 -0
  17. targetprocess_py-0.1.0/.tool-versions +1 -0
  18. targetprocess_py-0.1.0/CHANGELOG.md +101 -0
  19. targetprocess_py-0.1.0/CODEOWNERS +14 -0
  20. targetprocess_py-0.1.0/CODE_OF_CONDUCT.md +132 -0
  21. targetprocess_py-0.1.0/CONTRIBUTING.md +233 -0
  22. targetprocess_py-0.1.0/LICENSE +21 -0
  23. targetprocess_py-0.1.0/PKG-INFO +476 -0
  24. targetprocess_py-0.1.0/README.md +437 -0
  25. targetprocess_py-0.1.0/SECURITY.md +55 -0
  26. targetprocess_py-0.1.0/SPEC.md +951 -0
  27. targetprocess_py-0.1.0/docs/USAGE.md +588 -0
  28. targetprocess_py-0.1.0/docs/testing.md +128 -0
  29. targetprocess_py-0.1.0/examples/README.md +62 -0
  30. targetprocess_py-0.1.0/examples/bulk_updates.py +132 -0
  31. targetprocess_py-0.1.0/examples/create_bug.py +117 -0
  32. targetprocess_py-0.1.0/examples/list_user_stories.py +68 -0
  33. targetprocess_py-0.1.0/examples/readonly_reporting.py +78 -0
  34. targetprocess_py-0.1.0/pyproject.toml +161 -0
  35. targetprocess_py-0.1.0/scripts/apply_labels.sh +86 -0
  36. targetprocess_py-0.1.0/scripts/check_commit_message.py +122 -0
  37. targetprocess_py-0.1.0/scripts/check_internal_refs.py +169 -0
  38. targetprocess_py-0.1.0/scripts/check_large_files.py +100 -0
  39. targetprocess_py-0.1.0/scripts/check_model_coverage.py +538 -0
  40. targetprocess_py-0.1.0/scripts/check_todos.py +107 -0
  41. targetprocess_py-0.1.0/scripts/live_smoke.py +303 -0
  42. targetprocess_py-0.1.0/src/targetprocess/__init__.py +231 -0
  43. targetprocess_py-0.1.0/src/targetprocess/_assignables.py +162 -0
  44. targetprocess_py-0.1.0/src/targetprocess/_base.py +318 -0
  45. targetprocess_py-0.1.0/src/targetprocess/_content.py +287 -0
  46. targetprocess_py-0.1.0/src/targetprocess/_dates.py +70 -0
  47. targetprocess_py-0.1.0/src/targetprocess/_entity_types.py +33 -0
  48. targetprocess_py-0.1.0/src/targetprocess/_generals.py +324 -0
  49. targetprocess_py-0.1.0/src/targetprocess/_joins.py +217 -0
  50. targetprocess_py-0.1.0/src/targetprocess/_lookups.py +477 -0
  51. targetprocess_py-0.1.0/src/targetprocess/_nested.py +223 -0
  52. targetprocess_py-0.1.0/src/targetprocess/_observability.py +368 -0
  53. targetprocess_py-0.1.0/src/targetprocess/client.py +430 -0
  54. targetprocess_py-0.1.0/src/targetprocess/exceptions.py +147 -0
  55. targetprocess_py-0.1.0/src/targetprocess/models.py +121 -0
  56. targetprocess_py-0.1.0/src/targetprocess/py.typed +1 -0
  57. targetprocess_py-0.1.0/src/targetprocess/request_handler.py +724 -0
  58. targetprocess_py-0.1.0/src/targetprocess/resources/__init__.py +76 -0
  59. targetprocess_py-0.1.0/src/targetprocess/resources/assignments.py +29 -0
  60. targetprocess_py-0.1.0/src/targetprocess/resources/attachments.py +164 -0
  61. targetprocess_py-0.1.0/src/targetprocess/resources/base.py +563 -0
  62. targetprocess_py-0.1.0/src/targetprocess/resources/bugs.py +20 -0
  63. targetprocess_py-0.1.0/src/targetprocess/resources/comments.py +23 -0
  64. targetprocess_py-0.1.0/src/targetprocess/resources/custom_activities.py +56 -0
  65. targetprocess_py-0.1.0/src/targetprocess/resources/custom_fields.py +27 -0
  66. targetprocess_py-0.1.0/src/targetprocess/resources/custom_rules.py +28 -0
  67. targetprocess_py-0.1.0/src/targetprocess/resources/entities.py +433 -0
  68. targetprocess_py-0.1.0/src/targetprocess/resources/entity_states.py +20 -0
  69. targetprocess_py-0.1.0/src/targetprocess/resources/entity_types.py +61 -0
  70. targetprocess_py-0.1.0/src/targetprocess/resources/epics.py +20 -0
  71. targetprocess_py-0.1.0/src/targetprocess/resources/features.py +20 -0
  72. targetprocess_py-0.1.0/src/targetprocess/resources/iterations.py +20 -0
  73. targetprocess_py-0.1.0/src/targetprocess/resources/priorities.py +85 -0
  74. targetprocess_py-0.1.0/src/targetprocess/resources/processes.py +65 -0
  75. targetprocess_py-0.1.0/src/targetprocess/resources/projects.py +20 -0
  76. targetprocess_py-0.1.0/src/targetprocess/resources/relation_types.py +59 -0
  77. targetprocess_py-0.1.0/src/targetprocess/resources/relations.py +34 -0
  78. targetprocess_py-0.1.0/src/targetprocess/resources/releases.py +20 -0
  79. targetprocess_py-0.1.0/src/targetprocess/resources/requests.py +20 -0
  80. targetprocess_py-0.1.0/src/targetprocess/resources/role_efforts.py +21 -0
  81. targetprocess_py-0.1.0/src/targetprocess/resources/roles.py +52 -0
  82. targetprocess_py-0.1.0/src/targetprocess/resources/severities.py +53 -0
  83. targetprocess_py-0.1.0/src/targetprocess/resources/tasks.py +20 -0
  84. targetprocess_py-0.1.0/src/targetprocess/resources/team_assignments.py +21 -0
  85. targetprocess_py-0.1.0/src/targetprocess/resources/team_iterations.py +24 -0
  86. targetprocess_py-0.1.0/src/targetprocess/resources/teams.py +20 -0
  87. targetprocess_py-0.1.0/src/targetprocess/resources/terms.py +28 -0
  88. targetprocess_py-0.1.0/src/targetprocess/resources/test_cases.py +20 -0
  89. targetprocess_py-0.1.0/src/targetprocess/resources/times.py +392 -0
  90. targetprocess_py-0.1.0/src/targetprocess/resources/user_stories.py +20 -0
  91. targetprocess_py-0.1.0/src/targetprocess/resources/users.py +20 -0
  92. targetprocess_py-0.1.0/src/targetprocess/resources/workflows.py +27 -0
  93. targetprocess_py-0.1.0/src/targetprocess/response_parser.py +113 -0
  94. targetprocess_py-0.1.0/src/targetprocess/transport.py +116 -0
  95. targetprocess_py-0.1.0/src/targetprocess/types.py +56 -0
  96. targetprocess_py-0.1.0/tests/__init__.py +1 -0
  97. targetprocess_py-0.1.0/tests/_support/__init__.py +1 -0
  98. targetprocess_py-0.1.0/tests/_support/request_handler.py +74 -0
  99. targetprocess_py-0.1.0/tests/conftest.py +123 -0
  100. targetprocess_py-0.1.0/tests/integration/__init__.py +1 -0
  101. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_entity_types_catalogue_parses.yaml +209 -0
  102. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_find_for_day_matches_a_real_entry.yaml +159 -0
  103. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_generic_entities_comment.yaml +88 -0
  104. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_get_single_with_include.yaml +176 -0
  105. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_list_user_stories_parses.yaml +154 -0
  106. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_pagination_crosses_page_boundary.yaml +999 -0
  107. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_priorities_scoped_to_an_entity_type.yaml +87 -0
  108. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_severities_rank_the_bug_set.yaml +82 -0
  109. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite/test_bulk_create_and_update_tasks_under_a_story.yaml +807 -0
  110. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite/test_request_create_update_delete_round_trip.yaml +361 -0
  111. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite/test_user_story_create_update_delete_round_trip.yaml +359 -0
  112. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_assignment_create_and_delete.yaml +487 -0
  113. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_attachment_upload_list_download_and_delete.yaml +655 -0
  114. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_comment_create_update_delete_round_trip.yaml +497 -0
  115. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_relation_create_and_delete.yaml +660 -0
  116. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_role_effort_create_update_delete_round_trip.yaml +620 -0
  117. targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_team_assignment_create_and_delete.yaml +564 -0
  118. targetprocess_py-0.1.0/tests/integration/conftest.py +520 -0
  119. targetprocess_py-0.1.0/tests/integration/test_live_readonly.py +120 -0
  120. targetprocess_py-0.1.0/tests/integration/test_live_readwrite.py +279 -0
  121. targetprocess_py-0.1.0/tests/integration/test_live_readwrite_surfaces.py +482 -0
  122. targetprocess_py-0.1.0/tests/live_payloads.py +84 -0
  123. targetprocess_py-0.1.0/tests/test_assignment.py +38 -0
  124. targetprocess_py-0.1.0/tests/test_attachment.py +68 -0
  125. targetprocess_py-0.1.0/tests/test_bug.py +98 -0
  126. targetprocess_py-0.1.0/tests/test_cassette_guard.py +405 -0
  127. targetprocess_py-0.1.0/tests/test_cassette_sanitiser.py +533 -0
  128. targetprocess_py-0.1.0/tests/test_client.py +252 -0
  129. targetprocess_py-0.1.0/tests/test_comment.py +59 -0
  130. targetprocess_py-0.1.0/tests/test_commit_message.py +146 -0
  131. targetprocess_py-0.1.0/tests/test_custom_activity.py +44 -0
  132. targetprocess_py-0.1.0/tests/test_custom_field.py +50 -0
  133. targetprocess_py-0.1.0/tests/test_custom_field_value.py +50 -0
  134. targetprocess_py-0.1.0/tests/test_custom_rule.py +32 -0
  135. targetprocess_py-0.1.0/tests/test_entity_extras.py +262 -0
  136. targetprocess_py-0.1.0/tests/test_entity_ref.py +88 -0
  137. targetprocess_py-0.1.0/tests/test_entity_state.py +46 -0
  138. targetprocess_py-0.1.0/tests/test_entity_type.py +46 -0
  139. targetprocess_py-0.1.0/tests/test_epic.py +55 -0
  140. targetprocess_py-0.1.0/tests/test_exceptions.py +124 -0
  141. targetprocess_py-0.1.0/tests/test_feature.py +73 -0
  142. targetprocess_py-0.1.0/tests/test_integration_request_response.py +108 -0
  143. targetprocess_py-0.1.0/tests/test_internal_refs.py +190 -0
  144. targetprocess_py-0.1.0/tests/test_iteration.py +58 -0
  145. targetprocess_py-0.1.0/tests/test_model_field_coverage.py +578 -0
  146. targetprocess_py-0.1.0/tests/test_models.py +168 -0
  147. targetprocess_py-0.1.0/tests/test_observability.py +632 -0
  148. targetprocess_py-0.1.0/tests/test_priority.py +37 -0
  149. targetprocess_py-0.1.0/tests/test_process.py +32 -0
  150. targetprocess_py-0.1.0/tests/test_project.py +60 -0
  151. targetprocess_py-0.1.0/tests/test_relation.py +39 -0
  152. targetprocess_py-0.1.0/tests/test_relation_type.py +17 -0
  153. targetprocess_py-0.1.0/tests/test_release.py +56 -0
  154. targetprocess_py-0.1.0/tests/test_request.py +55 -0
  155. targetprocess_py-0.1.0/tests/test_request_handler.py +883 -0
  156. targetprocess_py-0.1.0/tests/test_request_handler_bulk.py +146 -0
  157. targetprocess_py-0.1.0/tests/test_resources/test_assignments.py +84 -0
  158. targetprocess_py-0.1.0/tests/test_resources/test_attachments.py +206 -0
  159. targetprocess_py-0.1.0/tests/test_resources/test_base_resource.py +533 -0
  160. targetprocess_py-0.1.0/tests/test_resources/test_bugs.py +39 -0
  161. targetprocess_py-0.1.0/tests/test_resources/test_comments.py +82 -0
  162. targetprocess_py-0.1.0/tests/test_resources/test_custom_activities.py +48 -0
  163. targetprocess_py-0.1.0/tests/test_resources/test_custom_fields.py +63 -0
  164. targetprocess_py-0.1.0/tests/test_resources/test_custom_rules.py +72 -0
  165. targetprocess_py-0.1.0/tests/test_resources/test_entities.py +596 -0
  166. targetprocess_py-0.1.0/tests/test_resources/test_entity_states.py +39 -0
  167. targetprocess_py-0.1.0/tests/test_resources/test_entity_types.py +51 -0
  168. targetprocess_py-0.1.0/tests/test_resources/test_epics.py +39 -0
  169. targetprocess_py-0.1.0/tests/test_resources/test_features.py +39 -0
  170. targetprocess_py-0.1.0/tests/test_resources/test_iterations.py +39 -0
  171. targetprocess_py-0.1.0/tests/test_resources/test_lookup_resolvers.py +109 -0
  172. targetprocess_py-0.1.0/tests/test_resources/test_priorities.py +154 -0
  173. targetprocess_py-0.1.0/tests/test_resources/test_processes.py +84 -0
  174. targetprocess_py-0.1.0/tests/test_resources/test_projects.py +39 -0
  175. targetprocess_py-0.1.0/tests/test_resources/test_relation_types.py +156 -0
  176. targetprocess_py-0.1.0/tests/test_resources/test_relations.py +88 -0
  177. targetprocess_py-0.1.0/tests/test_resources/test_releases.py +39 -0
  178. targetprocess_py-0.1.0/tests/test_resources/test_requests.py +39 -0
  179. targetprocess_py-0.1.0/tests/test_resources/test_role_efforts.py +64 -0
  180. targetprocess_py-0.1.0/tests/test_resources/test_roles.py +105 -0
  181. targetprocess_py-0.1.0/tests/test_resources/test_server_capability.py +133 -0
  182. targetprocess_py-0.1.0/tests/test_resources/test_severities.py +43 -0
  183. targetprocess_py-0.1.0/tests/test_resources/test_tasks.py +39 -0
  184. targetprocess_py-0.1.0/tests/test_resources/test_team_assignments.py +65 -0
  185. targetprocess_py-0.1.0/tests/test_resources/test_team_iterations.py +80 -0
  186. targetprocess_py-0.1.0/tests/test_resources/test_teams.py +39 -0
  187. targetprocess_py-0.1.0/tests/test_resources/test_terms.py +56 -0
  188. targetprocess_py-0.1.0/tests/test_resources/test_test_cases.py +39 -0
  189. targetprocess_py-0.1.0/tests/test_resources/test_times.py +603 -0
  190. targetprocess_py-0.1.0/tests/test_resources/test_user_stories.py +39 -0
  191. targetprocess_py-0.1.0/tests/test_resources/test_users.py +39 -0
  192. targetprocess_py-0.1.0/tests/test_resources/test_workflows.py +59 -0
  193. targetprocess_py-0.1.0/tests/test_response_parser.py +167 -0
  194. targetprocess_py-0.1.0/tests/test_role.py +39 -0
  195. targetprocess_py-0.1.0/tests/test_role_effort.py +48 -0
  196. targetprocess_py-0.1.0/tests/test_severity.py +38 -0
  197. targetprocess_py-0.1.0/tests/test_task.py +76 -0
  198. targetprocess_py-0.1.0/tests/test_team.py +40 -0
  199. targetprocess_py-0.1.0/tests/test_team_assignment.py +36 -0
  200. targetprocess_py-0.1.0/tests/test_team_iteration.py +91 -0
  201. targetprocess_py-0.1.0/tests/test_term.py +35 -0
  202. targetprocess_py-0.1.0/tests/test_test_case.py +52 -0
  203. targetprocess_py-0.1.0/tests/test_time.py +111 -0
  204. targetprocess_py-0.1.0/tests/test_transport.py +106 -0
  205. targetprocess_py-0.1.0/tests/test_types.py +47 -0
  206. targetprocess_py-0.1.0/tests/test_uploaded_attachment.py +124 -0
  207. targetprocess_py-0.1.0/tests/test_user.py +82 -0
  208. targetprocess_py-0.1.0/tests/test_user_story.py +75 -0
  209. targetprocess_py-0.1.0/tests/test_workflow.py +39 -0
  210. targetprocess_py-0.1.0/uv.lock +852 -0
@@ -0,0 +1,147 @@
1
+ # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
2
+ #
3
+ # This file supersedes the CodeRabbit dashboard settings for this repository:
4
+ # once present, dashboard values no longer apply here, so any organisation-wide
5
+ # settings we rely on must be restated in this file.
6
+
7
+ language: en-ZA
8
+
9
+ reviews:
10
+ profile: assertive
11
+ in_progress_fortune: false
12
+ # Withhold CodeRabbit's approval until every conversation on the PR is
13
+ # resolved and no error-mode pre-merge check is failing; approval is then
14
+ # granted automatically. This makes CodeRabbit re-approve once satisfied
15
+ # (a first-pass "changes requested" otherwise never clears to approved),
16
+ # and gives the error-mode pre-merge checks below their merge-blocking teeth.
17
+ request_changes_workflow: true
18
+
19
+ auto_review:
20
+ # No automatic reviews. Every pull request here is agent-authored and its
21
+ # coordinator requests each review explicitly ("@coderabbitai review", or
22
+ # "full review") once the content is final, so no included review or paid
23
+ # credit is spent on an intermediate push, and draft state gates nothing.
24
+ # With automatic reviews off CodeRabbit posts a passing "Review skipped"
25
+ # status on every push, so a required CodeRabbit status check no longer
26
+ # proves a review ran; the approving-review requirement is the gate.
27
+ # Bot-authored pull requests (Dependabot and the like) are not auto-reviewed
28
+ # regardless.
29
+ enabled: false
30
+
31
+ finishing_touches:
32
+ simplify:
33
+ enabled: true
34
+
35
+ pre_merge_checks:
36
+ # Only a requested reviewer — never the PR author — may ignore a failing
37
+ # error-mode check, so the author cannot self-bypass the error-mode gate
38
+ # defined below.
39
+ override_requested_reviewers_only: true
40
+
41
+ # The built-in docstring-coverage check cannot exclude test code, and test
42
+ # methods idiomatically carry no docstrings — so it is disabled here and
43
+ # replaced by the "Docstring coverage (non-test)" custom check below, which
44
+ # excludes tests by prose.
45
+ docstrings:
46
+ mode: "off"
47
+
48
+ custom_checks:
49
+ - name: "Docstring coverage (non-test)"
50
+ mode: "error"
51
+ instructions: |
52
+ Fail if any public function, method, or class ADDED or MODIFIED in
53
+ this pull request lacks a docstring. Judge each file by intent, not by
54
+ an exhaustive pattern list. EXCLUDE all test code: any file located in
55
+ a test directory at any depth (e.g. tests/, test/, __tests__/, spec/)
56
+ or whose name marks it as a test (test_*, *_test, *.test.*, *.spec.*
57
+ in any language or extension), and any test function or method (name
58
+ starting with "test") — test code idiomatically carries no docstrings
59
+ and must not count against coverage. Also exclude generated or
60
+ vendored code. Scope the check to languages that have a docstring
61
+ convention (Python, and JS/TS/JSX/TSX via JSDoc); ignore languages
62
+ that have none (YAML, shell, JSON).
63
+
64
+ - name: "Checklist complete"
65
+ mode: "error"
66
+ instructions: |
67
+ Parse task-list items in THIS pull request's own description only —
68
+ never in a linked issue, a comment, or any external document. GitHub
69
+ Flavored Markdown task lists use unordered ("-", "*", "+") or ordered
70
+ ("1." or "1)") list markers at any indentation level. IGNORE any
71
+ section whose heading is "Post-merge verification" (or that clearly
72
+ denotes post-merge / post-deploy checks): those are verified after
73
+ merge and must not gate this pre-merge check. Of the remaining items,
74
+ fail if any is unticked ("[ ]"). Treat "[x]" and "[X]" as ticked and
75
+ "[~]" (inapplicable) as addressed. Pass when no unticked items remain,
76
+ or the description has no gating task-list items.
77
+
78
+ - name: "No committed superpowers artefacts"
79
+ mode: "error"
80
+ instructions: |
81
+ Fail if this pull request ADDS any new file under docs/superpowers/
82
+ or docs/plans/. These directories hold transient brainstorming and
83
+ writing-plans working documents (design specs and implementation
84
+ plans) that are kept on disk for the working session only and must
85
+ never be committed — the living specification lives in SPEC.md,
86
+ updated alongside changes. A new file anywhere outside these two
87
+ directories is fine; the ban is scoped to them.
88
+
89
+ path_filters:
90
+ # Auto-generated lockfiles — reviewing their diffs is noise, not signal.
91
+ - "!**/package-lock.json"
92
+ - "!**/*.script.lock"
93
+ - "!**/poetry.lock"
94
+ - "!**/bun.lockb"
95
+ - "!**/uv.lock"
96
+
97
+ path_instructions:
98
+ - path: "src/targetprocess/**"
99
+ instructions: >
100
+ Async Python library for the TargetProcess v1 REST API. TP facts that are
101
+ correct and must not be "fixed": tokens are sent as an access_token query
102
+ parameter (TP has no header token scheme); dates arrive as /Date(ms±HHMM)/;
103
+ collection responses are {Next, Items} and pagination follows Next verbatim.
104
+ - path: "tests/**"
105
+ instructions: |
106
+ Pytest suite. New or modified test doubles must be constrained to a
107
+ real interface: Mock() and MagicMock() require spec= (or spec_set=),
108
+ and patch()/patch.object() require autospec=True or an explicit
109
+ spec. An unspecced double accepts any attribute access, hiding
110
+ exactly the interface-drift bugs a test exists to catch. For
111
+ TypedDicts and other shapes that spec poorly, use real stub dicts
112
+ instead of mocks.
113
+ - path: "tests/integration/cassettes/**"
114
+ instructions: >
115
+ Recorded VCR fixtures — flag immediately any unredacted credential,
116
+ PII (names, logins, emails), real TargetProcess hostname, or real
117
+ business content (issue titles, descriptions, comments): those must
118
+ be sanitised placeholder values. Bare numeric Ids are deliberately
119
+ preserved and must NOT be flagged — neither real entity Ids nor the
120
+ product-seeded lookup constants every TP tenant shares (Priority
121
+ 1–5, EntityType 4): with names, logins, text and hostname already
122
+ placeholders, an Id on its own identifies nothing. Structural
123
+ fields — Id, ResourceType, dates, numeric/boolean fields, the
124
+ Items/Next/Prev envelope — are kept as recorded so a cassette still
125
+ exercises real parsing, pagination and filter behaviour
126
+ (docs/testing.md). On a write-path cassette the REQUEST body is
127
+ recorded as sent and is deliberately not field-scrubbed: its
128
+ Name/Description values are synthetic strings the test invented,
129
+ carrying the recording ticket's reference as a prefix, and must NOT
130
+ be flagged. Do flag a request body carrying text that reads as
131
+ having come off the live instance rather than being invented.
132
+ - path: ".github/workflows/**"
133
+ instructions: |
134
+ GitHub Actions CI — high blast radius. Validation jobs run on pull
135
+ requests; nothing here deploys. Flag changes that loosen branch gating,
136
+ broaden event triggers, widen permissions, or expose secrets.
137
+ - path: "**/.env"
138
+ instructions: |
139
+ Gitignored credentials file — it must never be committed. Treat any
140
+ .env appearing in a diff as a critical defect.
141
+
142
+ chat:
143
+ art: false
144
+
145
+ code_generation:
146
+ docstrings:
147
+ language: en-ZA
@@ -0,0 +1,35 @@
1
+ {
2
+ "extends": ["@commitlint/config-conventional"],
3
+ "rules": {
4
+ "type-enum": [
5
+ 2,
6
+ "always",
7
+ [
8
+ "feat",
9
+ "fix",
10
+ "docs",
11
+ "style",
12
+ "refactor",
13
+ "perf",
14
+ "test",
15
+ "build",
16
+ "ci",
17
+ "chore",
18
+ "revert"
19
+ ]
20
+ ],
21
+ "type-case": [2, "always", "lower-case"],
22
+ "type-empty": [2, "never"],
23
+ "subject-empty": [2, "never"],
24
+ "subject-full-stop": [2, "never", "."],
25
+ "subject-case": [
26
+ 2,
27
+ "always",
28
+ ["lower-case", "sentence-case"]
29
+ ],
30
+ "header-max-length": [2, "always", 72],
31
+ "body-leading-blank": [2, "always"],
32
+ "body-max-line-length": [2, "always", 100],
33
+ "footer-leading-blank": [2, "always"]
34
+ }
35
+ }
@@ -0,0 +1,25 @@
1
+ # Copy this file to .env and fill in real values. .env is gitignored and
2
+ # must never be committed. See the "Secrets management" section of the
3
+ # README for the env-var -> secrets-manager pattern.
4
+ #
5
+ # cp .env.example .env
6
+
7
+ # TargetProcess instance domain (no scheme), e.g. example.tpondemand.com
8
+ TP_DOMAIN=example.tpondemand.com
9
+
10
+ # TargetProcess API token, sent as the access_token query parameter.
11
+ # Fetch it from your TP instance's account settings; never share or commit it.
12
+ TP_TOKEN=your-api-token
13
+
14
+ # Comma-separated allow-list of project ids the write examples may modify.
15
+ # Only set this for a throwaway/sandbox project; never production.
16
+ # Required by examples/create_bug.py and examples/bulk_updates.py.
17
+ TP_WRITE_ALLOWED_PROJECT_IDS=
18
+
19
+ # --- Integration-cassette recording only -------------------------------------
20
+ # tests/integration/ replays committed cassettes offline and needs nothing set.
21
+ # Re-recording against a live instance (ALLOW_PROD_RECORDING=1) uses this second
22
+ # pair instead, read from the environment or from ~/.config/targetprocess/.env.
23
+ # Leave both blank unless you are deliberately re-recording.
24
+ TP_BASE_URL=
25
+ TP_API_TOKEN=
@@ -0,0 +1,80 @@
1
+ name: Bug report
2
+ description: Report something that is not working as expected
3
+ title: "[Bug] "
4
+ labels: ["bug"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thanks for taking the time to file a bug report! Please fill in the
10
+ sections below so we can reproduce and fix it.
11
+ - type: textarea
12
+ id: summary
13
+ attributes:
14
+ label: Summary
15
+ description: A concise description of the problem.
16
+ validations:
17
+ required: true
18
+ - type: textarea
19
+ id: reproduce
20
+ attributes:
21
+ label: Steps to reproduce
22
+ description: |
23
+ The smallest self-contained example that triggers the bug. Include the
24
+ code, the command you ran, and any relevant environment details. Redact
25
+ real tokens — never paste a live `TP_TOKEN`.
26
+ placeholder: |
27
+ 1. ...
28
+ 2. ...
29
+ 3. ...
30
+ validations:
31
+ required: true
32
+ - type: textarea
33
+ id: expected
34
+ attributes:
35
+ label: Expected behaviour
36
+ validations:
37
+ required: true
38
+ - type: textarea
39
+ id: actual
40
+ attributes:
41
+ label: Actual behaviour
42
+ description: |
43
+ Include the full traceback or error message if there is one. Redact
44
+ tokens, credentials, authorisation headers, cookies, and query strings
45
+ before posting — a traceback often carries the request URL.
46
+ validations:
47
+ required: true
48
+ - type: textarea
49
+ id: environment
50
+ attributes:
51
+ label: Environment
52
+ description: Library version, Python version, OS, and anything else relevant.
53
+ placeholder: |
54
+ - targetprocess-py: 0.x.y
55
+ - Python: 3.12.x
56
+ - OS: ...
57
+ validations:
58
+ required: true
59
+ - type: dropdown
60
+ id: priority
61
+ attributes:
62
+ label: Priority
63
+ description: |
64
+ How urgent is this? P1 blocks work with no reasonable workaround, P2 has
65
+ real impact but a workaround exists, P3 is cosmetic or minor. P0 is
66
+ reserved for security incidents — report those via the security link on
67
+ the issue chooser instead.
68
+ options:
69
+ - "P1 — High"
70
+ - "P2 — Medium"
71
+ - "P3 — Low"
72
+ validations:
73
+ required: true
74
+ - type: textarea
75
+ id: context
76
+ attributes:
77
+ label: Additional context
78
+ description: Anything else? Links, related issues, screenshots.
79
+ validations:
80
+ required: false
@@ -0,0 +1,9 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ # GitHub's "report a vulnerability" advisory route needs private vulnerability
4
+ # reporting, which this private repository does not expose, so the security
5
+ # contact is e-mail. Switch to the advisories URL if the repo is ever made
6
+ # public and the feature is enabled.
7
+ - name: Security report
8
+ url: mailto:louis@man8.com?subject=targetprocess-py%20security%20report
9
+ about: Report a security vulnerability privately by e-mail, not as a public issue.
@@ -0,0 +1,66 @@
1
+ name: Feature request
2
+ description: Suggest a new capability or improvement
3
+ title: "[Feature] "
4
+ labels: ["enhancement"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thanks for the suggestion! Tell us what you want and why.
10
+ - type: textarea
11
+ id: problem
12
+ attributes:
13
+ label: Problem
14
+ description: What is currently hard or impossible to do?
15
+ validations:
16
+ required: true
17
+ - type: textarea
18
+ id: solution
19
+ attributes:
20
+ label: Proposed solution
21
+ description: What would you like the library to do instead?
22
+ validations:
23
+ required: true
24
+ - type: textarea
25
+ id: alternatives
26
+ attributes:
27
+ label: Alternatives considered
28
+ description: Any workarounds or other approaches you thought about.
29
+ validations:
30
+ required: false
31
+ - type: dropdown
32
+ id: area
33
+ attributes:
34
+ label: Area
35
+ description: Which part of the library does this touch?
36
+ options:
37
+ - "area: client"
38
+ - "area: models"
39
+ - "area: transport"
40
+ - "area: observability"
41
+ - "area: docs"
42
+ - "area: ci"
43
+ - "area: testing"
44
+ validations:
45
+ required: true
46
+ - type: dropdown
47
+ id: priority
48
+ attributes:
49
+ label: Priority
50
+ description: |
51
+ How important is this to you? P1 blocks work with no reasonable
52
+ workaround, P2 has real impact but a workaround exists, P3 is cosmetic
53
+ or minor.
54
+ options:
55
+ - "P1 — High"
56
+ - "P2 — Medium"
57
+ - "P3 — Low"
58
+ validations:
59
+ required: true
60
+ - type: textarea
61
+ id: context
62
+ attributes:
63
+ label: Additional context
64
+ description: Anything else? Links, mockups, related issues.
65
+ validations:
66
+ required: false
@@ -0,0 +1,107 @@
1
+ # Automated dependency updates. Two ecosystems are in play here:
2
+ #
3
+ # uv — the locked Python environment (pyproject.toml + uv.lock).
4
+ # versioning-strategy: lockfile-only keeps Dependabot out of
5
+ # pyproject.toml entirely, so the declared floors stay
6
+ # deliberate while the resolved versions CI installs stay
7
+ # current. See the strategy note on that key below.
8
+ # github-actions — the SHA-pinned actions in .github/workflows/. Pinning to a
9
+ # commit is the supply-chain-safe form but it never floats, so
10
+ # without Dependabot those pins silently rot.
11
+ # pre-commit — the hook repos pinned by `rev:` in .pre-commit-config.yaml.
12
+ # Same rot problem as the action pins. The ruff/mypy hooks are
13
+ # not listed there: they run via `uv run`, so the uv ecosystem
14
+ # above already keeps them current.
15
+ #
16
+ # Every update lands as a pull request, so the existing gates (ruff, ruff-format,
17
+ # mypy --strict, pytest with --cov-fail-under=90, the pre-commit hook suite,
18
+ # duplication detection, CodeQL, CodeRabbit review) decide whether a bump is safe
19
+ # before it reaches main.
20
+ version: 2
21
+
22
+ updates:
23
+ - package-ecosystem: "uv"
24
+ directory: "/"
25
+ # Explicit rather than the default "auto", which guesses app-vs-library and
26
+ # would rewrite pyproject.toml: "increase" raises the floor to the newest
27
+ # release, and "widen" adds an upper bound. Neither is right for a published
28
+ # library — an upper cap propagates into every downstream resolution, and a
29
+ # raised floor drops support for versions that still work. lockfile-only
30
+ # confines Dependabot to uv.lock. Because the constraints here are open-ended
31
+ # (httpx>=0.27.0, pydantic>=2.0.0, easylimit>=0.3.4), the manifest already
32
+ # permits new releases, so this forgoes no upgrades: majors still land, they
33
+ # just arrive as a lock change plus a green/red CI signal, and widening the
34
+ # declared floor stays a deliberate human decision.
35
+ versioning-strategy: "lockfile-only"
36
+ schedule:
37
+ interval: "weekly"
38
+ day: "monday"
39
+ time: "07:00"
40
+ timezone: "Africa/Johannesburg"
41
+ open-pull-requests-limit: 5
42
+ labels:
43
+ - "dependencies"
44
+ commit-message:
45
+ prefix: "deps"
46
+ prefix-development: "deps-dev"
47
+ include: "scope"
48
+ groups:
49
+ # Test/lint/type tooling moves together: a mypy or ruff bump is judged by
50
+ # whether CI still passes, so batching them keeps review cost proportional.
51
+ dev-tooling:
52
+ patterns:
53
+ - "pytest*"
54
+ - "mypy*"
55
+ - "ruff"
56
+ - "coverage*"
57
+ - "vcrpy"
58
+ - "pre-commit"
59
+ # Runtime dependencies are batched only for minor/patch. Majors are
60
+ # deliberately left ungrouped so each arrives as its own PR — httpx,
61
+ # pydantic and easylimit are the library's public surface (pydantic v2
62
+ # models and httpx types leak into user code), so a major needs to be
63
+ # reviewed and released on its own.
64
+ runtime-minor-patch:
65
+ patterns:
66
+ - "httpx"
67
+ - "pydantic*"
68
+ - "easylimit"
69
+ update-types:
70
+ - "minor"
71
+ - "patch"
72
+
73
+ - package-ecosystem: "pre-commit"
74
+ directory: "/"
75
+ schedule:
76
+ interval: "weekly"
77
+ day: "monday"
78
+ time: "07:00"
79
+ timezone: "Africa/Johannesburg"
80
+ open-pull-requests-limit: 3
81
+ labels:
82
+ - "dependencies"
83
+ commit-message:
84
+ prefix: "ci"
85
+ include: "scope"
86
+ groups:
87
+ pre-commit:
88
+ patterns:
89
+ - "*"
90
+
91
+ - package-ecosystem: "github-actions"
92
+ directory: "/"
93
+ schedule:
94
+ interval: "weekly"
95
+ day: "monday"
96
+ time: "07:00"
97
+ timezone: "Africa/Johannesburg"
98
+ open-pull-requests-limit: 3
99
+ labels:
100
+ - "dependencies"
101
+ commit-message:
102
+ prefix: "ci"
103
+ include: "scope"
104
+ groups:
105
+ github-actions:
106
+ patterns:
107
+ - "*"
@@ -0,0 +1,56 @@
1
+ # Issue and pull-request label set for targetprocess-py.
2
+ #
3
+ # GitHub's 9 default labels plus the two Dependabot labels
4
+ # (`dependencies`, `python:uv`) are already present; this file defines the
5
+ # project-specific priority and area labels that sit on top of them.
6
+ #
7
+ # To (re)apply this set to the repository, run:
8
+ #
9
+ # scripts/apply_labels.sh
10
+ #
11
+ # which calls `gh label create` (or `--force` to update colours/descriptions).
12
+ # Existing labels are left untouched unless they appear below.
13
+ #
14
+ # The priority and area dropdowns in the issue forms record the reporter's
15
+ # choice in the issue body only — GitHub applies just the form's own top-level
16
+ # `labels:` key, so the P#/area labels below still have to be applied by hand
17
+ # (or by a future labeler workflow) during triage.
18
+
19
+ # --- Priority ---------------------------------------------------------------
20
+ # P0 is reserved for security incidents and outages and is not exposed in the
21
+ # issue-template dropdowns; file those via the Security report contact link.
22
+ - name: "P0 — Critical"
23
+ color: "b60205"
24
+ description: "Security incident or outage; drop everything."
25
+ - name: "P1 — High"
26
+ color: "d93f0b"
27
+ description: "Blocks work, no reasonable workaround."
28
+ - name: "P2 — Medium"
29
+ color: "fbca04"
30
+ description: "Real impact, a workaround exists."
31
+ - name: "P3 — Low"
32
+ color: "0e8a16"
33
+ description: "Cosmetic or minor; nice to have."
34
+
35
+ # --- Area -------------------------------------------------------------------
36
+ - name: "area: client"
37
+ color: "1d76db"
38
+ description: "Client layer and resource managers."
39
+ - name: "area: models"
40
+ color: "5319e7"
41
+ description: "Pydantic entity and reference models."
42
+ - name: "area: transport"
43
+ color: "006b75"
44
+ description: "HTTP transport, auth, retry, rate limiting."
45
+ - name: "area: observability"
46
+ color: "0052cc"
47
+ description: "Logging, scrubbing, request-id propagation."
48
+ - name: "area: docs"
49
+ color: "0075ca"
50
+ description: "README, usage guide, examples, SPEC."
51
+ - name: "area: ci"
52
+ color: "6f42c1"
53
+ description: "GitHub Actions, pre-commit, Dependabot, CodeRabbit."
54
+ - name: "area: testing"
55
+ color: "a2eeef"
56
+ description: "pytest suite, VCR cassettes, coverage."
@@ -0,0 +1,62 @@
1
+ <!--
2
+ Thanks for the pull request! Title it as a Conventional Commits subject
3
+ (`type(scope): description`): squash merge makes it the commit on main, and CI
4
+ checks it as one. Fill in the sections below, then complete the
5
+ checklist. CodeRabbit's "Checklist complete" pre-merge check fails if any
6
+ unticked ("- [ ]") task-list item remains in this description, so tick each
7
+ box as you go (or mark inapplicable items with "[~]").
8
+ -->
9
+
10
+ ## Summary
11
+
12
+ <!-- What does this change do, and why? Reference the issue or work item
13
+ this closes. -->
14
+
15
+ Closes #
16
+
17
+ ## Changes
18
+
19
+ <!-- Bullet list of the meaningful changes. Group by area if the PR spans
20
+ more than one (e.g. transport, models, docs). -->
21
+
22
+ -
23
+
24
+ ## Testing
25
+
26
+ <!-- How did you verify this? Which commands did you run? Paste a short,
27
+ redacted transcript if useful. Never paste a live TP_TOKEN. -->
28
+
29
+ -
30
+
31
+ ## Context
32
+
33
+ <!-- Anything a reviewer should know: alternatives considered, follow-ups,
34
+ risk, migration notes, or "none". -->
35
+
36
+ -
37
+
38
+ ## Checklist
39
+
40
+ - [ ] `uv run ruff check .` and `uv run ruff format --check .` pass
41
+ - [ ] `uv run mypy --strict src` passes
42
+ - [ ] `uv run pytest -q` passes and coverage stays at or above 90%
43
+ - [ ] `uv run pre-commit run --all-files --hook-stage pre-commit` passes
44
+ - [ ] `uv run pre-commit run --all-files --hook-stage pre-push` passes
45
+ - [ ] New public functions, methods, and classes have docstrings
46
+ - [ ] No real credentials, tokens, or PII are added to the diff
47
+ - [ ] `TODO`/`FIXME`/`HACK`/`XXX` markers name an issue (e.g. `TODO(#123)`)
48
+
49
+ <!--
50
+ Post-merge verification does not belong in this description. It lives on the
51
+ linked work item under its own "## Post-merge verification" heading, where it
52
+ gates that item's Verify -> Done transition. Keeping it there leaves this
53
+ checklist purely pre-merge, so "all boxes ticked" and "ready to merge" mean the
54
+ same thing.
55
+ -->
56
+
57
+ <!--
58
+ Implicit merge gates — CI passing, the CodeRabbit review, human approval — are
59
+ deliberately absent from the checklist above. Branch protection already
60
+ enforces them, and rendering them as boxes invites a tick before the gate has
61
+ actually cleared.
62
+ -->