stapel-docs 0.2.2__tar.gz → 0.2.4__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 (80) hide show
  1. {stapel_docs-0.2.2/stapel_docs.egg-info → stapel_docs-0.2.4}/PKG-INFO +4 -4
  2. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/README.md +2 -2
  3. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/docs/capabilities.json +1 -1
  4. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/docs/errors.json +8 -0
  5. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/docs/llms.txt +4 -3
  6. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/pyproject.toml +7 -2
  7. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/services.py +38 -32
  8. {stapel_docs-0.2.2 → stapel_docs-0.2.4/stapel_docs.egg-info}/PKG-INFO +4 -4
  9. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/stapel_docs.egg-info/requires.txt +1 -1
  10. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/CONFIG.MD +0 -0
  11. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/LICENSE +0 -0
  12. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/__init__.py +0 -0
  13. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/_capabilities.py +0 -0
  14. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/_codegen.py +0 -0
  15. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/_codegen_settings.py +0 -0
  16. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/actions.py +0 -0
  17. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/admin.py +0 -0
  18. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/apps.py +0 -0
  19. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/assets/DEJAVU-FONTS-LICENSE.txt +0 -0
  20. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/assets/DejaVuSans-Bold.ttf +0 -0
  21. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/assets/DejaVuSans.ttf +0 -0
  22. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/authz.py +0 -0
  23. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/checks.py +0 -0
  24. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/codegen_urls.py +0 -0
  25. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/conf.py +0 -0
  26. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/conftest.py +0 -0
  27. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/doc_types.py +0 -0
  28. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/docs/flows.json +0 -0
  29. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/dto.py +0 -0
  30. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/errors.py +0 -0
  31. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/events.py +0 -0
  32. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/exporters.py +0 -0
  33. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/functions.py +0 -0
  34. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/gdpr.py +0 -0
  35. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/management/__init__.py +0 -0
  36. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/management/commands/__init__.py +0 -0
  37. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/management/commands/docs_purge_expired.py +0 -0
  38. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/migrations/0001_initial.py +0 -0
  39. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/migrations/0002_uploadsession_checksum_uploadsession_expires_at.py +0 -0
  40. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/migrations/__init__.py +0 -0
  41. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/models.py +0 -0
  42. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/presenters.py +0 -0
  43. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/py.typed +0 -0
  44. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/schemas/emits/document.created.json +0 -0
  45. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/schemas/emits/document.deleted.json +0 -0
  46. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/schemas/emits/document.storage_changed.json +0 -0
  47. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/schemas/emits/document.updated.json +0 -0
  48. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/schemas/functions/docs.create_document.json +0 -0
  49. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/serializers.py +0 -0
  50. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/setup.cfg +0 -0
  51. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/stapel_docs.egg-info/SOURCES.txt +0 -0
  52. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/stapel_docs.egg-info/dependency_links.txt +0 -0
  53. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/stapel_docs.egg-info/top_level.txt +0 -0
  54. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/storage.py +0 -0
  55. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tasks.py +0 -0
  56. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_checks.py +0 -0
  57. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_comm.py +0 -0
  58. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_content.py +0 -0
  59. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_contract.py +0 -0
  60. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_documents.py +0 -0
  61. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_error_i18n.py +0 -0
  62. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_export.py +0 -0
  63. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_folders.py +0 -0
  64. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_gdpr.py +0 -0
  65. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_ingest.py +0 -0
  66. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_limits.py +0 -0
  67. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_public_api.py +0 -0
  68. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_revisions.py +0 -0
  69. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_storage_seam.py +0 -0
  70. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_storage_tx.py +0 -0
  71. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_tasks.py +0 -0
  72. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_trash.py +0 -0
  73. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_updates.py +0 -0
  74. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/tests/test_uploads.py +0 -0
  75. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/translations/.state.json +0 -0
  76. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/translations/errors.es.json +0 -0
  77. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/translations/errors.ru.json +0 -0
  78. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/urls.py +0 -0
  79. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/urls_v1.py +0 -0
  80. {stapel_docs-0.2.2 → stapel_docs-0.2.4}/views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stapel-docs
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Documents: storage, revisions and per-type editors for the Stapel framework
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/usestapel/stapel-docs
@@ -22,7 +22,7 @@ Classifier: Typing :: Typed
22
22
  Requires-Python: >=3.11
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
- Requires-Dist: stapel-core<1.0,>=0.26.0
25
+ Requires-Dist: stapel-core<1.0,>=0.27.0
26
26
  Provides-Extra: s3
27
27
  Requires-Dist: boto3>=1.26; extra == "s3"
28
28
  Provides-Extra: pdf
@@ -58,13 +58,13 @@ pip install stapel-docs
58
58
 
59
59
  | Fact | Value |
60
60
  |---|---|
61
- | Version | `0.2.2` |
61
+ | Version | `0.2.4` |
62
62
  | Python | `>=3.11` (3.11, 3.12, 3.13) |
63
63
  | HTTP operations | 27 |
64
64
  | Config axes | 1 |
65
65
  | Usage surface | 54 |
