-
Notifications
You must be signed in to change notification settings - Fork 0
Data Model
solid.drive stores everything directly on the user’s Solid Pod using standard RDF vocabularies. There is no application database; the Pod itself is the data store. This page documents the layout, the vocabularies used, and the validation layer that enforces metadata quality at upload time.
Every uploaded file gets its own dedicated LDP BasicContainer. A DCAT catalog at the storage root acts as a queryable index of all files, making the Pod’s contents discoverable by any Solid-aware application.
Pod storage root/
│
├── catalog.ttl ← DCAT catalog, one dcat:Dataset per uploaded file
│
└── my-solid-app/
├── .shared-<contact-webid>.ttl ← per-contact shared catalog (one per contact)
│
└── holiday-photo-2024-01-15/ ← one LDP BasicContainer per uploaded file
├── photo.jpg ← the binary
└── index.ttl ← schema.org metadata document
The catalog at the storage root is a DCAT dataset.
solid.drive appends a dcat:Dataset entry on every upload and removes it on every delete using SPARQL PATCH, so the catalog always reflects the current state of the Pod.
On the first upload, the catalog URI is linked to the user’s WebID profile. This makes the Pod’s contents discoverable by other Solid applications that can read the profile. The catalog is a first-class linked data resource, not a private internal index.
Each file container holds an index.ttl document that describes the file using schema.org predicates.
| Field | Predicate | Notes |
|---|---|---|
Title |
|
Required, enforced by SHACL |
Description |
|
Optional |
Upload date |
|
Required, enforced by SHACL |
Publisher |
|
Required, stores the uploader’s WebID URI |
File type |
|
schema.org class derived from MIME type (see below) |
MIME type |
|
Stored as-is from the file’s content type |
File size |
|
Byte count |
MIME types are mapped to schema.org classes and written to index.ttl as rdf:type.
This makes files semantically typed and filterable by any RDF-aware consumer.
| MIME type | schema.org class |
|---|---|
|
|
|
|
|
|
|
|
CSV, Excel spreadsheets |
|
Everything else |
|
When a file is shared with a contact, solid.drive writes a copy of its catalog entry into .shared-<contact-webid>.ttl inside my-solid-app/.
The .acl on this file restricts read access to that specific contact’s WebID, so other users cannot see it.
When access is revoked, the file entry is removed from the shared catalog and the ACL is updated. This design keeps sharing scoped and auditable: each contact gets their own catalog snapshot with no cross-contamination.
Shape definitions live in src/.shapes/ and are compiled to typed TypeScript bindings in src/.ldo/ by the LDO generator.
Never edit the files in src/.ldo/ directly. They are regenerated on every npm run build:ldo run.
| Shape file | What it describes |
|---|---|
|
A Solid WebID profile: name, avatar, contacts ( |
|
A DCAT catalog entry and |
After editing a .shex file, regenerate the bindings:
npm run build:ldo|
ℹ️
|
Shapes are intentionally minimal; they declare only the fields the application needs.
The EXTRA a flag in the profile shape allows profiles that carry unexpected rdf:type triples to pass validation.
This is necessary for compatibility across different Solid server implementations, which sometimes add their own type declarations to profile documents.
|
At upload time, solid.drive loads a SHACL TBox from public/tbox.ttl.
This file is generated by npm run tbox:extract, which fetches the latest constraint definitions from datashapes.org.
Before any data is written to the Pod, the app validates the user’s metadata against these constraints.
If required fields (name, uploadDate, publisher) are missing, the upload is blocked and the missing fields are highlighted inline in the form.
No partial or invalid metadata ever reaches the Pod.