ver 1.0.0 initial commit

This commit is contained in:
Jason Stedwell
2026-06-27 17:25:55 -05:00
parent 550111295a
commit 2a7efe9c5d
20 changed files with 1850 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
# OpenProject API v3 endpoint map
Base: `<server>/api/v3`. Auth: HTTP Basic, username `apikey`, password = API token
(the CLI handles this). Responses are HAL+JSON: `_type`, `_links`, `_embedded`.
Collections carry `total`, `count`, `pageSize`, and `_embedded.elements`.
Endpoints the `op.py` CLI wraps directly are marked ✅. Everything else is reachable
via `op.py raw <METHOD> <path> [--data '{...}']`.
## Work packages
-`GET /work_packages` — list/filter (also `/projects/{id}/work_packages`)
-`GET /work_packages/{id}` — single
-`POST /work_packages` — create
-`PATCH /work_packages/{id}` — update (needs `lockVersion`; CLI auto-fetches)
-`DELETE /work_packages/{id}` — delete
-`POST /work_packages/{id}/activities` — add comment
- `GET /work_packages/{id}/activities` — comment/change history
- `GET /work_packages/{id}/relations` · `POST /relations` — links between WPs
- `GET /work_packages/{id}/watchers` · `POST .../watchers`
- `GET /work_packages/form` · `POST /work_packages/{id}/form` — field schema/validation
- `GET /work_packages/schemas` — allowed values per project+type
## Projects
-`GET /projects` — list/filter (`name_and_identifier` filter)
-`GET /projects/{id}` — single (id or identifier)
- `POST /projects` · `PATCH /projects/{id}` · `DELETE /projects/{id}`
-`GET /projects/{id}/types` — types enabled in a project
- `GET /projects/{id}/versions` — versions/milestones
- `GET /projects/{id}/categories`
- `GET /projects/{id}/memberships`
## People & metadata
-`GET /users/me` — current user (`ping`/`me`)
-`GET /users` — list/filter
- `GET /groups` · `GET /roles`
-`GET /types` · `GET /statuses` · `GET /priorities`
- `GET /time_entries/activities` — activity types for time logging
## Time tracking
-`POST /time_entries` — log time (`hours` is ISO-8601 duration, e.g. `PT1H30M`;
CLI accepts a plain number of hours and converts)
- `GET /time_entries` — list/filter
- `PATCH /time_entries/{id}` · `DELETE /time_entries/{id}`
## Other useful resources
- `GET /queries` · `GET /queries/{id}` — saved views (filters+columns+sort)
- `GET /versions/{id}` — milestone detail
- `GET /attachments/{id}` · `POST /work_packages/{id}/attachments` — files
- `GET /notifications` — in-app notifications
- `GET /memberships` — project membership management
## Notes
- **lockVersion / optimistic locking:** any `PATCH` to a work package must include the
`lockVersion` you got from the last `GET`. If it's stale, the API returns `409`/`422`
— re-fetch and retry. The CLI does this automatically for `wp update`/`wp close`.
- **Durations:** time values use ISO-8601 (`PT1H`, `PT30M`, `P1DT2H`). The CLI's
`time log --hours 1.5` emits `PT1.5H`.
- **Markdown fields:** `description` and `comment` take `{"format":"markdown","raw":"..."}`.
- **Form endpoints** (`POST .../form`) validate a payload and return allowed values
without persisting — handy when unsure which statuses/types are valid for a project.
+66
View File
@@ -0,0 +1,66 @@
# OpenProject filter & query syntax (API v3)
Filters are passed as a **JSON array** in the `filters` query parameter. Each element
is a single-key object: `{ "<attribute>": { "operator": "<op>", "values": [...] } }`.
The `op.py` CLI builds the common ones for you; this is for `raw` calls and edge cases.
## Operators
| Operator | Meaning | Values |
|----------|---------|--------|
| `=` | equals (one of) | array of ids/strings |
| `!` | not equal | array |
| `~` | contains (substring) | `["text"]` |
| `!~` | doesn't contain | `["text"]` |
| `o` | open (status) | `null` |
| `c` | closed (status) | `null` |
| `**` | full-text search | `["text"]` |
| `>=` / `<=` | date/number bounds | `["2026-01-01"]` / `["5"]` |
| `<t+` / `>t-` / `t` | relative dates (days from today) | `["7"]` |
| `*` | any (present) | `null` |
| `!*` | none (absent) | `null` |
## Common work-package filters
```jsonc
// Assigned to me, still open
[{"assignee":{"operator":"=","values":["me"]}},
{"status":{"operator":"o","values":null}}]
// In project 3, type Bug (id 7)
[{"project":{"operator":"=","values":["3"]}},
{"type":{"operator":"=","values":["7"]}}]
// Full-text search
[{"search":{"operator":"**","values":["certificate"]}}]
// Due within 7 days
[{"dueDate":{"operator":"<t+","values":["7"]}}]
// Updated since a date
[{"updatedAt":{"operator":">=","values":["2026-06-01T00:00:00Z"]}}]
// Created by a specific user (id 11)
[{"author":{"operator":"=","values":["11"]}}]
```
## Sorting & paging
- `sortBy` — JSON array of `[field, "asc"|"desc"]` pairs, e.g. `[["id","desc"]]`,
`[["status","asc"],["priority","desc"]]`.
- `offset` — 1-based page number (default 1).
- `pageSize` — items per page (the CLI's `get_all` follows pages automatically up to
its `max_items` cap).
- `groupBy`, `showSums=true` — for grouped/aggregated collection views.
## Passing filters via the CLI escape hatch
URL-encode the JSON in a `raw GET`:
```bash
OP="${CLAUDE_PLUGIN_ROOT}/skills/openproject/scripts/op.py"
python3 "$OP" raw GET '/api/v3/work_packages?filters=[{"status":{"operator":"o","values":null}}]&pageSize=5'
```
(The typed `wp list` command is easier for the common cases — use `raw` only for
attributes the CLI doesn't expose as flags.)