Add Mermaid system, components and container diagrams#2222
Add Mermaid system, components and container diagrams#2222gildub wants to merge 4 commits intoguacsec:mainfrom
Conversation
Reviewer's GuideAdds a new Mermaid-based UML classDiagram documenting the Trustify data model, including entities, relationships, and key design patterns for PURLs, SBOMs, relationships, statuses, versions, and licensing. ER diagram for core Trustify data modelerDiagram
advisory {
UUID id
UUID issuer_id
timestamp published
timestamp modified
timestamp withdrawn
String identifier
String title
String version
String document_id
jsonb labels
UUID source_document_id
bool deprecated
}
vulnerability {
String id
String title
timestamp published
timestamp modified
timestamp withdrawn
timestamp reserved
text[] cwes
}
advisory_vulnerability {
UUID advisory_id
String vulnerability_id
String title
String summary
String description
timestamp discovery_date
timestamp release_date
timestamp reserved_date
text[] cwes
}
sbom {
UUID sbom_id
String node_id
String document_id
timestamp published
String[] authors
jsonb labels
UUID source_document_id
text[] data_licenses
}
product {
UUID id
UUID vendor_id
String name
String cpe_key
}
product_version {
UUID id
UUID product_id
UUID sbom_id
String version
timestamp timestamp
}
base_purl {
UUID id
timestamp timestamp
String type
String namespace
String name
}
versioned_purl {
UUID id
UUID base_purl_id
String version
timestamp timestamp
}
qualified_purl {
UUID id
UUID versioned_purl_id
jsonb qualifiers
jsonb purl
timestamp timestamp
}
status {
UUID id
String slug
String name
String description
}
purl_status {
UUID id
UUID advisory_id
UUID status_id
UUID base_purl_id
UUID version_range_id
String vulnerability_id
UUID context_cpe_id
}
product_status {
UUID id
UUID advisory_id
String vulnerability_id
UUID status_id
UUID product_version_range_id
UUID context_cpe_id
String package
}
license {
UUID id
String text
text[] spdx_licenses
text[] spdx_license_exceptions
}
purl_license_assertion {
UUID id
UUID license_id
UUID sbom_id
UUID versioned_purl_id
}
cpe_license_assertion {
UUID id
UUID license_id
UUID sbom_id
UUID cpe_id
}
cpe {
UUID id
String part
String vendor
String product
String version
String update
String edition
String language
String sw_edition
String target_sw
String target_hw
String other
}
advisory ||--o{ advisory_vulnerability : has
vulnerability ||--o{ advisory_vulnerability : reported_in
product ||--o{ product_version : has
product_version }o--|| sbom : documented_by
base_purl ||--o{ versioned_purl : has_versions
versioned_purl ||--o{ qualified_purl : has_qualifiers
advisory ||--o{ purl_status : affects
advisory ||--o{ product_status : affects
status ||--o{ purl_status : classifies
status ||--o{ product_status : classifies
license ||--o{ purl_license_assertion : asserted_for
license ||--o{ cpe_license_assertion : asserted_for
purl_license_assertion }o--|| versioned_purl : applies_to
purl_license_assertion }o--|| sbom : in_context
cpe_license_assertion }o--|| cpe : applies_to
cpe_license_assertion }o--|| sbom : in_context
Class diagram for PURL hierarchy and license assertionsclassDiagram
class base_purl {
+UUID id
+timestamp timestamp
+String type
+String namespace
+String name
}
class versioned_purl {
+UUID id
+UUID base_purl_id
+String version
+timestamp timestamp
}
class qualified_purl {
+UUID id
+UUID versioned_purl_id
+jsonb qualifiers
+jsonb purl
+timestamp timestamp
}
class sbom {
+UUID sbom_id
+String node_id
+String document_id
+timestamp published
+String[] authors
+jsonb labels
+UUID source_document_id
+text[] data_licenses
}
class sbom_package {
+UUID sbom_id
+String node_id
+String version
}
class sbom_package_purl_ref {
+UUID sbom_id
+String node_id
+UUID qualified_purl_id
}
class cpe {
+UUID id
+String part
+String vendor
+String product
+String version
+String update
+String edition
+String language
+String sw_edition
+String target_sw
+String target_hw
+String other
}
class sbom_package_cpe_ref {
+UUID sbom_id
+String node_id
+UUID cpe_id
}
class license {
+UUID id
+String text
+text[] spdx_licenses
+text[] spdx_license_exceptions
}
class purl_license_assertion {
+UUID id
+UUID license_id
+UUID sbom_id
+UUID versioned_purl_id
}
class cpe_license_assertion {
+UUID id
+UUID license_id
+UUID sbom_id
+UUID cpe_id
}
%% PURL hierarchy
base_purl "1" --> "*" versioned_purl : has_versions
versioned_purl "1" --> "*" qualified_purl : has_qualifiers
%% SBOM package references
sbom "1" --> "*" sbom_package : contains
sbom_package "1" --> "*" sbom_package_purl_ref : has
sbom_package "1" --> "*" sbom_package_cpe_ref : has
%% CPE relations
cpe "1" --> "*" sbom_package_cpe_ref : referenced_in
cpe "1" --> "*" cpe_license_assertion : has
%% License assertions
license "1" --> "*" purl_license_assertion : asserted_for
license "1" --> "*" cpe_license_assertion : asserted_for
purl_license_assertion "*" --> "1" versioned_purl : applies_to
purl_license_assertion "*" --> "1" sbom : in_context
cpe_license_assertion "*" --> "1" sbom : in_context
Class diagram for advisory, vulnerability, product, and status modelclassDiagram
class advisory {
+UUID id
+UUID issuer_id
+timestamp published
+timestamp modified
+timestamp withdrawn
+String identifier
+String title
+String version
+String document_id
+jsonb labels
+UUID source_document_id
+bool deprecated
}
class advisory_vulnerability {
+UUID advisory_id
+String vulnerability_id
+String title
+String summary
+String description
+timestamp discovery_date
+timestamp release_date
+timestamp reserved_date
+text[] cwes
}
class vulnerability {
+String id
+String title
+timestamp published
+timestamp modified
+timestamp withdrawn
+timestamp reserved
+text[] cwes
}
class vulnerability_description {
+UUID id
+String vulnerability_id
+UUID advisory_id
+String lang
+String description
+timestamp timestamp
}
class weakness {
+text id
+text description
+text extended_description
+text[] child_of
+text[] parent_of
+text[] starts_with
+text[] can_follow
+text[] can_precede
+text[] required_by
+text[] requires
+text[] can_also_be
+text[] peer_of
}
class cvss3 {
+int minor_version
+UUID advisory_id
+String vulnerability_id
+cvss3_av av
+cvss3_ac ac
+cvss3_pr pr
+cvss3_ui ui
+cvss3_s s
+cvss3_c c
+cvss3_i i
+cvss3_a a
+double score
+cvss3_severity severity
}
class cvss4 {
+int minor_version
+UUID advisory_id
+String vulnerability_id
+cvss4_av av
+cvss4_ac ac
+cvss4_at at
+cvss4_pr pr
+cvss4_ui ui
+cvss4_vc vc
+cvss4_vi vi
+cvss4_va va
+cvss4_sc sc
+cvss4_si si
+cvss4_sa sa
}
class organization {
+UUID id
+String name
+String cpe_key
+String website
}
class product {
+UUID id
+UUID vendor_id
+String name
+String cpe_key
}
class product_version {
+UUID id
+UUID product_id
+UUID sbom_id
+String version
+timestamp timestamp
}
class product_version_range {
+UUID id
+UUID product_id
+UUID version_range_id
+String cpe_key
}
class status {
+UUID id
+String slug
+String name
+String description
}
class purl_status {
+UUID id
+UUID advisory_id
+UUID status_id
+UUID base_purl_id
+UUID version_range_id
+String vulnerability_id
+UUID context_cpe_id
}
class product_status {
+UUID id
+UUID advisory_id
+String vulnerability_id
+UUID status_id
+UUID product_version_range_id
+UUID context_cpe_id
+String package
}
class version_range {
+UUID id
+String version_scheme_id
+String low_version
+bool low_inclusive
+String high_version
+bool high_inclusive
}
class version_scheme {
+String id
+String name
+String description
}
class base_purl {
+UUID id
+timestamp timestamp
+String type
+String namespace
+String name
}
class cpe {
+UUID id
+String part
+String vendor
+String product
+String version
+String update
+String edition
+String language
+String sw_edition
+String target_sw
+String target_hw
+String other
}
class sbom {
+UUID sbom_id
+String node_id
+String document_id
+timestamp published
+String[] authors
+jsonb labels
+UUID source_document_id
+text[] data_licenses
}
%% Advisory and vulnerability relations
advisory "1" --> "*" advisory_vulnerability : has
advisory "1" --> "*" cvss3 : has_scores
advisory "1" --> "*" cvss4 : has_scores
advisory "1" --> "*" purl_status : affects
advisory "1" --> "*" product_status : affects
advisory "1" --> "*" vulnerability_description : has
vulnerability "1" --> "*" advisory_vulnerability : reported_in
vulnerability "1" --> "*" vulnerability_description : has
vulnerability "1" --> "*" cvss3 : has_scores
vulnerability "1" --> "*" cvss4 : has_scores
weakness "1" --> "*" vulnerability : categorizes
%% Product hierarchy
organization "1" --> "*" product : owns
product "1" --> "*" product_version : has
product "1" --> "*" product_version_range : has
product_version "*" --> "0..1" sbom : documented_by
product_version_range "*" --> "1" version_range : uses
%% Status tracking
purl_status "*" --> "1" base_purl : applies_to
purl_status "*" --> "1" status : has
purl_status "*" --> "1" advisory : from
purl_status "*" --> "1" version_range : version_constraint
purl_status "*" --> "0..1" cpe : context
product_status "*" --> "1" status : has
product_status "*" --> "1" advisory : from
product_status "*" --> "1" product_version_range : applies_to
product_status "*" --> "0..1" cpe : context
%% Version scheme
version_range "*" --> "1" version_scheme : uses_scheme
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- Consider adding a short legend/section explaining the meaning of the data types used in the diagram (e.g., String vs text vs jsonb, timestamp vs timestamptz) so that readers can more easily map them to the actual database types and semantics.
- Some entities mix String-based identifiers and UUID-based identifiers for
idfields (e.g.,vulnerability.idas String vs most others as UUID); it may help to briefly call out where String IDs represent external identifiers (like CVE IDs) to avoid confusion with internal primary keys.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider adding a short legend/section explaining the meaning of the data types used in the diagram (e.g., String vs text vs jsonb, timestamp vs timestamptz) so that readers can more easily map them to the actual database types and semantics.
- Some entities mix String-based identifiers and UUID-based identifiers for `id` fields (e.g., `vulnerability.id` as String vs most others as UUID); it may help to briefly call out where String IDs represent external identifiers (like CVE IDs) to avoid confusion with internal primary keys.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2222 +/- ##
==========================================
+ Coverage 69.22% 69.24% +0.01%
==========================================
Files 414 414
Lines 23304 23304
Branches 23304 23304
==========================================
+ Hits 16132 16136 +4
+ Misses 6262 6252 -10
- Partials 910 916 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Wouldn't an ER diagram be a better fit for this? Also, why does it have another diagram as PNG? And how do we ensure this stays in sync? Which tool was used to create this? Can the resolution be enhanced. |
You're right, I've changed it to an ER diagram. This was actually an intermediary stage as I had to create the domain model (added now) by reverse engineer the data model.
Having diagrams exported as a png files provides extra visualization options offering flexibility to communicate about the project. |
7537a59 to
a8ac001
Compare
5d6d8f0 to
6c5567c
Compare
|
Thanks for explaining this. I still don't see the benefit of having the (quite small) PNG, compared to the complexity it adds. And the problems when things go out of alignment. I think it's easy enough to view the diagram on GitHub, and at least in IntelliJ too. I'd assume VScode has something similar. So which case would require having this PNG? |
|
The PNG (or SVG, JPEG) are definitely optional and I understand everyone might have different needs to use them or not. I removed the images and let's keep only the instruction for anyone to generate them if needed. |
Could it be that you forgot to push those changes, as they still seem to be part of the PR. |
|
Just to understand the process, whenever we do changes in the codebase, how to we update these diagrams? |
6c5567c to
49372a2
Compare
|
@ctron, sorry I missed the change, now the generated images are removed. Regarding the process of updating the diagrams, I believe that should be initiated from a new ADR. |
49372a2 to
58ae3a3
Compare
Yes, how would that relate to the folder https://github.com/guacsec/trustify/blob/main/docs/design/ |
|
nice content 👍 |
The design/README.md articulates together the design information of the Trustify project using Mermaid providing diagram as code with the following :
mermaid-clitool in order to regenerate images (PNG, SVG or PDF) along with the default theme and scale parameters.