Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions docs/strictdoc_01_user_guide.sdoc
Original file line number Diff line number Diff line change
Expand Up @@ -2442,8 +2442,8 @@ This is the example of how images are included using the reST syntax:

.. note::

Currently, it is not possible to upload images via the web user interface.
Therefore, you must manually place the image into the ``_assets`` folder using either the command-line or a file browser.
When editing a requirement or a text block in the Web UI, you can also **drag and drop** image files directly into the statement field, or **paste** an image from the clipboard.
This will automatically upload the image to the "_assets" folder and insert the required reST image directive.
<<<

[[/SECTION]]
Expand Down Expand Up @@ -4707,7 +4707,6 @@ Currently StrictDoc server maintains an in-memory state of a documentation tree,
The following essential features are still missing and will be worked on in the future:

- A dedicated screen where a user can commit and push changes to GitHub/GitLab or other Git servers.
- Adding images via drag-and-drop or an upload button to the multiline fields like such requirements and text nodes ``STATEMENT``.
- Adding/editing sections with ``LEVEL: None``.
- Deleting a document.
- Deleting a section recursively with a correct cleanup of all traceability information.
Expand Down
147 changes: 147 additions & 0 deletions docs/strictdoc_22_l3_low_level_requirements.sdoc
Original file line number Diff line number Diff line change
Expand Up @@ -965,3 +965,150 @@ RELATIONS:
[[/SECTION]]

[[/SECTION]]

[[SECTION]]
MID: b0138705e9b24886bd2792faff067410
TITLE: Assets

[REQUIREMENT]
MID: 992a734673884c4a89ada5cb1fd640c4
UID: SDOC-LLR-211
TITLE: Asset directory resolution
STATEMENT: >>>
StrictDoc shall associate a local _assets directory with every document to store assets.

Documents shall reference assets via relative paths.
<<<
RATIONALE: >>>
- The local assets directory preserves compatibility with standard relative paths.
<<<

[REQUIREMENT]
MID: da0c32fb66434bcd80d959613a35a446
UID: SDOC-LLR-212
TITLE: Asset Exporting
STATEMENT: >>>
When exporting, StrictDoc shall copy the contents of the Local Asset Directories to the output folder.

The directory structure of the assets within the output folder shall mirror their relative structure in the source project tree to preserve relative path integrity.
<<<

[[SECTION]]
MID: ce512ba0998d4ea1a85cfed432007922
TITLE: Image Upload

[REQUIREMENT]
MID: 7768b2575117435e80c3b26515382b23
UID: SDOC-LLR-207
STATUS: Active
TITLE: Image upload
STATEMENT: >>>
The Web Editor shall support image upload in multi-line text fields via paste and drag-and-drop:

1. Intercept `drop` and `paste` events and prevent default browser behaviour.
2. Accept only image MIME types.
3. Upload images asynchronously to the backend ``/actions/document/upload_asset`` endpoint, passing the current requirement MID and the active document MID along.
4. Indicate upload progress via a temporary placeholder text.
5. On success, insert an image reference at the original cursor position, following the document's markup:

- RST: ``.. image:: ./_assets/<node_specific_subfolder>/<filename>``
- HTML: ``<img src="./_assets/<node_specific_subfolder>/<filename>" />``
- Markdown: ``![](./_assets/<node_specific_subfolder>/<filename>)``

6. On failure, notify the user.
<<<
RATIONALE: >>>
Supports standard editor interactions and removes manual file handling, improving usability and reducing potential for user errors.
<<<

[REQUIREMENT]
MID: 7cdd7a0838fc4212a43b336eba5ccde8
UID: SDOC-LLR-208
TITLE: Asset upload endpoint
STATEMENT: >>>
The StrictDoc web server shall provide an ``/actions/document/upload_asset`` endpoint that accepts image uploads and stores them in a node-specific subfolder.

The endpoint shall:

1. Validate that the payload is an image, and the node is not read-only (i.e. autogen)
2. Sanitize the filename by replacing spaces with underscores.
3. Validate the requirement MIDs formally
4. Use the provided Document MID to resolve the correct document relative ``_assets`` directory.
5. Determine the exact target subfolder based on the Asset Path Resolution Strategy (see [LINK: SDOC-LLR-213]).
6. Store the file in the target folder, and overwrite any existing image file with the same name.
7. Sync the assets to the web server so it can be served immediately.
8. When successful, return HTTP 200 with the stored filename expressed as relative paths.
9. When unsuccessful, return an error response.
<<<
RATIONALE: >>>
Defines a consistent and predictable storage model for image assets:

