{
  "lexicon": 1,
  "id": "net.bisks.postwith.profile",
  "defs": {
    "main": {
      "type": "record",
      "description": "A person's standing entry in the postwith matching pool: one topic they want to be matched on, a goal, and optionally a note and a city. Singleton per repo — re-posting overwrites the previous profile in place (the client calls putRecord with rkey \"self\"). Deleted (via deleteRecord) when someone leaves the pool. Written and read by postwith (https://postwith.bisks.net).",
      "key": "literal:self",
      "record": {
        "type": "object",
        "required": ["topic", "goal", "createdAt"],
        "properties": {
          "topic": {
            "type": "string",
            "maxLength": 60,
            "knownValues": ["mentoring", "gaming", "foodie", "fitness", "books", "music", "career", "creative", "code", "coffee"],
            "description": "The topic id this person wants to be matched on, e.g. \"gaming\". Chosen from a fixed in-UI dropdown (listed as knownValues, not a strict enum, since the app's topic list is a plain in-code array that could grow without a lexicon change)."
          },
          "goal": {
            "type": "string",
            "maxLength": 960,
            "maxGraphemes": 240,
            "description": "What this person wants out of a match, e.g. \"find a co-founder\". Required non-empty by the UI. Bound matches the input's maxlength=240 (characters)."
          },
          "note": {
            "type": "string",
            "maxLength": 960,
            "maxGraphemes": 240,
            "description": "Optional free-text note shown alongside the goal. Always written as a (possibly empty) string by the client rather than omitted. Bound matches the textarea's maxlength=240."
          },
          "location": {
            "type": "string",
            "maxLength": 240,
            "maxGraphemes": 60,
            "description": "Optional city/location string used to surface nearby matches first. Always written as a (possibly empty) string by the client rather than omitted. Bound matches the input's maxlength=60."
          },
          "createdAt": {
            "type": "string",
            "format": "datetime",
            "description": "When this profile was last written (post or update), as an ISO 8601 datetime. Not renamed to updatedAt even though putRecord may be overwriting an existing profile."
          }
        }
      }
    }
  }
}
