Data catalog

Every dataset behind the Wardrobe Diary: what it holds, who can read it, where it comes from and how good it is. Licence: CC BY 4.0.

Semantic layer version 0.2.1 (2026-10-16) · JSON-LD · source (YAML) · CC BY 4.0

Data quality

The rules the data must meet. The results below are computed in your browser from the public data when the page loads, with the same code that checks the data every night.

Checking…

RuleDatasetRequirementSeverityResult
unique-idsGarmentsEvery garment id is unique.error–
known-categoryGarmentsEvery category is one of the 13 standard categories.error–
dates-orderedGarmentspurchased ≤ divested when both are set.error–
non-negativeGarmentsprice ≥ 0, timesUsedInit ≥ 0, weightG > 0 when set.error–
known-tagsGarmentsEvery tag is in the vocabulary.error–
worn-existsWear logEvery worn id is an existing garment.error–
wears-in-ownershipWear logWears fall within the garment's ownership period. Known exceptions are ignored by the metrics (Q-9).warning–
public-matches-sourcePublic wardrobe dataThe public copy equals garments + days + comparison.error–
materials-coverageGarmentsShare of active garments with a weight and readable materials (reported, no threshold).info–

Datasets

Classification: public readable by anyone (published by choice) · owner-only only the signed-in owner · private not exposed by the app. All data describes one identifiable person, who publishes the public parts by choice.

Garments owner-only

Every garment owned at some point since tracking began, with its details. The source of truth for garment details (decision D-4).

Where
Firestore users/{uid}/garments/{garmentId}
Contract
ODCS data contract
Represents
Garment
Published via
Public wardrobe data
Lineage
from Google Sheet (retired): Sheet → Firestore migration and sync (until 2026-10-09) – D-4
from owner: edited in the app (/manage) (since 2026-10-09)
FieldTypeRequiredDefinitionConstraints
idtextyesGarment id, from the original Sheet's Photo id (e.g. Jackets_and_hoodies-006); also the photo file name.pattern <Category_words>-NNN; unique
categorytextyesThe garment's category. (Category)one of the 13 standard categories
itemtextyesName (brand, model, colour; numbered when identical items exist).
detailstextFree-text details such as size or model code.
phototextyesPhoto file name without .png in public storage.
photoVersiontextSet when the photo is replaced; part of the photo URL so caches show the new one.
pricemoney-eurWhat was paid, rounded to whole cents. (Price)≥ 0
purchaseddatePurchase date.≤ divested
divesteddateLast day owned; empty while active. (Divested)
timesUsedInitintegeryesWears before tracking began (estimate). (Pre-tracking wears)≥ 0
materialstextThe materials label as written. (Materials)
weightGmass-gWeight in grams.> 0
tagslist of textDescriptive tags. (Tag)each one of: second-hand, hanko, bicycle, motorcycle, winter, summer
detailsUnavailablebooleanDivested only: missing materials or weight can no longer be filled in (left off the review list).

Garment history owner-only

Every saved version of every garment (an audit trail), including the version before each change.

Where
Firestore users/{uid}/garments/{garmentId}/history/{autoId}
Contract
ODCS data contract
Lineage
from Garments: written in the same transaction as each garment save
FieldTypeRequiredDefinitionConstraints
savedAttimestampyesWhen the version was saved.
beforegarmentThe previous version; empty when the garment was created in the app.
aftergarmentyesThe saved version.
notetextWhat happened, e.g. "Photo replaced".

Deleted garments owner-only

Garments deleted in the app (only never-worn ones can be), kept as a record.

Where
Firestore users/{uid}/deletedGarments/{garmentId}
Contract
ODCS data contract
FieldTypeRequiredDefinitionConstraints
deletedAttimestampyesWhen it was deleted.
garmentgarmentyesThe garment as it was.

Wear log owner-only

One record per day with wears - the garments worn that day. Days with nothing worn have no record.

Where
Firestore users/{uid}/days/{YYYY-MM-DD}
Contract
ODCS data contract
Represents
Wear day
Published via
Public wardrobe data
Lineage
from Google Sheet (retired): daily checkbox columns, migrated (until 2026-10-09)
from owner: logged in the app (/log) (since 2026-10-10) – R-15
FieldTypeRequiredDefinitionConstraints
datedateyesThe day (document id).≥ 2018-01-01; not in the future
wornlist of garment idsyesThe garments worn that day.each an existing garment id; no duplicates

Settings owner-only

App settings, e.g. settings/app.sheetRetired, the cut-over date after which the retired Sheet may no longer be synced.

Where
Firestore users/{uid}/settings/app
Contract
ODCS data contract
FieldTypeRequiredDefinitionConstraints
sheetRetireddateCut-over date (2026-10-09).

Comparison items owner-only

Other everyday spending shown next to the clothing categories in the monthly cost chart.

Where
Firestore users/{uid}/settings/comparison (items)
Contract
ODCS data contract
Represents
Comparison item
Published via
Public wardrobe data
Lineage
from Google Sheet (retired): one-off import of the Comparison tab (values only) (until 2026-10-12)
from owner: edited in the app (/manage/comparison) (since 2026-10-12)
FieldTypeRequiredDefinitionConstraints
idtextyesItem id (from its name).
typetextKind of spending, e.g. Content, Physical service.
itemtextyesName.
detailstextFree-text details.
phototextPhoto file name (Comparison-<Name>) without .png; empty when none.
photoVersiontextSet when a photo is uploaded.
monthlyCostmoney-euryesMonthly cost (entered).≥ 0
useFrequencyshareyesShare of days used (entered). (Use frequency)0–1

Public wardrobe data public

The world-readable copy for public pages and the MCP server: all garments, the full day-by-day log (as indexes into the garment list) and the comparison items, in one document, so any metric can be computed for any range with one read (decision D-1).

Where
Firestore users/{uid}/public/data
Contract
ODCS data contract
Access
Firestore REST (JSON): firestore.googleapis.com/v1/projects/threddit-297417/databas…
web app: wardrobediary.io/dashboard
MCP server: mcp/ (local; public server planned, R-29 phase 2)
Lineage
from Garments, Wear log, Comparison items: updated in the same write as every change in the app (transactions / batches) – D-1
FieldTypeRequiredDefinitionConstraints
versionintegeryesFormat version (1).
garmentslist of garmentyesAll garments with all their fields (same as dataset garments).
daysmap date → list of integeryesThe wear log as positions in the garments list.
comparisonlist of comparison itemThe comparison items.

Photos public

Garment photos (228 × 228 PNG), category images and comparison photos.

Where
Firebase Storage bucket threddit-297417.appspot.com

Nightly backups private

A full JSON export of garments (with history), days, deleted garments and settings, every night, with git history keeping every day.

Where
private GitHub repository hoverfalt/wardrobe-diary-backups (wardrobe.json); local backups/ folder
Updated
daily at 02:17 UTC
Lineage
from Garments, Garment history, Wear log, Deleted garments, Settings: tools/backup.py with a read-only service account – R-28

Google Sheet (retired) private retired

The original data entry, 2018-01-01 to 2026-10-09 - one row per garment, one checkbox column per day. Retired at the cut-over; kept read-only for reference.

Where
Google Sheet 1IQgCth6qPDHv_mqh8wSg9MaphLPR5dlTv0pi2QgAJLM, tab Threddit (and Comparison)