The project
My wardrobe data
Glossary
Model
Data
AI evaluation
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…
Rule Dataset Requirement Severity Result
unique-idsGarments Every garment id is unique. error –
known-categoryGarments Every category is one of the 13 standard categories. error –
dates-orderedGarments purchased ≤ divested when both are set. error –
non-negativeGarments price ≥ 0, timesUsedInit ≥ 0, weightG > 0 when set. error –
known-tagsGarments Every tag is in the vocabulary. error –
worn-existsWear log Every worn id is an existing garment. error –
wears-in-ownershipWear log Wears fall within the garment's ownership period. Known exceptions are ignored by the metrics (Q-9). warning –
public-matches-sourcePublic wardrobe data The public copy equals garments + days + comparison. error –
materials-coverageGarments Share 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)
Field Type Required Definition Constraints
idtext yes Garment id, from the original Sheet's Photo id (e.g. Jackets_and_hoodies-006); also the photo file name. pattern <Category_words>-NNN; unique
categorytext yes The garment's category. (Category ) one of the 13 standard categories
itemtext yes Name (brand, model, colour; numbered when identical items exist).
detailstext Free-text details such as size or model code.
phototext yes Photo file name without .png in public storage.
photoVersiontext Set when the photo is replaced; part of the photo URL so caches show the new one.
pricemoney-eur What was paid, rounded to whole cents. (Price ) ≥ 0
purchaseddate Purchase date. ≤ divested
divesteddate Last day owned; empty while active. (Divested )
timesUsedInitinteger yes Wears before tracking began (estimate). (Pre-tracking wears ) ≥ 0
materialstext The materials label as written. (Materials )
weightGmass-g Weight in grams. > 0
tagslist of text Descriptive tags. (Tag ) each one of: second-hand, hanko, bicycle, motorcycle, winter, summer
detailsUnavailableboolean Divested 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
Field Type Required Definition Constraints
savedAttimestamp yes When the version was saved.
beforegarment The previous version; empty when the garment was created in the app.
aftergarment yes The saved version.
notetext What 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
Field Type Required Definition Constraints
deletedAttimestamp yes When it was deleted.
garmentgarment yes The 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
Field Type Required Definition Constraints
datedate yes The day (document id). ≥ 2018-01-01; not in the future
wornlist of garment ids yes The 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
Field Type Required Definition Constraints
sheetRetireddate Cut-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)
Field Type Required Definition Constraints
idtext yes Item id (from its name).
typetext Kind of spending, e.g. Content, Physical service.
itemtext yes Name.
detailstext Free-text details.
phototext Photo file name (Comparison-<Name>) without .png; empty when none.
photoVersiontext Set when a photo is uploaded.
monthlyCostmoney-eur yes Monthly cost (entered). ≥ 0
useFrequencyshare yes Share 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
Field Type Required Definition Constraints
versioninteger yes Format version (1).
garmentslist of garment yes All garments with all their fields (same as dataset garments).
daysmap date → list of integer yes The wear log as positions in the garments list.
comparisonlist of comparison item The 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)
Generated from the semantic layer ,
which tests keep in line with the app's code. © Olof Hoverfält, CC BY 4.0.