Architecture

This document contains the architectural design for zen-do. For design details of the Seedcase Project as a whole, see the Seedcase Design documentation.

The purpose of this description is to ensure that the team shares a common understanding about the implementation and to outline the design to anyone else interested in the internal workings of the package.

Actions and objects

This section describes the different actions and objects used throughout the package.

Objects used in zen-do.
Object Description
deposit(s) A Zenodo deposit is the combined set of files and metadata that make up the content that will eventually form the published record.
record(s) A Zenodo record is a given published set of metadata and files for a specific DOI.
metadata The metadata for a deposit, kept within .zenodo.toml, see the Inputs page.
file(s) The files to add to a deposit.
format The file formats for the Zenodo metadata file(s) to convert between.
token The Zenodo personal access token to authenticate with the Zenodo API.
Actions used in zen-do.
Action Description
init Create an empty metadata file to be filled in.
list List all Zenodo deposits in an account.
get Get a Zenodo deposit in an account from a metadata file.
convert Convert metadata files to and from different formats.
update Updates an existing Zenodo deposit’s metadata only (not file) based on the contents of a metadata file.
publish Publish a new Zenodo record from an existing or new Zenodo deposit based on the metadata file and, if given, updating the file(s) in the deposit.
discard Discard a draft of or update to a Zenodo deposit (but not record).

C4 Models

This section contains diagrams for zen-do that are inspired by the C4 Model. The C4 Model is an established visualisation approach to describe the architecture of a software system. It breaks the system down into four levels of architectural abstraction: system context, containers, components, and code. For zen-do, we only use diagrams that are similar to the context and container models.

System context

The system context diagram shows the users and external systems that interact with zen-do. The users provide zen-do with the metadata file, the file or files to add to a Zenodo deposit, and the token for the Zenodo account.

flowchart TB
    user("User<br>[person]"):::user
    metadata[/"Metadata file<br>['.zenodo.toml']"/]
    metadata_formats("Metadata formats<br>[e.g. 'cff', 'json',<br>'toml', 'yml']")
    deposit("Deposit<br>[Zenodo server]"):::external
    record("Record<br>[Zenodo server]"):::external
    file[/"File<br>[e.g. PDF]"/]
    token[/"Token<br>[authentication]"/]
    zen_do["zen-do<br>[CLI]"]

    user -->|edit| metadata
    user -->|provide| token
    metadata -->|read| zen_do
    metadata <-.->|convert| metadata_formats
    token --> zen_do
    zen_do -->|convert| metadata_formats
    file -->|add| zen_do
    user --> file
    zen_do -->|publish<br>update<br>discard<br>list<br>get| deposit
    deposit -.->|publish| record

    %% Styling
    classDef user fill:#FFFFFF,color:#000000;
    classDef external fill:#F5F5F5;
Figure 1: Diagram showing the interaction between user and external systems that zen-do interacts with. The parallogram boxes represent input, the rectangle represents the CLI, and the rounded boxes represent the start and end points of the flow. The gray boxes represent external systems, in this case, the Zenodo server.

Container/component

In C4, a container diagram zooms in on the system boundary to show the containers within it while a component diagram is “a grouping of related functionality encapsulated behind a well-defined interface”, like a class or a module. For zen-do, we have a single container (the CLI) so we combine the container and component diagrams into one. The diagram below shows the main actions and objects within zen-do, how they interact with each other at a high level, and the technologies used for each.

flowchart TB
    user("User<br>[person]"):::user

    subgraph input ["Input"]
        metadata[/"Metadata file<br>['.zenodo.toml']"/]
        file[/"File<br>[e.g. PDF]"/]
        token[/"Token<br>[authentication]"/]
    end

    subgraph zen-do
        init["init<br>[Rust]"]
        get["get<br>[Rust]"]
        list["list<br>[Rust]"]
        convert["convert<br>[Rust]"]
        update["update<br>[Rust]"]
        publish["publish<br>[Rust]"]
        discard["discard<br>[Rust]"]
        deposit[/"Deposit<br>[Zenodo server]"/]:::external
        account[/"Account<br>[Zenodo server]"/]:::external

        update & discard & publish -->|request| deposit
        get & list -->|request| account
    end

    subgraph output ["Output"]
        record("Record<br>[Zenodo server]"):::external
        metadata_formats("Metadata formats<br>[e.g. 'cff', 'json',<br>'toml', 'yml']")
        empty_metadata("Empty metadata file<br>['.zenodo.toml']")
        deposit_get("Deposit<br>[JSON]")
        deposits_list("List of deposits<br>[JSON]")
    end

    deposit -.->|publish| record
    account -->|response| deposit_get
    account -->|response| deposits_list
    convert --> metadata_formats
    init -->|create| empty_metadata
    user --> input
    token -->|required<br>except init<br>and convert| zen-do
    metadata -->|required<br>except init<br>and list| zen-do
    file -->|required| publish

    %% Styling
    style zen-do fill:#FFFFFF,color:#000000;
    style output fill:#FFFFFF,color:#000000;
    style input fill:#FFFFFF,color:#000000;
    classDef user fill:#FFFFFF,color:#000000;
    classDef external fill:#F5F5F5;
Figure 2: Diagram showing the inputs, outputs, and actions within zen-do. Parallogram boxes represent input and output, the rectangles represents actions, and the rounded boxes represent the start and end points of the flow. The gray boxes represent external systems, in this case, the Zenodo server.