Fix issues #002-#006 found by the LLM test harness
- #006 (high, data loss): make_room_for() no longer deletes unkept artifacts on a doomed request - checks whether eviction can possibly succeed before deleting anything. Also fixed a related latent bug found while testing: the function returned evicted Artifact objects after calling .delete() on them, so their .id was always None (Django clears pk on delete); now returns ids captured beforehand. - #003: added server-side field-length validation (source/title/ source_name/source_id/theme) on POST and PATCH, matching the model's own max_length limits, which were previously unenforced on the ingest path entirely. - #004: ported daybook_post.py's content-shape validation (html_fragment/html_full/deck/markdown) to the server, closing the gap for any client that doesn't go through the helper script. - #005: PATCH now rejects wrong-typed `tags` (previously silently wiped existing tags) and rejects immutable fields (content/source/kind/day) with 400 instead of silently no-op'ing them. - #002: deleted the misleading skills/daybook-posting/.env.example (a zero-dependency script that never reads .env files) and clarified SKILL.md/docs/llm_posting_helper.md that these must be real process/shell env vars. Adds tests/unit/ for storage-layer tests. 46 tests passing (was 25). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
c1ea5c7990
commit
07328a3412
13 changed files with 635 additions and 35 deletions
63
docs/api.md
63
docs/api.md
|
|
@ -83,22 +83,28 @@ Required fields:
|
|||
|
||||
| Field | Notes |
|
||||
|---|---|
|
||||
| `source` | Required. |
|
||||
| `source` | Required. Max 80 characters. |
|
||||
| `kind` | One of `html_fragment`, `html_full`, `markdown`, `deck`. |
|
||||
| `title` | Required. |
|
||||
| `content` | Required text content. |
|
||||
| `title` | Required. Max 200 characters. |
|
||||
| `content` | Required text content. Must match the shape `kind` implies — see below. |
|
||||
|
||||
`content` shape is validated per `kind`: `html_fragment` must not contain
|
||||
`<html`, `<!doctype`, or `<body` (body-only HTML, wrapped in a theme
|
||||
server-side); `html_full` must contain `<html`; `deck` must contain
|
||||
`<section`; `markdown` must not be blank or whitespace-only. A mismatch
|
||||
returns `400`.
|
||||
|
||||
Optional fields:
|
||||
|
||||
| Field | Notes |
|
||||
|---|---|
|
||||
| `theme` | Defaults by kind. Common values: `report`, `tasks`, `deck`, `base`. |
|
||||
| `theme` | Defaults by kind. Common values: `report`, `tasks`, `deck`, `base`. Max 40 characters. |
|
||||
| `tags` | Array or comma-separated string. |
|
||||
| `tag_colors` | Object mapping tag name → `#RRGGBB`. Sets a colour override for those tags. |
|
||||
| `source_prompt` | Prompt or instruction that led to the artifact. |
|
||||
| `source_type` | Defaults to `agent`. |
|
||||
| `source_name` | Defaults to `source`. |
|
||||
| `source_id` | Optional stable source ID. |
|
||||
| `source_name` | Defaults to `source`. Max 120 characters. |
|
||||
| `source_id` | Optional stable source ID. Max 120 characters. |
|
||||
| `metadata` | Optional object. |
|
||||
|
||||
### Tag colours
|
||||
|
|
@ -332,28 +338,11 @@ Editable fields:
|
|||
| `metadata` | Object. Replaces existing metadata. |
|
||||
|
||||
You can only PATCH artifacts your own token owns; others return `404`.
|
||||
`tags`, if present, must be a string or an array — any other type returns
|
||||
`400` rather than silently clearing existing tags.
|
||||
|
||||
## Delete Artifact
|
||||
|
||||
Endpoint:
|
||||
|
||||
```http
|
||||
DELETE /api/artifacts/{id}
|
||||
Authorization: Bearer <your-personal-token>
|
||||
```
|
||||
|
||||
Removes the artifact's database row and its files (primary file, markdown
|
||||
sidecar, and any attached assets). Returns `204` with no body on success.
|
||||
|
||||
You can only delete artifacts your own token owns; others return `404`, as
|
||||
does a second delete of the same id.
|
||||
|
||||
```bash
|
||||
curl -X DELETE "http://127.0.0.1:8001/api/artifacts/a1b2c3d4" \
|
||||
-H "Authorization: Bearer <your-personal-token>"
|
||||
```
|
||||
|
||||
Not editable yet:
|
||||
Not editable — sending any of these returns `400` naming the field, rather
|
||||
than silently ignoring it:
|
||||
|
||||
| Field | Reason |
|
||||
|---|---|
|
||||
|
|
@ -383,6 +372,26 @@ Invoke-RestMethod `
|
|||
-Body $body
|
||||
```
|
||||
|
||||
## Delete Artifact
|
||||
|
||||
Endpoint:
|
||||
|
||||
```http
|
||||
DELETE /api/artifacts/{id}
|
||||
Authorization: Bearer <your-personal-token>
|
||||
```
|
||||
|
||||
Removes the artifact's database row and its files (primary file, markdown
|
||||
sidecar, and any attached assets). Returns `204` with no body on success.
|
||||
|
||||
You can only delete artifacts your own token owns; others return `404`, as
|
||||
does a second delete of the same id.
|
||||
|
||||
```bash
|
||||
curl -X DELETE "http://127.0.0.1:8001/api/artifacts/a1b2c3d4" \
|
||||
-H "Authorization: Bearer <your-personal-token>"
|
||||
```
|
||||
|
||||
## Rendered And Raw Content
|
||||
|
||||
Rendered browser view:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue