Data Contracts

Data-Contracts.md

Data Contracts

Big Rule

runtime data lives under /data.

repo intent:

  • /data is not supposed to be versioned normally
  • .gitignore ignores /data/**/*
  • .rsyncignore excludes /data/** from deployment sync

so local/dev/prod data has to be managed separately.

data/accounts/

accounts.json

expected top-level shape:

{
  "accounts": [
    {
      "username": "string",
      "name": "string",
      "password": "bcrypt-hash or empty",
      "isAdmin": true,
      "allowedPages": ["feed", "journal"],
      "bookmarks": ["2026-01-01_12-00-00", "journal:12"],
      "glowIntensity": "none|low|medium|high",
      "mobileFriendlyView": true,
      "colors": {
        "bg": "#RRGGBB",
        "fg": "#RRGGBB",
        "border": "#RRGGBB",
        "subtle": "#RRGGBB",
        "links": "#RRGGBB"
      }
    }
  ]
}

notes:

  • extra unknown keys can exist and are preserved by account/admin/edit
  • bookmarks are the current source of truth for logged-in users

login_attempts.json

  • map of client IP -> unix timestamp array
  • used for login throttling

data/feed/

feed post format:

  1. @username
  2. YYYY-MM-DD HH:MM:SS
  3. body text / BBCode

other file:

  • index.toml is generated by /feed/index.php

data/journal/

published journal post:

  1. YYYY-MM-DD
  2. title
  3. description
  4. trusted HTML body

draft format:

  1. USER:<username>
  2. title
  3. description
  4. optional FORMAT:html
  5. draft body

without FORMAT:html, preview treats the body as BBCode. with it, preview treats the body as raw HTML.

data/guestbook/

entry format:

  1. timestamp
  2. display name
  3. message body

plus:

  • ip_index.json for one-post-per-IP ownership tracking

data/images/

  • uploaded images used across feed, journal, gallery, and newsletter content
  • expected web path is /data/images/<filename>

data/music/

artist folders currently include:

  • frdg3
  • cactile

album JSON shape:

{
  "album_name": "string",
  "album_caption": "string",
  "album_type": "Album|EP|Single|Remix|...",
  "album_art": "/data/images/example.jpg",
  "album_art_directory": "/data/images/example.jpg",
  "order": 6,
  "songs": [
    { "name": "Track", "directory": "/data/audio/file.wav" }
  ]
}

album_art_directory is preferred by current code.

data/audio/

  • track files referenced by music metadata
  • also used by shared playback features

data/newsletter/

  • published newsletter bodies as {id}.html
  • commonly date-shaped ids like YYYY-MM-DD

data/etc/

wip

  • plain text maintenance flag

webhooks.json

used key:

{
  "discord_feed": "https://discord.com/api/webhooks/..."
}

toast.json

expected shape:

{
  "bot": { "token": "...", "client_id": "...", "status": "online|offline" },
  "stream": { "url": "http(s)://...", "name": "..." },
  "channel": { "id": "...", "name": "..." },
  "features": { "auto_play": true, "loop": true }
}

toast-updates.json

  • array of timestamped bot status entries

off-topic-archive.json

  • Discord export blob used by the archive viewer

page_views.json

shape is roughly:

{
  "pages": {
    "/": {
      "count": 12,
      "visitors": {
        "<sha256>": 1730931224
      }
    }
  },
  "updated_at": "2026-03-02T00:00:00Z"
}

data/downloads/

  • downloadable binaries, archives, presets, and similar files linked from the site