docs/ADRs/0003.vertex-and-edge-ids.md
# Vertex and Edge IDs
| author | created at | updated at | status |
|:-------------|:-----------|------------|:---------|
| @gabor-boros | 2023-03-16 | - | accepted |
## Abstract
The database of choice for the project is Neo4j. Neo4j is a graph database, and
it is a good fit for the project, because project management is basically about
managing a bunch of interconnected objects.
However, there are some things we need to consider when working with Neo4j:
* The ID of vertices and edges generated by Neo4j are meant to be used only
internally by the database. Furthermore, IDs of generated by Neo4j _may_ be
reused by the database upon need after deleting its previous owner.
Therefore, we need to generate our own IDs for the vertices and edges, and
use them in the application.
* The database is schemaless, which means that we can't use the database to
validate the data we are storing. We need to validate the data in the
application.
This ADR describes how we are going to generate IDs for vertices and edges. For
more about schema validation, see the [Database Schema Validation] ADR.
[Database Schema Validation]: 0004.database-schema-validation.md
## Decision
To make our lives easier on the long run, we are setting common properties for
all vertices and edges on the database level with only one caveat: languages[^1]
references. One of these properties is the ID property. The ID must be a
unique, URL-friendly string. Although we could use UUIDs, we decided to use
[xid], because it is shorter, configuration-free, and sortable.
Xid is dependent on the system time, a monotonic counter and so is not
cryptographically secure. This is not a problem, because we don't need it to be
cryptographically secure. We just need it to be unique, and to be sortable.
The IDs will be generated by the application as Neo4j is not able to generate
them for us.
[xid]: https://github.com/rs/xid
[^1]: We are skipping ID creation for languages as those are the sole nodes
that are uniquely identified by their name, and we don't need to generate
IDs for them.
## Consequences
As a consequence of this decision, we need to generate IDs for vertices and
edges on our own, and set them as properties. This brings us the advantage of
being able to identify vertices and edges by their IDs, even if other
properties are the same.
On the other hand, we need to make sure to assign the ID for every vertex and
edge upon creation, which should be part of the repository layer.
## References
* [Neo4j](https://neo4j.com/)
* [Software Architecture](0001.software-architecture.md)