social.dracome.library.defs

dracome.social

{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "acquisitionType": {
      "description": "How an actor came to own a specific book edition, tracked on a `library.acquisition` record.",
      "knownValues": [
        "review_copy",
        "purchased",
        "gift",
        "giveaway",
        "subscription",
        "other"
      ],
      "type": "string"
    },
    "audioProgress": {
      "description": "Position marker for time-based audio progress.",
      "properties": {
        "positionSeconds": {
          "description": "Playback position in seconds reached as of this progress entry.",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "positionSeconds"
      ],
      "type": "object"
    },
    "audioTargetCustomization": {
      "description": "User-confirmed customization for an audio target. Runtime validation MUST require at least one of durationSeconds or chapterTotal. Both may be populated at once: an audiobook edition can carry an independent chapter total alongside its duration total.",
      "properties": {
        "chapterTotal": {
          "description": "User-confirmed total chapter count for this audiobook target, independent of durationSeconds — set when the actor tracks progress by chapter instead of (or in addition to) audio position.",
          "minimum": 1,
          "type": "integer"
        },
        "durationSeconds": {
          "description": "Total audio duration in seconds, as confirmed by the actor.",
          "minimum": 1,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "catalogTargetCustomization": {
      "description": "User-confirmed target-scoped customization that overrides catalog totals for this actor. Runtime validation MUST require exactly one of book, audiobook, manga, or comic to be populated, chosen based on the edition's actual tracking modality rather than a literal workType lookup: for most workType values this is book (paginated); narrated audio recordings of any workType use audiobook (audio_drama itself is a comparatively rare workType, not the common case for this payload); manga and comic each use their own respective payload, since comic is a distinct workType. The format-appropriate shape always takes precedence over workType since audio recordings of any work type need audio-shaped tracking.",
      "properties": {
        "audiobook": {
          "description": "Customization payload for a target tracked with audio-duration progress. Most commonly used for narrated audio recordings of any workType (e.g. an audiobook edition of a novel) — audio_drama is a comparatively rare workType value, not the common case, but always uses this same shape.",
          "ref": "#audioTargetCustomization",
          "type": "ref"
        },
        "book": {
          "description": "Customization payload for a target tracked with paginated (page or chapter) progress, most commonly used for novel, poetry, non_fiction, and other text-first workType values.",
          "ref": "#paginatedTargetCustomization",
          "type": "ref"
        },
        "comic": {
          "description": "Customization payload for a target tracked with comic-style chapter progress, used for comic workType values. Comic is a distinct workType from manga (not a subset or synonym of it), even though both share the same chapter-based payload shape.",
          "ref": "#paginatedTargetCustomization",
          "type": "ref"
        },
        "manga": {
          "description": "Customization payload for a target tracked with manga-style chapter progress, used for manga workType values.",
          "ref": "#paginatedTargetCustomization",
          "type": "ref"
        },
        "workType": {
          "description": "Structural content form of the targeted work, carried here for context. It informs, but does not literally select, which of book, audiobook, manga, or comic is populated below: the populated payload MUST match the edition's actual tracking modality (page/chapter-based, audio-duration-based, or manga/comic-chapter-based), not a literal workType lookup. For example, an audiobook recording of a novel still has workType novel while needing the audiobook-shaped payload; audio_drama itself is a comparatively rare workType value even though it always needs the same audiobook-shaped payload.",
          "ref": "social.dracome.work.defs#workType",
          "type": "ref"
        }
      },
      "required": [
        "workType"
      ],
      "type": "object"
    },
    "chapterProgress": {
      "description": "Position marker for chapter-based reading progress.",
      "properties": {
        "position": {
          "description": "One-based chapter number reached as of this progress entry.",
          "minimum": 1,
          "type": "integer"
        }
      },
      "required": [
        "position"
      ],
      "type": "object"
    },
    "goalFormatScope": {
      "description": "The format category a `library.goal` record's `formatScope` restricts fulfillment counting to. Resolved to specific `social.dracome.work.defs#editionFormat` values at read time.",
      "knownValues": [
        "physical",
        "digital",
        "audiobook"
      ],
      "type": "string"
    },
    "goalMetric": {
      "description": "The consumption metric a `library.goal` record targets. Fulfillment for every value is computed at read time by filtering the actor's `library.state` records that both fall within the goal's period and have status `completed`; each value differs only in what it sums/counts from that filtered set. `completed_state_count`: count of completed `library.state` records within the period. `page_count_sum`: aggregate page total of those completed records, sourcing each record's page count from `catalogSnapshot.edition.pageCount`, or from the record's own `catalogTargetCustomization` page-total override when the actor set a more accurate figure. `duration_seconds_sum`: aggregate duration in seconds of those completed records, sourcing each record's duration from `catalogSnapshot.edition.durationSeconds`, or from the record's own `catalogTargetCustomization` audiobook duration override when the actor set a more accurate figure.",
      "knownValues": [
        "completed_state_count",
        "page_count_sum",
        "duration_seconds_sum"
      ],
      "type": "string"
    },
    "pageProgress": {
      "description": "Position marker for page-based reading progress.",
      "properties": {
        "position": {
          "description": "Zero-based page position reached as of this progress entry.",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "position"
      ],
      "type": "object"
    },
    "paginatedTargetCustomization": {
      "description": "User-confirmed totals for paginated works. Runtime validation MUST require at least one of pageTotal or chapterTotal.",
      "properties": {
        "chapterTotal": {
          "description": "User-confirmed total chapter count for this work or edition, overriding catalog data when the actor knows a more accurate figure.",
          "minimum": 1,
          "type": "integer"
        },
        "pageTotal": {
          "description": "User-confirmed total page count for this work or edition, overriding catalog data when the actor knows a more accurate figure.",
          "minimum": 1,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "percentageProgress": {
      "description": "Position marker for percentage-based reading progress.",
      "properties": {
        "percentage": {
          "description": "Percentage of the work completed as of this progress entry, from 0 to 100.",
          "maximum": 100,
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "percentage"
      ],
      "type": "object"
    },
    "progressLogEntry": {
      "description": "Runtime validation SHOULD require at least one of page, percentage, chapter, or audio to be present.",
      "properties": {
        "audio": {
          "description": "Audio-based progress recorded for this day, present when the actor tracks by listening time.",
          "ref": "#audioProgress",
          "type": "ref"
        },
        "chapter": {
          "description": "Chapter-based progress recorded for this day, present when the actor tracks by chapter.",
          "ref": "#chapterProgress",
          "type": "ref"
        },
        "date": {
          "description": "Canonical UTC instant for the progress entry day, serialized as ISO 8601 with a trailing Z suffix. At most one entry per UTC calendar day should exist in the log. Frontend clients may localize this for presentation only.",
          "format": "datetime",
          "type": "string"
        },
        "page": {
          "description": "Page-based progress recorded for this day, present when the actor tracks by page.",
          "ref": "#pageProgress",
          "type": "ref"
        },
        "percentage": {
          "description": "Percentage-based progress recorded for this day, present when the actor tracks by percentage.",
          "ref": "#percentageProgress",
          "type": "ref"
        }
      },
      "required": [
        "date"
      ],
      "type": "object"
    },
    "trackingProgress": {
      "description": "An actor's progress on a work or edition, expressed either as text-based (page, chapter, or percentage) or audio-based (elapsed time) tracking.",
      "properties": {
        "kind": {
          "description": "Progress dimension. text = page, chapter, or percentage tracking; audio = time-based tracking. Mirrors the workType medium but stays independent of it.",
          "knownValues": [
            "text",
            "audio"
          ],
          "type": "string"
        },
        "log": {
          "description": "Ordered progress log, oldest entry first. At most one entry per UTC calendar day should be stored. Capped at 2000 entries: writers drop the oldest entries when the cap is reached.",
          "items": {
            "ref": "#progressLogEntry",
            "type": "ref"
          },
          "maxLength": 2000,
          "type": "array"
        }
      },
      "required": [
        "kind"
      ],
      "type": "object"
    },
    "trackingStatus": {
      "description": "Current reading-state status for a work or edition, from initial intent through completion or abandonment.",
      "enum": [
        "wishlist",
        "backlog",
        "in_progress",
        "paused",
        "completed",
        "abandoned"
      ],
      "type": "string"
    }
  },
  "id": "social.dracome.library.defs",
  "lexicon": 1
}

Validate Record

Validate a record against social.dracome.library.defs

Validation Options
Automatically resolve and include external schemas for full validation
Treat any remaining unresolved references as valid

Metadata

DID
did:plc:66dyrt2bmghwlmdteyizs5l3
CID
bafyreidrlryn2rhnr7lucprp667pjqeq2cdgzefiqrv5pcmlkl7lq5ipoe
Indexed At
2026-10-14 19:42 UTC
AT-URI
at://did:plc:66dyrt2bmghwlmdteyizs5l3/com.atproto.lexicon.schema/social.dracome.library.defs

Version History (2 versions)

Referenced Schemas (1)

Similar Lexicons

Lexicons whose schemas describe something close to this one. Check them before publishing a new one that overlaps.

  • social.dracome.library.state recordnot from the namespace authority

    A reading-state record for one edition per actor. Duplicate convention: the rkey is a TID minted once at first create and never changes. Several records may exist for one actor and edition (for example from out-of-band …

  • social.dracome.library.goal recordnot from the namespace authority

    A repeatable consumption-goal record for an actor, targeting a metric over a half-open time period `[periodStart, periodEnd)` (periodStart is inclusive, periodEnd is exclusive). Fulfillment progress against the goal is …

Lexicon Garden

@