Data schema
All tracker data is stored as JSON inside a postpartum-tracker fenced code block. This page documents the complete schema.
PostpartumData (top level)
Section titled “PostpartumData (top level)”interface PostpartumData { /** Schema version for future migrations (currently 1) */ version: number;
/** Baby metadata */ meta: { babyName?: string; birthDate?: string; // ISO 8601 date birthWeight?: number; // Grams unitSystem?: 'metric' | 'imperial'; };
/** Ordered list of module IDs for section layout */ layout: string[];
/** Entry arrays keyed by module ID */ trackers: { feeding?: FeedingEntry[]; diaper?: DiaperEntry[]; medication?: MedicationEntry[]; medicationConfig?: MedicationConfig[]; comments?: LogNoteEntry[]; // Notes & comments tracker logNotes?: LogNoteEntry[]; [key: string]: unknown; // Library tracker entries };
/** Optional per-code-block settings overrides */ settingsOverrides?: Partial<PostpartumTrackerSettings>;
/** Active logic pack ID (overrides global setting for this block) */ logicPackId?: string;}The [key: string]: unknown index signature means any library tracker can store its entries without schema changes.
FeedingEntry
Section titled “FeedingEntry”interface FeedingEntry { id: string; type: 'breast' | 'bottle' | 'solid'; side?: 'left' | 'right' | 'both'; position?: 'cradle' | 'cross-cradle' | 'football' | 'side-lying' | 'laid-back'; start: string; // ISO 8601 end: string | null; // null = actively feeding durationSec?: number; // Cached for completed entries volumeMl?: number; // For bottle feeding notes: string;}DiaperEntry
Section titled “DiaperEntry”interface DiaperEntry { id: string; timestamp: string; // ISO 8601 wet: boolean; dirty: boolean; color?: DiaperColor; description: string; notes: string;}
type DiaperColor = | 'meconium' // Black/dark green (days 1-2) | 'transitional' // Dark green to brown (days 3-4) | 'yellow-seedy' // Normal breastfed (day 4+) | 'green' // Foremilk/hindmilk imbalance | 'brown' // Normal formula-fed | 'other';MedicationEntry
Section titled “MedicationEntry”interface MedicationEntry { id: string; name: string; // 'Tylenol', 'Ibuprofen', or custom dosage?: string; // '500mg', '200mg' timestamp: string; // ISO 8601 notes: string;}MedicationConfig
Section titled “MedicationConfig”Stored per code block in trackers.medicationConfig (copied from plugin settings on creation):
interface MedicationConfig { name: string; technicalName?: string; // Generic name (e.g., 'Acetaminophen') dosage: string; minIntervalHours: number; // Min hours between doses maxDailyDoses: number; // Max per 24h (0 = unlimited) enabled: boolean; icon: string; category?: 'medication' | 'remedy'; // Remedy = topical (cream, spray, ice)}The category field distinguishes oral medications (medication) from topical treatments (remedy). Remedies like nipple cream or ice packs may have no max daily limit and are excluded from alternating schedule logic.
SimpleTrackerEntry
Section titled “SimpleTrackerEntry”Used by all library tracker modules:
interface SimpleTrackerEntry { id: string; timestamp: string; // ISO 8601 end?: string | null; // For duration trackers durationSec?: number; // Calculated on stop fields: Record<string, string | number | boolean>; notes: string;}The fields object contains key-value pairs matching the field definitions in the tracker’s SimpleTrackerDef.
LogNoteEntry
Section titled “LogNoteEntry”General-purpose notes. Used by both the legacy logNotes slot and the comments tracker (trackers.comments):
interface LogNoteEntry { id: string; timestamp: string; // ISO 8601 category: string; text: string;}Layout
Section titled “Layout”The layout array controls the order of sections in the widget:
["feeding", "diaper", "medication", "sleep", "mood", "event-history"]Module IDs not in the layout array appear after the listed ones, sorted by defaultOrder. Module IDs in the layout that aren’t enabled are silently skipped.
The special ID event-history controls the position of the unified event history feed. It can be reordered among module sections like any other entry. If not present in the array, the event history section appears at the end (if enabled in settings).
Logic packs
Section titled “Logic packs”Logic packs define expected milestones and thresholds by day of life. The logicPackId field on the code block overrides the global setting.
Built-in pack IDs:
first-week-newborn— AAP-based first week expectations (diapers, feedings, stool color)postpartum-recovery— Mother’s recovery milestones (pain, bowel movements, walking)breastfeeding-establishment— Feeding frequency targets for the first 8 weeks
Each pack contains milestone rules evaluated against actual tracker data:
interface MilestoneRule { moduleId: string; // Which tracker module ('diaper', 'feeding', etc.) field: string; // '_count', '_count_wet', '_count_dirty', '_duration_avg', or a field key fromDay: number; // Start day of life (0 = birth day) toDay: number; // End day of life expect: { min?: number; // Minimum expected value max?: number; // Maximum expected value values?: string[]; // Expected string values (e.g., ['yellow-seedy']) perPeriod?: 'day' | '24h'; // Count per day vs cumulative }; alertLevel: 'info' | 'warning' | 'urgent'; description: string; onTrackMessage?: string; // Shown when the expectation IS met}Version
Section titled “Version”Currently 1. The version field exists for future schema migrations. The parser applies backward-compatible defaults for any missing fields.
Example
Section titled “Example”A minimal code block with one feeding entry:
{ "version": 1, "meta": { "babyName": "Luna", "birthDate": "2026-02-15" }, "layout": ["feeding", "diaper", "medication"], "trackers": { "feeding": [ { "id": "f1a2b3c4", "type": "breast", "side": "left", "start": "2026-03-04T08:30:00.000Z", "end": "2026-03-04T08:45:00.000Z", "durationSec": 900, "notes": "" } ], "diaper": [], "medication": [], "medicationConfig": [], "logNotes": [] }}