---
title: "C4 Models"
---

This section contains the [C4 Models](https://c4model.com/) for Sprout.
The C4 Model is an established visualization approach to describe the
architecture of a software system. It breaks the system down into four
levels of architectural abstraction: Context, Containers, Components,
and Code. The last level is rarely used nor recommended for most
software architecture since it is used to visualize a high degree of
detail that most projects don't need. For our case, we only needed to
create the **Context** and **Containers** diagrams.

These diagrams and their content draw from our overall Seedcase [design
documentation](https://design.seedcase-project.org/) and [design
decisions](https://decisions.seedcase-project.org/). See those websites
for more information.

## Context

The Context diagram shows the users and any external systems that
interact with Sprout. This includes the user roles described in the
[User Personas](user-personas.qmd#user-types) page.

::: callout-caution
For some reason, these diagrams don't display well on some browsers like
Firefox. To see them, try using a different browser like Chrome or Edge.
:::

```{mermaid}
%%| label: fig-c4-context
%%| fig-width: 6.3
%%| fig-cap: "C4 Context diagram showing a very basic overview of Sprout and its anticipated users."
flowchart LR
    user_owner(["Owner/creator<br>[person]<br><br>Creates and owns a<br>project that generates<br>data. Uses Sprout<br>for more control."])
    user_admin(["Administrator<br>[person]<br><br>Manages data and<br>metadata from a<br>project for an owner.<br>Uses Sprout for<br>more control."])
    user_swe(["Software engineer<br>[person]<br><br>Creates and develops<br>data infrastructure.<br>Uses Sprout to<br>build extensions and<br>customizations."])
    user_de(["Data engineer<br>[person]<br><br>Develops data pipelines<br>and infrastructures.<br>Uses Sprout to<br>build and customize<br>the pipelines."])
    sprout["Seedcase Sprout<br>[system]<br><br>Allows users fine-<br>grained control over<br>building, managing,<br>and structuring data<br>in a way that makes<br>it easier to share<br>with collaborators<br>and to analyze.<br>Structures data<br>following the<br>Frictionless Data<br>Package Standard."]
    output[("Filesystem (local or server)<br>[system]<br><br>Structured data from<br>Sprout that is stored<br>in a filesystem for<br>later use. This can<br>be on a server or<br>on a local, personal<br>computer, depending<br>on the privacy of<br>the data.")]

    user_swe --> sprout:::system
    user_de --> sprout
    user_admin --> sprout
    user_owner --> sprout
    sprout --> output:::external

    classDef system stroke-width:4pt
    classDef external fill:lightgrey
```

## Container

The Container diagram shows the larger parts of the system, what they
are responsible for, and how they interact with each other. It also
shows the technology choices for each container.

```{mermaid}
%%| label: fig-c4-container
%%| fig-width: 6.3
%%| fig-cap: "C4 Container diagram showing larger functional parts of Sprout and their connections."
flowchart TB
    user(["User<br>[person]"])
    subgraph sprout [Sprout]
        package["Data package functions<br>[Python]<br><br>Create, manage, and check a data package<br>and its 'properties' (metadata)."]
        resource["Data resource functions<br>[Python]<br><br>Create, manage, and check data resources<br>and their 'properties' (metadata) in a<br>data package."]
        obs_unit["Observational unit functions<br>[Python]<br><br>Manage and delete observational units<br>in a resource. An observational unit<br>is an entity with data collected at a<br>specific time. Necessary for<br>GDPR-compliance."]
        batch[("Batch data<br>[Parquet]")]
        data[("Data<br>[Parquet]")]
        metadata[["Metadata ('properties')<br>[Frictionless Standard, JSON]"]]
    end
    output[("Filesystem<br><br>Stored data and metadata on a local or server filesystem.")]

    user --> sprout:::system
    package --> metadata
    resource --> data
    resource --> metadata
    obs_unit --> batch
    resource --> batch
    sprout --> output:::external

    classDef system fill:none
    classDef external fill:lightgrey
```
