{
"id": "net.anisota.chronicle.expedition.camp",
"defs": {
"main": {
"key": "tid",
"type": "record",
"record": {
"type": "object",
"required": [
"expeditionRef",
"status",
"campedAt",
"reason",
"signature",
"createdAt"
],
"properties": {
"light": {
"ref": "#campLight",
"type": "ref"
},
"reason": {
"enum": [
"user_initiated",
"light_low",
"stamina_low",
"conditions_harsh"
],
"type": "string",
"description": "Why camp was made"
},
"status": {
"enum": [
"active",
"completed"
],
"type": "string",
"description": "Whether the camp is currently active or has been broken"
},
"brokeAt": {
"type": "string",
"format": "datetime",
"description": "When camp was broken (only set when status is 'completed')"
},
"campedAt": {
"type": "string",
"format": "datetime",
"description": "When camp was set up"
},
"duration": {
"type": "integer",
"minimum": 0,
"description": "Total camp duration in milliseconds (only set when status is 'completed')"
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "When the record was created"
},
"signature": {
"ref": "#chronicleSignature",
"type": "ref"
},
"updatedAt": {
"type": "string",
"format": "datetime",
"description": "When the record was last updated (set on break camp)"
},
"campNumber": {
"type": "integer",
"minimum": 1,
"description": "Sequential camp number within the parent expedition (1, 2, 3...). Combined with expeditionNumber gives e.g. Camp 2.1, Camp 2.3"
},
"conditions": {
"ref": "#campConditions",
"type": "ref"
},
"expeditionRef": {
"type": "string",
"format": "at-uri",
"description": "AT URI of the parent expedition record (net.anisota.chronicle.expedition)"
}
}
},
"description": "Camp record. Created when a user makes camp during an expedition. Updated when camp is broken. References the parent expedition record via AT URI."
},
"campLight": {
"type": "object",
"properties": {
"atCamp": {
"type": "integer",
"minimum": 0,
"description": "Light level when camp was made (in minutes)"
},
"atBreak": {
"type": "integer",
"minimum": 0,
"description": "Light level when camp was broken (in minutes)"
},
"regenerated": {
"type": "integer",
"minimum": 0,
"description": "Light regenerated during camp"
}
},
"description": "Light levels at camp start/end"
},
"campConditions": {
"type": "object",
"properties": {
"weather": {
"enum": [
"clear",
"overcast",
"rainy",
"stormy",
"foggy"
],
"type": "string",
"description": "Weather condition when camp was made"
},
"lightLevel": {
"enum": [
"dawn",
"morning",
"midday",
"afternoon",
"dusk",
"night",
"deepnight"
],
"type": "string",
"description": "Time-of-day light condition when camp was made"
}
},
"description": "Environmental conditions when camp was made"
},
"chronicleSignature": {
"type": "object",
"required": [
"sig",
"alg",
"kid",
"signedAt",
"nonce",
"version"
],
"properties": {
"alg": {
"type": "string",
"description": "Signing algorithm (ES256)"
},
"kid": {
"type": "string",
"description": "Key identifier for the signing key"
},
"sig": {
"type": "string",
"description": "Base64-encoded ES256 signature"
},
"nonce": {
"type": "string",
"description": "Unique random nonce to prevent replay"
},
"version": {
"type": "integer",
"description": "Signature schema version"
},
"signedAt": {
"type": "string",
"format": "datetime",
"description": "When the record was signed"
}
},
"description": "ES256 cryptographic signature proving record authenticity"
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1
}