- preventing image filename collisions between requirements,
- allowing the user to update an image through re-uploading,
- allowing the user to upload images when creating a new requirement
<<<

[REQUIREMENT]
MID: 27981746203042b299b216295b6a7588
UID: SDOC-LLR-213
TITLE: Asset path resolution strategy
STATEMENT: >>>
When storing an uploaded asset, the system shall determine the correct node-specific subfolder within the document local ``_assets`` directory based on the following strategy:

- If the node has a permanent MID, or if MIDs are explicitly enabled in the document options, the subfolder shall be ``_assets/<MID>/``. (This allows uploads for not-yet-existing requirements when MIDs are enabled).

- Otherwise, if the node exists and has a UID, the subfolder shall be ``_assets/<UID>/``.

- Otherwise, if the node exists but lacks both a permanent MID and UID, the asset shall be stored in the document local ``_assets/`` directory.

- If the node does not yet exist and MIDs are disabled, the upload shall be rejected.
<<<
RATIONALE: >>>
Defines a consistent storage model that prevents image filename collisions between requirements.

- Prioritizing the MID over the UID ensures asset paths remain stable even if a requirement's human-readable UID is changed later.

- When MIDs are disabled, the asset storage path depends entirely on the node's UID, which is only established after the node is created. Therefore, image upload attempts at node creation time must be rejected to prevent orphaned files.
<<<

[REQUIREMENT]
MID: 3157ce3de267437c8e083455fc2b1b87
UID: SDOC-LLR-209
TITLE: Support for wildcard image directive generation
STATEMENT: >>>
When multiple image files are uploaded in a single operation, the ``/actions/document/upload_asset`` endpoint shall detect pairs of files that share the same filename stem and differ only by file extension.

If such a pair consists of one raster format image and one vector format image, the system shall:

- Store both files in the requirement-specific assets location.
- Return information that allows the client to generate a single image directive using the wildcard filename ``./_assets/<node_specific_subfolder>/<stem>.*``.

If no such pair is detected, the system shall treat each file independently.
<<<
RATIONALE: >>>
Supports the wildcard-enhanced-image feature of StrictDoc/ReST also when uploading images through the server
<<<

[REQUIREMENT]
MID: 82dd31e22ccf44bd8b6b924ae9591b0c
UID: SDOC-LLR-210
TITLE: Orphaned asset cleanup
STATEMENT: >>>
StrictDoc shall provide a CLI command ``strictdoc manage assets`` to identify and remove orphaned assets.

An asset file shall be considered orphaned if it is an image file, and not referenced by any requirement.

The command shall:

- Detect image references in nodes (for RST, HTML or Markdown).
- List image files that are not referenced by any requirement.
- Remove such orphaned files upon user request.
- When removing files, also remove empty asset folders.
<<<
RATIONALE: >>>
Prevents accumulation of orphaned assets. This would for instance happen if requirement creation is aborted after already having uploaded images.
<<<

[[/SECTION]]

[[/SECTION]]
3 changes: 2 additions & 1 deletion strictdoc/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from strictdoc.commands.export import ExportCommand
from strictdoc.commands.import_excel import ImportExcelCommand
from strictdoc.commands.import_reqif import ImportReqIFCommand
from strictdoc.commands.manage_assets_command import ManageAssetsCommand
from strictdoc.commands.manage_autouid_command import ManageAutoUIDCommand
from strictdoc.commands.server import ServerCommand
from strictdoc.commands.version_command import VersionCommand
Expand All @@ -27,7 +28,7 @@
"about": AboutCommand,
"export": ExportCommand,
"import": {"excel": ImportExcelCommand, "reqif": ImportReqIFCommand},
"manage": {"auto-uid": ManageAutoUIDCommand},
"manage": {"auto-uid": ManageAutoUIDCommand, "assets": ManageAssetsCommand},
"server": ServerCommand,
"version": VersionCommand,
}
Expand Down
Loading
Loading