Skip to content

Data Model

Parnian Hajian edited this page Apr 23, 2026 · 1 revision

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.


Pod Layout

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

DCAT Catalog (catalog.ttl)

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.


File Metadata (index.ttl)

Each file container holds an index.ttl document that describes the file using schema.org predicates.

Field Predicate Notes

Title

schema:name

Required, enforced by SHACL

Description

schema:description

Optional

Upload date

schema:uploadDate

Required, enforced by SHACL

Publisher

schema:publisher

Required, stores the uploader’s WebID URI

File type

rdf:type

schema.org class derived from MIME type (see below)

MIME type

schema:encodingFormat

Stored as-is from the file’s content type

File size

schema:contentSize

Byte count


Semantic Classification

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

image/*

schema:ImageObject

video/*

schema:VideoObject

audio/*

schema:AudioObject

text/*, application/pdf, Word documents

schema:TextDigitalDocument

CSV, Excel spreadsheets

schema:SpreadsheetDigitalDocument

Everything else

schema:DigitalDocument


Per-Contact Shared Catalogs

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.


ShEx Shapes

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

solidProfile.shex

A Solid WebID profile: name, avatar, contacts (foaf:knows), Pod storage root (pim:storage), and LDP inbox URI.

catalogEntry.shex

A DCAT catalog entry and index.ttl metadata document with all the fields listed in the table above.

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.

SHACL Validation

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.

Clone this wiki locally