matelab-python-sdk 0.1.0a19__tar.gz → 0.1.0a21__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.
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/CHANGELOG.md +25 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/PKG-INFO +27 -19
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/README.md +26 -18
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/contracts/matelab-integration-v1.lock.json +3 -3
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/contracts/matelab-integration-v1.openapi.yaml +97 -85
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/docs/operation-coverage.yaml +5 -5
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/pyproject.toml +1 -1
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/_generated/models.py +156 -49
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/records.py +1 -7
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_generation.py +164 -5
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_operation_coverage.py +1 -1
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_record_mutations.py +16 -8
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_records.py +104 -13
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/uv.lock +1 -1
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/.env.example +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/.github/workflows/release.yml +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/.gitignore +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/AGENTS.md +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/CONTEXT.md +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/LICENSE +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/NOTICE +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/scripts/check_release.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/scripts/generate_models.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/_wire_validation.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/groups.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/literature.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/templates.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/src/matelab/streaming.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_async_attachment_upload.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_client.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_comments_and_downloads.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_extended_records.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_groups.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_notebook_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_record_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_release.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_template_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_transport.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_uploads_and_literature.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/typing/consumer.py +0 -0
- {matelab_python_sdk-0.1.0a19 → matelab_python_sdk-0.1.0a21}/tests/typing/pyproject.toml +0 -0
|
@@ -3,6 +3,31 @@
|
|
|
3
3
|
This file records release-to-release changes and migration impact. It is not the authority for the current interface;
|
|
4
4
|
see [README.md](README.md) for current behavior and [AGENTS.md](AGENTS.md) for maintenance policy.
|
|
5
5
|
|
|
6
|
+
## 0.1.0a21 - 2026-08-28
|
|
7
|
+
|
|
8
|
+
- Adopts immutable `matelab-spec v0.4.4` at commit `be070c5f931b2063327a3beaccc53a360204b64e` and OpenAPI
|
|
9
|
+
SHA-256 `2de38e46d3814b8b049af8afd18e85fb20be6ca29cc409390d25df663abc43f9`, aligned with Provider evidence
|
|
10
|
+
`7bd9704286057653632424fa82f413d99cd69ab6`.
|
|
11
|
+
- Accepts the required nullable `readRecord.datetime_locked` wire field for current unlocked records and follows the
|
|
12
|
+
unexposed `/actions/app` rename to `readApplicationBootstrap`; SDK Session identity remains sourced from token issuance.
|
|
13
|
+
- Keeps `RecordFilesAttachmentAppend` root-only. The release describes a safe optional folder path in its dedicated
|
|
14
|
+
staged-name append schema, but `UpdateRecordRequest.add[]` still references `AddValueOperation`, which forbids that
|
|
15
|
+
`path`;
|
|
16
|
+
exposing it would require bypassing whole-request Contract validation. PVD-044 also records that malformed path
|
|
17
|
+
containers can silently append at root.
|
|
18
|
+
|
|
19
|
+
## 0.1.0a20 - 2026-08-24
|
|
20
|
+
|
|
21
|
+
- Adopts immutable `matelab-spec v0.4.3` at commit `7965ac9803505ae35dc5ce36f52afc3c2c133c45` and OpenAPI
|
|
22
|
+
SHA-256 `6576812dd13f92ad58131f4edb8dc919d1b1fe0f19a695c2d25fbe6d13a8445b`, aligned with Provider evidence
|
|
23
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27`.
|
|
24
|
+
- Breaking: tightens record readback to one canonical attachment object or `null` per table file cell, removing the
|
|
25
|
+
obsolete attachment-array compatibility path. Template decoding now accepts nullable JSON-code data and preserves
|
|
26
|
+
empty-string number/boolean cells alongside their scalar and null forms.
|
|
27
|
+
- Records PVD-046 while keeping `templates.save_content()` deliberately narrower than the Provider: the request remains
|
|
28
|
+
a canonical module list, and every table file cell remains one canonical attachment object or `null`, never an
|
|
29
|
+
arbitrary or multi-attachment array.
|
|
30
|
+
|
|
6
31
|
## 0.1.0a19 - 2026-08-23
|
|
7
32
|
|
|
8
33
|
- Re-adopts the force-rewritten `matelab-spec v0.4.2` at commit
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: matelab-python-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a21
|
|
4
4
|
Summary: Reusable async Python client for the Matelab Integration Contract
|
|
5
5
|
Author-email: 朱天念 <zhutiannian@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -35,10 +35,10 @@ This README describes the current SDK interface, integration semantics, examples
|
|
|
35
35
|
[AGENTS.md](AGENTS.md) for durable maintenance rules, and `docs/operation-coverage.yaml` for the machine-readable
|
|
36
36
|
operation inventory.
|
|
37
37
|
|
|
38
|
-
The current alpha is `0.1.
|
|
38
|
+
The current alpha is `0.1.0a21`. `[project].version` in `pyproject.toml` is the sole SDK version source;
|
|
39
39
|
`uv.lock` only mirrors that source.
|
|
40
40
|
|
|
41
|
-
The SDK is pinned to the
|
|
41
|
+
The SDK is pinned to the immutable `matelab-spec v0.4.4` Contract Release. The sole release pin is
|
|
42
42
|
`contracts/matelab-integration-v1.lock.json`, which records
|
|
43
43
|
the source tag, commit, OpenAPI path, local snapshot path, and SHA-256.
|
|
44
44
|
|
|
@@ -64,14 +64,14 @@ To test the same artifact a downstream Consumer will install, build and install
|
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
66
|
uv build --no-build-isolation --out-dir dist/release
|
|
67
|
-
python -m pip install dist/release/matelab_python_sdk-0.1.
|
|
67
|
+
python -m pip install dist/release/matelab_python_sdk-0.1.0a21-py3-none-any.whl
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
|
|
71
71
|
tag, commit, and checksum recorded below.
|
|
72
72
|
|
|
73
73
|
The Contract and public SDK interface track the current reviewed Provider at
|
|
74
|
-
`
|
|
74
|
+
`7bd9704286057653632424fa82f413d99cd69ab6`. Provider limitations that remain relevant to integrations are documented
|
|
75
75
|
alongside the affected interfaces below.
|
|
76
76
|
|
|
77
77
|
## Design
|
|
@@ -121,7 +121,7 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
121
121
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
122
122
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
123
123
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
124
|
-
The pinned v0.4.
|
|
124
|
+
The pinned v0.4.4 Contract also declares optional code-4 `errs`, but PVD-041 and PCG-015 record opaque array/object
|
|
125
125
|
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
126
126
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
127
127
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
@@ -316,8 +316,10 @@ supports one file column. A locally rejected target does not spend the handle; o
|
|
|
316
316
|
result cannot be retried through the same client.
|
|
317
317
|
|
|
318
318
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
319
|
-
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root
|
|
320
|
-
|
|
319
|
+
other non-conflicting record changes. `RecordFilesAttachmentAppend` currently targets the module root. Although
|
|
320
|
+
v0.4.4 records Provider evidence for safe folder paths, its top-level `UpdateRecordRequest.add[]` schema still excludes
|
|
321
|
+
the `path` property declared by the dedicated staged-name append shape; the SDK therefore does not expose folder paths
|
|
322
|
+
until that wire-schema conflict is resolved (PVD-044):
|
|
321
323
|
|
|
322
324
|
```python
|
|
323
325
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -348,7 +350,9 @@ await client.records.update(
|
|
|
348
350
|
|
|
349
351
|
For a files occurrence, `caption=None` preserves the observed string caption (an observed null caption normalizes to
|
|
350
352
|
the required empty string). Table replacement requires exactly one current attachment in the selected cell and does
|
|
351
|
-
not accept a caption.
|
|
353
|
+
not accept a caption. Record reads likewise accept only one canonical attachment object or `null` in a table file cell;
|
|
354
|
+
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
355
|
+
differ from the current occurrence.
|
|
352
356
|
|
|
353
357
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
354
358
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
@@ -425,8 +429,8 @@ and `deletePersonalLiteratureItem`.
|
|
|
425
429
|
|
|
426
430
|
Every other implemented operation is explicitly `experimental`; the exact per-operation list and its
|
|
427
431
|
PVD/PCG references live in
|
|
428
|
-
`docs/operation-coverage.yaml`. `
|
|
429
|
-
|
|
432
|
+
`docs/operation-coverage.yaml`. `readApplicationBootstrap` is intentionally unexposed because it returns the Provider
|
|
433
|
+
application environment and menu model, while SDK identity is sourced from token issuance. `readLiteratureCreateTemplate`
|
|
430
434
|
is intentionally unexposed because it returns a frontend form definition and an optional deployment flag rather than
|
|
431
435
|
a resource needed by the SDK interface. There are no `planned` operations. Experimental support means the SDK
|
|
432
436
|
validates and exposes the pinned Contract while preserving limitations such as unstable ordering/pagination,
|
|
@@ -500,9 +504,12 @@ await client.templates.save_content(template, modules)
|
|
|
500
504
|
`TemplateModule.data_present` distinguishes a missing `data` property from an explicit null value, while
|
|
501
505
|
`attributes` prevents additive canonical properties from being dropped during a read/save cycle. The SDK does not
|
|
502
506
|
synthesize frontend editor UIDs, layout widths, rows, folders, option encoding, or a fixed set of display module
|
|
503
|
-
types.
|
|
504
|
-
|
|
505
|
-
|
|
507
|
+
types. A JSON-language code module with style metadata may return its JSON string or explicit `null`; number and boolean
|
|
508
|
+
table cells preserve the Provider's empty string as distinct from scalar and `null` values. The Provider accepts some
|
|
509
|
+
non-canonical module roots and arbitrary table file arrays, but the SDK does not expose that behavior: saved content
|
|
510
|
+
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-046).
|
|
511
|
+
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-007),
|
|
512
|
+
so a read-modify-save sequence can overwrite a concurrent change.
|
|
506
513
|
|
|
507
514
|
The market result retains the Provider's `total_count` and derives `has_more` without echoing the caller's page
|
|
508
515
|
arguments; it does not claim a stable order or continuation token. Template reads remain experimental
|
|
@@ -613,8 +620,9 @@ returns the acknowledgement classification
|
|
|
613
620
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
614
621
|
retries stay disabled. Encrypted record content is outside the SDK's public read/update interface: the list-level
|
|
615
622
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
616
|
-
password lifecycle remain unexposed. Files-module attachment append
|
|
617
|
-
|
|
623
|
+
password lifecycle remain unexposed. Files-module attachment append remains root-only because the pinned top-level
|
|
624
|
+
update request schema does not admit the dedicated staged-name append shape's folder `path`; malformed path containers
|
|
625
|
+
may also silently append at root according to PVD-044. A staged attachment is indeterminate once the write has started.
|
|
618
626
|
|
|
619
627
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-019
|
|
620
628
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -912,6 +920,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
912
920
|
```
|
|
913
921
|
|
|
914
922
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
915
|
-
byte-identical wheel and source distribution hashes. The release is bound to
|
|
916
|
-
|
|
917
|
-
`
|
|
923
|
+
byte-identical wheel and source distribution hashes. The release is bound to immutable `matelab-spec v0.4.4`, commit
|
|
924
|
+
`be070c5f931b2063327a3beaccc53a360204b64e`, and OpenAPI SHA-256
|
|
925
|
+
`2de38e46d3814b8b049af8afd18e85fb20be6ca29cc409390d25df663abc43f9`.
|
|
@@ -7,10 +7,10 @@ This README describes the current SDK interface, integration semantics, examples
|
|
|
7
7
|
[AGENTS.md](AGENTS.md) for durable maintenance rules, and `docs/operation-coverage.yaml` for the machine-readable
|
|
8
8
|
operation inventory.
|
|
9
9
|
|
|
10
|
-
The current alpha is `0.1.
|
|
10
|
+
The current alpha is `0.1.0a21`. `[project].version` in `pyproject.toml` is the sole SDK version source;
|
|
11
11
|
`uv.lock` only mirrors that source.
|
|
12
12
|
|
|
13
|
-
The SDK is pinned to the
|
|
13
|
+
The SDK is pinned to the immutable `matelab-spec v0.4.4` Contract Release. The sole release pin is
|
|
14
14
|
`contracts/matelab-integration-v1.lock.json`, which records
|
|
15
15
|
the source tag, commit, OpenAPI path, local snapshot path, and SHA-256.
|
|
16
16
|
|
|
@@ -36,14 +36,14 @@ To test the same artifact a downstream Consumer will install, build and install
|
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
uv build --no-build-isolation --out-dir dist/release
|
|
39
|
-
python -m pip install dist/release/matelab_python_sdk-0.1.
|
|
39
|
+
python -m pip install dist/release/matelab_python_sdk-0.1.0a21-py3-none-any.whl
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
|
|
43
43
|
tag, commit, and checksum recorded below.
|
|
44
44
|
|
|
45
45
|
The Contract and public SDK interface track the current reviewed Provider at
|
|
46
|
-
`
|
|
46
|
+
`7bd9704286057653632424fa82f413d99cd69ab6`. Provider limitations that remain relevant to integrations are documented
|
|
47
47
|
alongside the affected interfaces below.
|
|
48
48
|
|
|
49
49
|
## Design
|
|
@@ -93,7 +93,7 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
93
93
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
94
94
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
95
95
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
96
|
-
The pinned v0.4.
|
|
96
|
+
The pinned v0.4.4 Contract also declares optional code-4 `errs`, but PVD-041 and PCG-015 record opaque array/object
|
|
97
97
|
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
98
98
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
99
99
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
@@ -288,8 +288,10 @@ supports one file column. A locally rejected target does not spend the handle; o
|
|
|
288
288
|
result cannot be retried through the same client.
|
|
289
289
|
|
|
290
290
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
291
|
-
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root
|
|
292
|
-
|
|
291
|
+
other non-conflicting record changes. `RecordFilesAttachmentAppend` currently targets the module root. Although
|
|
292
|
+
v0.4.4 records Provider evidence for safe folder paths, its top-level `UpdateRecordRequest.add[]` schema still excludes
|
|
293
|
+
the `path` property declared by the dedicated staged-name append shape; the SDK therefore does not expose folder paths
|
|
294
|
+
until that wire-schema conflict is resolved (PVD-044):
|
|
293
295
|
|
|
294
296
|
```python
|
|
295
297
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -320,7 +322,9 @@ await client.records.update(
|
|
|
320
322
|
|
|
321
323
|
For a files occurrence, `caption=None` preserves the observed string caption (an observed null caption normalizes to
|
|
322
324
|
the required empty string). Table replacement requires exactly one current attachment in the selected cell and does
|
|
323
|
-
not accept a caption.
|
|
325
|
+
not accept a caption. Record reads likewise accept only one canonical attachment object or `null` in a table file cell;
|
|
326
|
+
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
327
|
+
differ from the current occurrence.
|
|
324
328
|
|
|
325
329
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
326
330
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
@@ -397,8 +401,8 @@ and `deletePersonalLiteratureItem`.
|
|
|
397
401
|
|
|
398
402
|
Every other implemented operation is explicitly `experimental`; the exact per-operation list and its
|
|
399
403
|
PVD/PCG references live in
|
|
400
|
-
`docs/operation-coverage.yaml`. `
|
|
401
|
-
|
|
404
|
+
`docs/operation-coverage.yaml`. `readApplicationBootstrap` is intentionally unexposed because it returns the Provider
|
|
405
|
+
application environment and menu model, while SDK identity is sourced from token issuance. `readLiteratureCreateTemplate`
|
|
402
406
|
is intentionally unexposed because it returns a frontend form definition and an optional deployment flag rather than
|
|
403
407
|
a resource needed by the SDK interface. There are no `planned` operations. Experimental support means the SDK
|
|
404
408
|
validates and exposes the pinned Contract while preserving limitations such as unstable ordering/pagination,
|
|
@@ -472,9 +476,12 @@ await client.templates.save_content(template, modules)
|
|
|
472
476
|
`TemplateModule.data_present` distinguishes a missing `data` property from an explicit null value, while
|
|
473
477
|
`attributes` prevents additive canonical properties from being dropped during a read/save cycle. The SDK does not
|
|
474
478
|
synthesize frontend editor UIDs, layout widths, rows, folders, option encoding, or a fixed set of display module
|
|
475
|
-
types.
|
|
476
|
-
|
|
477
|
-
|
|
479
|
+
types. A JSON-language code module with style metadata may return its JSON string or explicit `null`; number and boolean
|
|
480
|
+
table cells preserve the Provider's empty string as distinct from scalar and `null` values. The Provider accepts some
|
|
481
|
+
non-canonical module roots and arbitrary table file arrays, but the SDK does not expose that behavior: saved content
|
|
482
|
+
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-046).
|
|
483
|
+
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-007),
|
|
484
|
+
so a read-modify-save sequence can overwrite a concurrent change.
|
|
478
485
|
|
|
479
486
|
The market result retains the Provider's `total_count` and derives `has_more` without echoing the caller's page
|
|
480
487
|
arguments; it does not claim a stable order or continuation token. Template reads remain experimental
|
|
@@ -585,8 +592,9 @@ returns the acknowledgement classification
|
|
|
585
592
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
586
593
|
retries stay disabled. Encrypted record content is outside the SDK's public read/update interface: the list-level
|
|
587
594
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
588
|
-
password lifecycle remain unexposed. Files-module attachment append
|
|
589
|
-
|
|
595
|
+
password lifecycle remain unexposed. Files-module attachment append remains root-only because the pinned top-level
|
|
596
|
+
update request schema does not admit the dedicated staged-name append shape's folder `path`; malformed path containers
|
|
597
|
+
may also silently append at root according to PVD-044. A staged attachment is indeterminate once the write has started.
|
|
590
598
|
|
|
591
599
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-019
|
|
592
600
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -884,6 +892,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
884
892
|
```
|
|
885
893
|
|
|
886
894
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
887
|
-
byte-identical wheel and source distribution hashes. The release is bound to
|
|
888
|
-
|
|
889
|
-
`
|
|
895
|
+
byte-identical wheel and source distribution hashes. The release is bound to immutable `matelab-spec v0.4.4`, commit
|
|
896
|
+
`be070c5f931b2063327a3beaccc53a360204b64e`, and OpenAPI SHA-256
|
|
897
|
+
`2de38e46d3814b8b049af8afd18e85fb20be6ca29cc409390d25df663abc43f9`.
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"contract_line": "integration-v1",
|
|
4
4
|
"release": {
|
|
5
|
-
"tag": "v0.4.
|
|
6
|
-
"commit": "
|
|
5
|
+
"tag": "v0.4.4",
|
|
6
|
+
"commit": "be070c5f931b2063327a3beaccc53a360204b64e"
|
|
7
7
|
},
|
|
8
8
|
"openapi": {
|
|
9
9
|
"source_path": "openapi/matelab-integration-v1.openapi.yaml",
|
|
10
10
|
"snapshot": "matelab-integration-v1.openapi.yaml",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "2de38e46d3814b8b049af8afd18e85fb20be6ca29cc409390d25df663abc43f9"
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
openapi: 3.1.0
|
|
2
2
|
info:
|
|
3
3
|
title: Matelab Integration Contract
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.4
|
|
5
5
|
description: |
|
|
6
6
|
Current PHP wire contract for generating SDKs against the selected
|
|
7
7
|
`matelab-server` Provider version.
|
|
@@ -9,7 +9,7 @@ info:
|
|
|
9
9
|
x-contract-line: integration-v1
|
|
10
10
|
x-provider-evidence:
|
|
11
11
|
repository: /home/tnzhu/projects/matelab-server
|
|
12
|
-
commit:
|
|
12
|
+
commit: 7bd9704286057653632424fa82f413d99cd69ab6
|
|
13
13
|
files:
|
|
14
14
|
- controller/Actions.php
|
|
15
15
|
- controller/Tokens.php
|
|
@@ -39,8 +39,8 @@ info:
|
|
|
39
39
|
- sql/matelab.sql
|
|
40
40
|
- sql/recommend.sql
|
|
41
41
|
x-provider-audit:
|
|
42
|
-
currentCommit:
|
|
43
|
-
previousReleaseEvidenceCommit:
|
|
42
|
+
currentCommit: 7bd9704286057653632424fa82f413d99cd69ab6
|
|
43
|
+
previousReleaseEvidenceCommit: a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27
|
|
44
44
|
contractStatus: current-provider-aligned
|
|
45
45
|
incorporatedChanges:
|
|
46
46
|
- {operationId: stageTemporaryFile, change: staging-identifiers-expanded-to-100}
|
|
@@ -49,7 +49,13 @@ info:
|
|
|
49
49
|
- {operationId: importRecordDataset, change: explicit-null-table-file-cells-rejected}
|
|
50
50
|
- {operationId: extractLiteratureMetadata, change: doi-format-validated-before-extraction}
|
|
51
51
|
- {operationId: searchRecordData, change: encrypted-records-excluded}
|
|
52
|
-
- {operationId: updateRecordData, change: files-folder-path-
|
|
52
|
+
- {operationId: updateRecordData, change: safe-files-folder-path-restored-to-callable-shape}
|
|
53
|
+
- {operationId: readApplicationBootstrap, change: identity-and-notifications-moved-out-of-app-response}
|
|
54
|
+
- {operationId: readRecord, change: table-file-cell-readback-modeled-as-attachment-object-or-null}
|
|
55
|
+
- {operationId: readRecord, change: current-unlocked-datetime-locked-may-be-null}
|
|
56
|
+
- {operationId: readTemplateContent, change: json-code-null-readback-accepted}
|
|
57
|
+
- {operationId: saveTemplateContent, change: empty-number-and-boolean-cells-preserved}
|
|
58
|
+
- {operationId: saveTemplateContent, change: noncanonical-module-structures-contract-contained}
|
|
53
59
|
x-consumer-evidence:
|
|
54
60
|
- repository: /home/tnzhu/projects/matelab-mcp
|
|
55
61
|
commit: 94a129b2df0ef0fbcf179c10550fb7c9a5dd2e6f
|
|
@@ -64,8 +70,11 @@ info:
|
|
|
64
70
|
record and currently resolves its private staging state through a
|
|
65
71
|
native `#hash` reference.
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
At this recorded MCP commit, identity resolution used a non-contract
|
|
74
|
+
POST to `/actions/app`. The current Provider removed identity from that
|
|
75
|
+
response, so this historical call cannot define current wire; session
|
|
76
|
+
identity must come from token issuance. ELN-group and notebook-list
|
|
77
|
+
calls still provide Consumer evidence for their canonical GET forms.
|
|
69
78
|
- repository: /home/tnzhu/projects/matelab-front
|
|
70
79
|
commit: 3c356731e883f6035fc4b475b84982739bba4095
|
|
71
80
|
files:
|
|
@@ -81,6 +90,11 @@ info:
|
|
|
81
90
|
- src/views/recommend/fav.vue
|
|
82
91
|
- src/views/recommend/favDetail.vue
|
|
83
92
|
- src/views/recommend/favItems.vue
|
|
93
|
+
note: |
|
|
94
|
+
This Front commit reads environment/menu and identity/notifications
|
|
95
|
+
from `/actions/app`. The current Provider moved the latter fields out
|
|
96
|
+
of that route; only the still-callable application-bootstrap use case
|
|
97
|
+
defines the current `/actions/app` contract.
|
|
84
98
|
x-record-attachment-staging:
|
|
85
99
|
status: contract-contained
|
|
86
100
|
producerOperationId: uploadRecordAttachment
|
|
@@ -128,8 +142,8 @@ info:
|
|
|
128
142
|
operationArrays: [add]
|
|
129
143
|
attachmentOperationSchema:
|
|
130
144
|
$ref: "#/components/schemas/AppendFilesModuleStagedAttachmentOperation"
|
|
131
|
-
folderPath:
|
|
132
|
-
readback: one-new-canonical-files-entry
|
|
145
|
+
folderPath: optional-non-empty-safe-segments
|
|
146
|
+
readback: one-new-canonical-files-entry-at-root-or-resolved-folder
|
|
133
147
|
tableFileCellReplacement:
|
|
134
148
|
operationArrays: [modify]
|
|
135
149
|
attachmentOperationSchema:
|
|
@@ -223,15 +237,15 @@ tags:
|
|
|
223
237
|
paths:
|
|
224
238
|
/actions/app:
|
|
225
239
|
get:
|
|
226
|
-
operationId:
|
|
240
|
+
operationId: readApplicationBootstrap
|
|
227
241
|
tags: [Authentication]
|
|
228
|
-
summary:
|
|
242
|
+
summary: Read the authenticated Matelab application bootstrap
|
|
229
243
|
description: |
|
|
230
|
-
Read-only
|
|
231
|
-
`/actions/app` method in integration-v1.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
244
|
+
Read-only environment, product-name, AI and menu bootstrap used by
|
|
245
|
+
Matelab Front and the only `/actions/app` method in integration-v1.
|
|
246
|
+
The current Provider no longer returns `user` or `notifications` from
|
|
247
|
+
this route; authenticated identity is available from token issuance
|
|
248
|
+
flows and is not inferred from this response.
|
|
235
249
|
security:
|
|
236
250
|
- bearerAuth: []
|
|
237
251
|
responses:
|
|
@@ -241,22 +255,16 @@ paths:
|
|
|
241
255
|
application/json:
|
|
242
256
|
schema:
|
|
243
257
|
oneOf:
|
|
244
|
-
- $ref: "#/components/schemas/
|
|
258
|
+
- $ref: "#/components/schemas/AppBootstrapResponse"
|
|
245
259
|
- $ref: "#/components/schemas/ErrorResponse"
|
|
246
260
|
examples:
|
|
247
261
|
success:
|
|
248
|
-
summary:
|
|
262
|
+
summary: Application bootstrap with enabled ELN navigation
|
|
249
263
|
value:
|
|
250
264
|
code: 0
|
|
251
265
|
msg: ""
|
|
252
266
|
errcode: 0
|
|
253
267
|
errmsg: ""
|
|
254
|
-
user:
|
|
255
|
-
username: Example User
|
|
256
|
-
avatar: null
|
|
257
|
-
email: user@example.invalid
|
|
258
|
-
userid: 101
|
|
259
|
-
notifications: []
|
|
260
268
|
env:
|
|
261
269
|
ai: false
|
|
262
270
|
smtp: true
|
|
@@ -288,22 +296,12 @@ paths:
|
|
|
288
296
|
url: /db/eln
|
|
289
297
|
order: 1
|
|
290
298
|
nullable:
|
|
291
|
-
summary:
|
|
299
|
+
summary: Application bootstrap with no licensed institute features
|
|
292
300
|
value:
|
|
293
301
|
code: 0
|
|
294
302
|
msg: ""
|
|
295
303
|
errcode: 0
|
|
296
304
|
errmsg: ""
|
|
297
|
-
user:
|
|
298
|
-
username: null
|
|
299
|
-
avatar: null
|
|
300
|
-
email: null
|
|
301
|
-
userid: 102
|
|
302
|
-
notifications:
|
|
303
|
-
- id: 501
|
|
304
|
-
showtext: null
|
|
305
|
-
datetime_add: "2026-01-02 08:00:00"
|
|
306
|
-
datetime: "2026-01-02 08:00"
|
|
307
305
|
env:
|
|
308
306
|
ai: false
|
|
309
307
|
smtp: false
|
|
@@ -827,6 +825,7 @@ paths:
|
|
|
827
825
|
operationId: saveTemplateContent
|
|
828
826
|
tags: [Templates]
|
|
829
827
|
summary: Replace canonical modules for an owned template
|
|
828
|
+
x-known-provider-issues: [PVD-046]
|
|
830
829
|
security: [{bearerAuth: []}]
|
|
831
830
|
requestBody:
|
|
832
831
|
required: true
|
|
@@ -1688,8 +1687,10 @@ paths:
|
|
|
1688
1687
|
or replacing an exact table file cell, appending a table row and
|
|
1689
1688
|
setting its file cell in the same request, appending one root files
|
|
1690
1689
|
entry, and replacing one files entry by an immediately read index.
|
|
1691
|
-
Files-module folder `path`
|
|
1692
|
-
|
|
1690
|
+
Files-module folder `path` accepts a non-empty list of safe folder-name
|
|
1691
|
+
segments. PVD-044 remains because malformed or empty path containers are
|
|
1692
|
+
not reliably rejected by the Provider; those shapes stay outside the
|
|
1693
|
+
callable request schema.
|
|
1693
1694
|
Form-file replacement remains unsafe under PVD-014. Richtext only
|
|
1694
1695
|
recognizes hash-bearing `elnurl://` references; `#file{name}` is plain
|
|
1695
1696
|
text there, while the hash path can fall back to an existing quote and
|
|
@@ -2541,6 +2542,19 @@ paths:
|
|
|
2541
2542
|
name: Notes
|
|
2542
2543
|
uid: module-example
|
|
2543
2544
|
data: Sanitized content
|
|
2545
|
+
- type: table
|
|
2546
|
+
name: Measurements
|
|
2547
|
+
uid: table-example
|
|
2548
|
+
rows: [row-example]
|
|
2549
|
+
data:
|
|
2550
|
+
- type: file
|
|
2551
|
+
name: Evidence
|
|
2552
|
+
uid: column-example
|
|
2553
|
+
data:
|
|
2554
|
+
- filename: evidence.txt
|
|
2555
|
+
hash: 74034daeef860e12596c34f7e83703e668d578f4a85e72ec1645117223d4e6a7
|
|
2556
|
+
size: 26
|
|
2557
|
+
timestamp: 1767946200000
|
|
2544
2558
|
template_id: 8
|
|
2545
2559
|
datetime_modify: 1767946200000
|
|
2546
2560
|
username: Example User
|
|
@@ -2554,7 +2568,7 @@ paths:
|
|
|
2554
2568
|
uid: REC-EXAMPLE-001
|
|
2555
2569
|
current_version: 70001
|
|
2556
2570
|
item_id: 9001
|
|
2557
|
-
datetime_locked:
|
|
2571
|
+
datetime_locked: null
|
|
2558
2572
|
locked: false
|
|
2559
2573
|
signs: []
|
|
2560
2574
|
signed: false
|
|
@@ -4450,13 +4464,11 @@ components:
|
|
|
4450
4464
|
filename: {type: string, minLength: 1}
|
|
4451
4465
|
size: {type: integer, minimum: 0}
|
|
4452
4466
|
hash: {$ref: "#/components/schemas/Sha256"}
|
|
4453
|
-
|
|
4467
|
+
AppBootstrapResponse:
|
|
4454
4468
|
allOf:
|
|
4455
4469
|
- $ref: "#/components/schemas/ResponseEnvelope"
|
|
4456
4470
|
- type: object
|
|
4457
4471
|
required:
|
|
4458
|
-
- user
|
|
4459
|
-
- notifications
|
|
4460
4472
|
- env
|
|
4461
4473
|
- ai_enable
|
|
4462
4474
|
- ai_text
|
|
@@ -4470,13 +4482,6 @@ components:
|
|
|
4470
4482
|
const: 0
|
|
4471
4483
|
errcode:
|
|
4472
4484
|
const: 0
|
|
4473
|
-
user:
|
|
4474
|
-
$ref: "#/components/schemas/AppUser"
|
|
4475
|
-
notifications:
|
|
4476
|
-
type: array
|
|
4477
|
-
maxItems: 5
|
|
4478
|
-
items:
|
|
4479
|
-
$ref: "#/components/schemas/AppNotification"
|
|
4480
4485
|
env:
|
|
4481
4486
|
$ref: "#/components/schemas/AppEnvironment"
|
|
4482
4487
|
ai_enable:
|
|
@@ -4498,36 +4503,6 @@ components:
|
|
|
4498
4503
|
type: array
|
|
4499
4504
|
items:
|
|
4500
4505
|
$ref: "#/components/schemas/AppMenu"
|
|
4501
|
-
AppUser:
|
|
4502
|
-
type: object
|
|
4503
|
-
required: [username, avatar, email, userid]
|
|
4504
|
-
properties:
|
|
4505
|
-
username:
|
|
4506
|
-
type: [string, "null"]
|
|
4507
|
-
description: Raw nullable `login_user.realname`.
|
|
4508
|
-
avatar:
|
|
4509
|
-
type: [string, "null"]
|
|
4510
|
-
description: Raw id-photo path, normalized to null when empty.
|
|
4511
|
-
email:
|
|
4512
|
-
type: [string, "null"]
|
|
4513
|
-
userid:
|
|
4514
|
-
type: integer
|
|
4515
|
-
minimum: 1
|
|
4516
|
-
AppNotification:
|
|
4517
|
-
type: object
|
|
4518
|
-
required: [id, showtext, datetime_add, datetime]
|
|
4519
|
-
properties:
|
|
4520
|
-
id:
|
|
4521
|
-
type: integer
|
|
4522
|
-
minimum: 1
|
|
4523
|
-
showtext:
|
|
4524
|
-
type: [string, "null"]
|
|
4525
|
-
datetime_add:
|
|
4526
|
-
type: [string, "null"]
|
|
4527
|
-
description: Raw database datetime retained by the PHP response.
|
|
4528
|
-
datetime:
|
|
4529
|
-
type: string
|
|
4530
|
-
description: Provider-formatted `Y-m-d H:i`.
|
|
4531
4506
|
AppEnvironment:
|
|
4532
4507
|
type: object
|
|
4533
4508
|
required:
|
|
@@ -4914,7 +4889,7 @@ components:
|
|
|
4914
4889
|
required: [data]
|
|
4915
4890
|
properties:
|
|
4916
4891
|
data:
|
|
4917
|
-
type: string
|
|
4892
|
+
type: [string, "null"]
|
|
4918
4893
|
contentMediaType: application/json
|
|
4919
4894
|
additionalProperties: true
|
|
4920
4895
|
TemplateTableColumn:
|
|
@@ -4949,6 +4924,7 @@ components:
|
|
|
4949
4924
|
oneOf:
|
|
4950
4925
|
- {type: number}
|
|
4951
4926
|
- {type: string, pattern: '^[+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$'}
|
|
4927
|
+
- {type: string, const: ""}
|
|
4952
4928
|
- {type: "null"}
|
|
4953
4929
|
- if:
|
|
4954
4930
|
properties: {type: {const: bool}}
|
|
@@ -4957,7 +4933,11 @@ components:
|
|
|
4957
4933
|
properties:
|
|
4958
4934
|
data:
|
|
4959
4935
|
type: array
|
|
4960
|
-
items:
|
|
4936
|
+
items:
|
|
4937
|
+
oneOf:
|
|
4938
|
+
- {type: boolean}
|
|
4939
|
+
- {type: string, const: ""}
|
|
4940
|
+
- {type: "null"}
|
|
4961
4941
|
- if:
|
|
4962
4942
|
properties: {type: {const: file}}
|
|
4963
4943
|
required: [type]
|
|
@@ -4967,9 +4947,25 @@ components:
|
|
|
4967
4947
|
type: array
|
|
4968
4948
|
items:
|
|
4969
4949
|
oneOf:
|
|
4970
|
-
- {
|
|
4950
|
+
- {$ref: "#/components/schemas/RecordAttachment"}
|
|
4971
4951
|
- {type: "null"}
|
|
4972
4952
|
additionalProperties: true
|
|
4953
|
+
RecordAttachment:
|
|
4954
|
+
type: object
|
|
4955
|
+
required: [filename, hash, size, timestamp]
|
|
4956
|
+
properties:
|
|
4957
|
+
filename:
|
|
4958
|
+
type: string
|
|
4959
|
+
description: Original filename; the Provider's canonical empty attachment uses an empty string.
|
|
4960
|
+
hash:
|
|
4961
|
+
type: string
|
|
4962
|
+
pattern: "^(?:[0-9a-f]{64})?$"
|
|
4963
|
+
description: SHA-256 digest, or an empty string in the Provider's canonical empty attachment.
|
|
4964
|
+
size: {type: integer, minimum: 0}
|
|
4965
|
+
timestamp:
|
|
4966
|
+
type: integer
|
|
4967
|
+
minimum: 1
|
|
4968
|
+
description: Provider-generated Unix timestamp in milliseconds.
|
|
4973
4969
|
TemplateFormItem:
|
|
4974
4970
|
type: object
|
|
4975
4971
|
required: [name]
|
|
@@ -5603,6 +5599,17 @@ components:
|
|
|
5603
5599
|
required: [module, data]
|
|
5604
5600
|
properties:
|
|
5605
5601
|
module: {type: string, minLength: 1}
|
|
5602
|
+
path:
|
|
5603
|
+
type: array
|
|
5604
|
+
minItems: 1
|
|
5605
|
+
items:
|
|
5606
|
+
type: string
|
|
5607
|
+
minLength: 1
|
|
5608
|
+
maxLength: 245
|
|
5609
|
+
pattern: '^[^/:*?"<>\\|]+$'
|
|
5610
|
+
description: |
|
|
5611
|
+
Ordered folder names below the files-module root. Existing folders
|
|
5612
|
+
are reused by exact name and parent; missing folders are created.
|
|
5606
5613
|
data:
|
|
5607
5614
|
type: object
|
|
5608
5615
|
required: [file, text]
|
|
@@ -5612,8 +5619,10 @@ components:
|
|
|
5612
5619
|
additionalProperties: false
|
|
5613
5620
|
additionalProperties: false
|
|
5614
5621
|
description: |
|
|
5615
|
-
Appends one staged attachment to the root of an existing files module
|
|
5616
|
-
|
|
5622
|
+
Appends one staged attachment to the root of an existing files module
|
|
5623
|
+
when `path` is absent, or below the resolved folder path when present.
|
|
5624
|
+
Empty and malformed path containers are intentionally outside the
|
|
5625
|
+
callable shape because the Provider treats some of them as root append.
|
|
5617
5626
|
ReplaceFilesModuleStagedAttachmentOperation:
|
|
5618
5627
|
type: object
|
|
5619
5628
|
required: [path, data]
|
|
@@ -6518,9 +6527,12 @@ components:
|
|
|
6518
6527
|
type: integer
|
|
6519
6528
|
minimum: 1
|
|
6520
6529
|
datetime_locked:
|
|
6521
|
-
type: integer
|
|
6530
|
+
type: [integer, "null"]
|
|
6522
6531
|
minimum: 0
|
|
6523
|
-
description:
|
|
6532
|
+
description: |
|
|
6533
|
+
Unix timestamp in milliseconds; null for the current unlocked
|
|
6534
|
+
record. Provider paths that normalize the absent timestamp may
|
|
6535
|
+
return zero.
|
|
6524
6536
|
locked:
|
|
6525
6537
|
type: boolean
|
|
6526
6538
|
signs:
|