66
66
  | Extension points | 7 |
67
- | Error codes | 73 |
67
+ | Error codes | 74 |
68
68
  | Fleet dependencies | [`stapel-auth`](https://github.com/usestapel/stapel-auth) (optional) · [`stapel-core`](https://github.com/usestapel/stapel-core) · [`stapel-workspaces`](https://github.com/usestapel/stapel-workspaces) (optional) |
69
69
 
70
70
  ## Documentation
@@ -24,13 +24,13 @@ pip install stapel-docs
24
24
 
25
25
  | Fact | Value |
26
26
  |---|---|
27
- | Version | `0.2.2` |
27
+ | Version | `0.2.4` |
28
28
  | Python | `>=3.11` (3.11, 3.12, 3.13) |
29
29
  | HTTP operations | 27 |
30
30
  | Config axes | 1 |
31
31
  | Usage surface | 54 |
32
32
  | Extension points | 7 |
33
- | Error codes | 73 |
33
+ | Error codes | 74 |
34
34
  | Fleet dependencies | [`stapel-auth`](https://github.com/usestapel/stapel-auth) (optional) · [`stapel-core`](https://github.com/usestapel/stapel-core) · [`stapel-workspaces`](https://github.com/usestapel/stapel-workspaces) (optional) |
35
35
 
36
36
  ## Documentation
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "module": "stapel-docs",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "provides": "Google-Drive-style workspace documents: a folder tree, one-entity-per-type documents over an open type registry, content-addressed snapshot storage with an update journal and revision history, optimistic-lock editing (v1), trash with irreversible purge, a swappable object-storage seam, comm ingest (docs.create_document) and registry-driven export (PDF built in).",
5
5
  "axes": [
6
6
  {
@@ -603,6 +603,14 @@
603
603
  "en": "Workspace membership service is unavailable",
604
604
  "owner": "stapel_docs"
605
605
  },
606
+ {
607
+ "code": "error.503.mandate_unavailable",
608
+ "status": 503,
609
+ "params": [],
610
+ "remediation": "retry",
611
+ "en": "Cannot verify workspace mandate right now",
612
+ "owner": "stapel_core"
613
+ },
606
614
  {
607
615
  "code": "error.507.docs_workspace_quota",
608
616
  "status": 507,
@@ -1,8 +1,8 @@
1
- # stapel-docs 0.2.2
1
+ # stapel-docs 0.2.4
2
2
 
3
3
  Google-Drive-style workspace documents: a folder tree, one-entity-per-type documents over an open type registry, content-addressed snapshot storage with an update journal and revision history, optimistic-lock editing (v1), trash with irreversible purge, a swappable object-storage seam, comm ingest (docs.create_document) and registry-driven export (PDF built in).
4
4
 
5
- Contract: axes 1 · surface 54 · extension points 7 · operations 27 · error codes 73.
5
+ Contract: axes 1 · surface 54 · extension points 7 · operations 27 · error codes 74.
6
6
  Generated from docs/capabilities.json by `stapel-llms-txt` — do not edit; drift-gated by `make contract-check`.
7
7
 
8
8
  ## Configuration axes — what a product switches on
@@ -189,7 +189,7 @@ Paths are relative to `/docs/api/v1/`.
189
189
  - POST /uploads — docs_api_v1_uploads_create
190
190
  - POST /uploads/{upload_id}/finalize — docs_api_v1_uploads_finalize_create
191
191
 
192
- ## Error codes (73) — the StapelError envelope
192
+ ## Error codes (74) — the StapelError envelope
193
193
  Render `t(code, params)`; branch UX on the remediation. Localized text lives in docs/errors.<lang>.md, not here.
194
194
  - error.400.bad_request [400] fix_input
195
195
  - error.400.captcha_invalid [400] retry
@@ -263,4 +263,5 @@ Render `t(code, params)`; branch UX on the remediation. Localized text lives in
263
263
  - error.503.docs_download_url_unavailable [503] retry
264
264
  - error.503.docs_exporter_unavailable [503] retry
265
265
  - error.503.docs_workspaces_unavailable [503] retry
266
+ - error.503.mandate_unavailable [503] retry
266
267
  - error.507.docs_workspace_quota [507] retry
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "stapel-docs"
7
- version = "0.2.2"
7
+ version = "0.2.4"
8
8
  description = "Documents: storage, revisions and per-type editors for the Stapel framework"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -43,7 +43,12 @@ dependencies = [
43
43
  # (>=0.3,<0.4) that made the package uninstallable next to any real host.
44
44
  # Floor: 0.26.0 emits docs/errors.json with the `owner` field the
45
45
  # committed artifact and its drift gate require.
46
- "stapel-core>=0.26.0,<1.0",
46
+ # Floor: 0.27.0 registers `error.503.mandate_unavailable` (+ ru/es
47
+ # catalogs) — CI always installs core off git HEAD, so the committed
48
+ # docs/errors.json (regenerated against the current core) needs the
49
+ # floor to match or a consumer on an older core silently regenerates a
50
+ # smaller artifact and the drift gate goes red again.
51
+ "stapel-core>=0.27.0,<1.0",
47
52
  ]
48
53
 
49
54
  [project.urls]
@@ -622,43 +622,49 @@ def _save_snapshot(
622
622
  already_stored = storage_tx.put(key, body, content_type=content_mime(document))
623
623
  added = 0 if already_stored else len(body)
624
624
 
625
- document.head_seq = new_seq
626
- document.snapshot_seq = new_seq
627
- document.snapshot_key = key
628
- document.size_bytes = len(body)
629
- document.save(
630
- update_fields=["head_seq", "snapshot_seq", "snapshot_key", "size_bytes", "updated_at"]
631
- )
632
-
633
625
  revision = None
634
- if force_revision or _auto_revision_due(document):
635
- revision = Revision.objects.create(
636
- document=document,
637
- seq=new_seq,
638
- kind=Revision.KIND_AUTO,
639
- storage_key=key,
640
- created_by=user,
641
- size_bytes=len(body),
626
+ # Mutation + outbox rows share this atomic block (outbox canon — see
627
+ # module docstring). The callers already hold a wider
628
+ # transaction.atomic(); nesting here is a safe savepoint (per
629
+ # stapel_core.comm.mutate_and_emit's documented nesting guarantee) and
630
+ # makes this helper self-sufficient for emit-check's lexical scan.
631
+ with transaction.atomic():
632
+ document.head_seq = new_seq
633
+ document.snapshot_seq = new_seq
634
+ document.snapshot_key = key
635
+ document.size_bytes = len(body)
636
+ document.save(
637
+ update_fields=["head_seq", "snapshot_seq", "snapshot_key", "size_bytes", "updated_at"]
642
638
  )
643
639
 
644
- # Orphan cleanup: the previous snapshot dies iff no Revision points at
645
- # it (content-addressed keys make identical bodies dedup for free).
646
- freed = 0
647
- if (
648
- prev_key
649
- and prev_key != key
650
- and not Revision.objects.filter(document=document, storage_key=prev_key).exists()
651
- ):
652
- storage_tx.delete(prev_key)
653
- freed = prev_size
640
+ if force_revision or _auto_revision_due(document):
641
+ revision = Revision.objects.create(
642
+ document=document,
643
+ seq=new_seq,
644
+ kind=Revision.KIND_AUTO,
645
+ storage_key=key,
646
+ created_by=user,
647
+ size_bytes=len(body),
648
+ )
649
+
650
+ # Orphan cleanup: the previous snapshot dies iff no Revision points at
651
+ # it (content-addressed keys make identical bodies dedup for free).
652
+ freed = 0
653
+ if (
654
+ prev_key
655
+ and prev_key != key
656
+ and not Revision.objects.filter(document=document, storage_key=prev_key).exists()
657
+ ):
658
+ storage_tx.delete(prev_key)
659
+ freed = prev_size
654
660
 
655
- _compact_journal(document)
661
+ _compact_journal(document)
656
662
 
657
- if emit_updated:
658
- events.emit_document_updated(document)
659
- delta = added - freed
660
- if delta:
661
- events.emit_storage_changed(document.workspace_id, delta)
663
+ if emit_updated:
664
+ events.emit_document_updated(document)
665
+ delta = added - freed
666
+ if delta:
667
+ events.emit_storage_changed(document.workspace_id, delta)
662
668
  return revision
663
669
 
664
670
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stapel-docs
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Documents: storage, revisions and per-type editors for the Stapel framework
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/usestapel/stapel-docs
@@ -22,7 +22,7 @@ Classifier: Typing :: Typed
22
22
  Requires-Python: >=3.11
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
- Requires-Dist: stapel-core<1.0,>=0.26.0
25
+ Requires-Dist: stapel-core<1.0,>=0.27.0
26
26
  Provides-Extra: s3
27
27
  Requires-Dist: boto3>=1.26; extra == "s3"
28
28
  Provides-Extra: pdf
@@ -58,13 +58,13 @@ pip install stapel-docs
58
58
 
59
59
  | Fact | Value |
60
60
  |---|---|
61
- | Version | `0.2.2` |
61
+ | Version | `0.2.4` |
62
62
  | Python | `>=3.11` (3.11, 3.12, 3.13) |
63
63
  | HTTP operations | 27 |
64
64
  | Config axes | 1 |
65
65
  | Usage surface | 54 |
66
66
  | Extension points | 7 |
67
- | Error codes | 73 |
67
+ | Error codes | 74 |
68
68
  | Fleet dependencies | [`stapel-auth`](https://github.com/usestapel/stapel-auth) (optional) · [`stapel-core`](https://github.com/usestapel/stapel-core) · [`stapel-workspaces`](https://github.com/usestapel/stapel-workspaces) (optional) |
69
69
 
70
70
  ## Documentation
@@ -1,4 +1,4 @@
1
- stapel-core<1.0,>=0.26.0
1
+ stapel-core<1.0,>=0.27.0
2
2
 
3
3
  [all]
4
4
  boto3>=1.26
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes