meta/architecture-docs/panel-data-model.svg
cinereal 7d68f6fef8 add data model for the reference front-end (#31)
follows up from #31 to offer a data model focused on formalize to the point of incorporating any data attribute types to be stored in the `panel` db.

data model [requirements](https://git.fediversity.eu/Fediversity/meta/src/branch/main/architecture-docs/data-model-requirements.md):

- [x] specifying [entity relations](https://mermaid.js.org/syntax/entityRelationshipDiagram.html#relationship-syntax) e.g. many-to-many
- [x] migrating both deployed and staged configurations
- [x] deploying of applications using the same versions
- [x] retaining relevant application state
- handling of application-specific migration logic, such as to rewrite URLs as needed - note this requirement does not affect the model here, in the sense it is handled through code rather than through the database

closes Fediversity/Fediversity#103.

Reviewed-on: #31
Reviewed-by: Valentin Gagarin <valentin.gagarin@tweag.io>
Co-authored-by: cinereal <cinereal@riseup.net>
Co-committed-by: cinereal <cinereal@riseup.net>
2025-06-06 11:05:27 +02:00

1 line
No EOL
12 KiB
XML

<svg aria-roledescription="er" role="graphics-document document" viewBox="-60.156768798828125 -61 344.171875 686" style="max-width: 344.172px; background-color: transparent;" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="100%" id="my-svg"><style>#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#333333;stroke:#333333;}#my-svg .marker.cross{stroke:#333333;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .entityBox{fill:#ECECFF;stroke:#9370DB;}#my-svg .attributeBoxOdd{fill:#ffffff;stroke:#9370DB;}#my-svg .attributeBoxEven{fill:#f2f2f2;stroke:#9370DB;}#my-svg .relationshipLabelBox{fill:hsl(80, 100%, 96.2745098039%);opacity:0.7;background-color:hsl(80, 100%, 96.2745098039%);}#my-svg .relationshipLabelBox rect{opacity:0.5;}#my-svg .relationshipLine{stroke:#333333;}#my-svg .entityTitleText{text-anchor:middle;font-size:18px;fill:#333;}#my-svg #MD_PARENT_START{fill:#f5f5f5!important;stroke:#333333!important;stroke-width:1;}#my-svg #MD_PARENT_END{fill:#f5f5f5!important;stroke:#333333!important;stroke-width:1;}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g/><defs><marker orient="auto" markerHeight="240" markerWidth="190" refY="7" refX="0" id="MD_PARENT_START"><path d="M 18,7 L9,13 L1,7 L9,1 Z"/></marker></defs><defs><marker orient="auto" markerHeight="28" markerWidth="20" refY="7" refX="19" id="MD_PARENT_END"><path d="M 18,7 L9,13 L1,7 L9,1 Z"/></marker></defs><defs><marker orient="auto" markerHeight="18" markerWidth="18" refY="9" refX="0" id="ONLY_ONE_START"><path d="M9,0 L9,18 M15,0 L15,18" fill="none" stroke="gray"/></marker></defs><defs><marker orient="auto" markerHeight="18" markerWidth="18" refY="9" refX="18" id="ONLY_ONE_END"><path d="M3,0 L3,18 M9,0 L9,18" fill="none" stroke="gray"/></marker></defs><defs><marker orient="auto" markerHeight="18" markerWidth="30" refY="9" refX="0" id="ZERO_OR_ONE_START"><circle r="6" cy="9" cx="21" fill="white" stroke="gray"/><path d="M9,0 L9,18" fill="none" stroke="gray"/></marker></defs><defs><marker orient="auto" markerHeight="18" markerWidth="30" refY="9" refX="30" id="ZERO_OR_ONE_END"><circle r="6" cy="9" cx="9" fill="white" stroke="gray"/><path d="M21,0 L21,18" fill="none" stroke="gray"/></marker></defs><defs><marker orient="auto" markerHeight="36" markerWidth="45" refY="18" refX="18" id="ONE_OR_MORE_START"><path d="M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27" fill="none" stroke="gray"/></marker></defs><defs><marker orient="auto" markerHeight="36" markerWidth="45" refY="18" refX="27" id="ONE_OR_MORE_END"><path d="M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18" fill="none" stroke="gray"/></marker></defs><defs><marker orient="auto" markerHeight="36" markerWidth="57" refY="18" refX="18" id="ZERO_OR_MORE_START"><circle r="6" cy="18" cx="48" fill="white" stroke="gray"/><path d="M0,18 Q18,0 36,18 Q18,36 0,18" fill="none" stroke="gray"/></marker></defs><defs><marker orient="auto" markerHeight="36" markerWidth="57" refY="18" refX="39" id="ZERO_OR_MORE_END"><circle r="6" cy="18" cx="9" fill="white" stroke="gray"/><path d="M21,18 Q39,0 57,18 Q39,36 21,18" fill="none" stroke="gray"/></marker></defs><path style="stroke: gray; fill: none;" marker-start="url(#ONLY_ONE_START)" marker-end="url(#ZERO_OR_MORE_END)" d="M111.929,86L111.929,94.333C111.929,102.667,111.929,119.333,111.929,136C111.929,152.667,111.929,169.333,111.929,177.667L111.929,186" class="er relationshipLine"/><path style="stroke: gray; fill: none;" marker-start="url(#ONLY_ONE_START)" marker-end="url(#ZERO_OR_MORE_END)" d="M111.929,273L111.929,281.333C111.929,289.667,111.929,306.333,111.929,323C111.929,339.667,111.929,356.333,111.929,364.667L111.929,373" class="er relationshipLine"/><path style="stroke: gray; fill: none;" marker-start="url(#ONLY_ONE_START)" marker-end="url(#ONE_OR_MORE_END)" d="M111.929,439L111.929,447.333C111.929,455.667,111.929,472.333,111.929,489C111.929,505.667,111.929,522.333,111.929,530.667L111.929,539" class="er relationshipLine"/><g transform="translate(53.6265869140625,20 )" id="entity-operator-6c3c8122-d73d-5044-ae44-1ef3f93ceeda"><rect height="66" width="116.60519409179688" y="0" x="0" class="er entityBox"/><text style="dominant-baseline: middle; text-anchor: middle; font-size: 12px;" transform="translate(58.30259704589844,12)" y="0" x="0" id="text-entity-operator-6c3c8122-d73d-5044-ae44-1ef3f93ceeda" class="er entityLabel">operator</text><rect height="21" width="35.245819091796875" y="24" x="0" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,34.5)" y="0" x="0" id="text-entity-operator-6c3c8122-d73d-5044-ae44-1ef3f93ceeda-attr-1-type" class="er entityLabel">string</text><rect height="21" width="81.359375" y="24" x="35.245819091796875" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(40.245819091796875,34.5)" y="0" x="0" id="text-entity-operator-6c3c8122-d73d-5044-ae44-1ef3f93ceeda-attr-1-name" class="er entityLabel">username</text><rect height="21" width="35.245819091796875" y="45" x="0" class="er attributeBoxEven"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,55.5)" y="0" x="0" id="text-entity-operator-6c3c8122-d73d-5044-ae44-1ef3f93ceeda-attr-2-type" class="er entityLabel">string</text><rect height="21" width="81.359375" y="45" x="35.245819091796875" class="er attributeBoxEven"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(40.245819091796875,55.5)" y="0" x="0" id="text-entity-operator-6c3c8122-d73d-5044-ae44-1ef3f93ceeda-attr-2-name" class="er entityLabel">password_hash</text></g><g transform="translate(20,186 )" id="entity-deployment-6e8d4da4-7b9e-52d1-a6c4-135846840a1b"><rect height="87" width="183.85836791992188" y="0" x="0" class="er entityBox"/><text style="dominant-baseline: middle; text-anchor: middle; font-size: 12px;" transform="translate(91.92918395996094,12)" y="0" x="0" id="text-entity-deployment-6e8d4da4-7b9e-52d1-a6c4-135846840a1b" class="er entityLabel">deployment</text><rect height="21" width="68.49899291992188" y="24" x="0" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,34.5)" y="0" x="0" id="text-entity-deployment-6e8d4da4-7b9e-52d1-a6c4-135846840a1b-attr-1-type" class="er entityLabel">json</text><rect height="21" width="115.359375" y="24" x="68.49899291992188" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(73.49899291992188,34.5)" y="0" x="0" id="text-entity-deployment-6e8d4da4-7b9e-52d1-a6c4-135846840a1b-attr-1-name" class="er entityLabel">deployed_configuration</text><rect height="21" width="68.49899291992188" y="45" x="0" class="er attributeBoxEven"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,55.5)" y="0" x="0" id="text-entity-deployment-6e8d4da4-7b9e-52d1-a6c4-135846840a1b-attr-2-type" class="er entityLabel">option[string]</text><rect height="21" width="115.359375" y="45" x="68.49899291992188" class="er attributeBoxEven"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(73.49899291992188,55.5)" y="0" x="0" id="text-entity-deployment-6e8d4da4-7b9e-52d1-a6c4-135846840a1b-attr-2-name" class="er entityLabel">staged_configuration</text><rect height="21" width="68.49899291992188" y="66" x="0" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,76.5)" y="0" x="0" id="text-entity-deployment-6e8d4da4-7b9e-52d1-a6c4-135846840a1b-attr-3-type" class="er entityLabel">option[string]</text><rect height="21" width="115.359375" y="66" x="68.49899291992188" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(73.49899291992188,76.5)" y="0" x="0" id="text-entity-deployment-6e8d4da4-7b9e-52d1-a6c4-135846840a1b-attr-3-name" class="er entityLabel">version</text></g><g transform="translate(61.92918395996094,373 )" id="entity-backup-3e040283-ead5-539d-96e6-9b4dc06cda21"><rect height="66" width="100" y="0" x="0" class="er entityBox"/><text style="dominant-baseline: middle; text-anchor: middle; font-size: 12px;" transform="translate(50,12)" y="0" x="0" id="text-entity-backup-3e040283-ead5-539d-96e6-9b4dc06cda21" class="er entityLabel">back-up</text><rect height="21" width="42.99383544921875" y="24" x="0" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,34.5)" y="0" x="0" id="text-entity-backup-3e040283-ead5-539d-96e6-9b4dc06cda21-attr-1-type" class="er entityLabel">string</text><rect height="21" width="57.00616455078125" y="24" x="42.99383544921875" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(47.99383544921875,34.5)" y="0" x="0" id="text-entity-backup-3e040283-ead5-539d-96e6-9b4dc06cda21-attr-1-name" class="er entityLabel">bucket</text><rect height="21" width="42.99383544921875" y="45" x="0" class="er attributeBoxEven"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,55.5)" y="0" x="0" id="text-entity-backup-3e040283-ead5-539d-96e6-9b4dc06cda21-attr-2-type" class="er entityLabel">string</text><rect height="21" width="57.00616455078125" y="45" x="42.99383544921875" class="er attributeBoxEven"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(47.99383544921875,55.5)" y="0" x="0" id="text-entity-backup-3e040283-ead5-539d-96e6-9b4dc06cda21-attr-2-name" class="er entityLabel">endpoint</text></g><g transform="translate(61.92918395996094,539 )" id="entity-keypair-c4c6e66f-4864-5ca0-a719-2e65393232d1"><rect height="66" width="100" y="0" x="0" class="er entityBox"/><text style="dominant-baseline: middle; text-anchor: middle; font-size: 12px;" transform="translate(50,12)" y="0" x="0" id="text-entity-keypair-c4c6e66f-4864-5ca0-a719-2e65393232d1" class="er entityLabel">keypair</text><rect height="21" width="35.55693054199219" y="24" x="0" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,34.5)" y="0" x="0" id="text-entity-keypair-c4c6e66f-4864-5ca0-a719-2e65393232d1-attr-1-type" class="er entityLabel">string</text><rect height="21" width="64.44306945800781" y="24" x="35.55693054199219" class="er attributeBoxOdd"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(40.55693054199219,34.5)" y="0" x="0" id="text-entity-keypair-c4c6e66f-4864-5ca0-a719-2e65393232d1-attr-1-name" class="er entityLabel">access_key</text><rect height="21" width="35.55693054199219" y="45" x="0" class="er attributeBoxEven"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(5,55.5)" y="0" x="0" id="text-entity-keypair-c4c6e66f-4864-5ca0-a719-2e65393232d1-attr-2-type" class="er entityLabel">string</text><rect height="21" width="64.44306945800781" y="45" x="35.55693054199219" class="er attributeBoxEven"/><text style="dominant-baseline: middle; font-size: 10.2px;" transform="translate(40.55693054199219,55.5)" y="0" x="0" id="text-entity-keypair-c4c6e66f-4864-5ca0-a719-2e65393232d1-attr-2-name" class="er entityLabel">secret_key</text></g><rect height="14" width="19.359375" y="129" x="102.24931335449219" class="er relationshipLabelBox"/><text style="text-anchor: middle; dominant-baseline: middle; font-size: 12px;" y="136" x="111.92900085449219" id="rel1" class="er relationshipLabel">has</text><rect height="14" width="19.359375" y="316" x="102.24931335449219" class="er relationshipLabelBox"/><text style="text-anchor: middle; dominant-baseline: middle; font-size: 12px;" y="323" x="111.92900085449219" id="rel2" class="er relationshipLabel">has</text><rect height="14" width="55.375" y="482" x="84.24150085449219" class="er relationshipLabelBox"/><text style="text-anchor: middle; dominant-baseline: middle; font-size: 12px;" y="489" x="111.92900085449219" id="rel3" class="er relationshipLabel">authorises</text><text class="entityTitleText" y="-25" x="111.92918395996094" text-anchor="middle">Data model of sample web application</text></svg>