Claude-skill-registry crop-data

Crop planning data model and architecture. Use when working with crops.json, bed-plan.json, TimelineCrop, or plan data structures for: (1) Understanding entity relationships (Crop → PlantingConfig → Planting → Product), (2) Determining which fields are static inputs vs calculated, (3) Identifying which entity a field belongs to (crop, product, planting, or config-level), (4) Planning data migrations or implementing the slim data architecture, (5) Modifying timeline or explorer components that consume crop data. (project)

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/crop-data" ~/.claude/skills/majiayu000-claude-skill-registry-crop-data && rm -rf "$T"
manifest: skills/data/crop-data/SKILL.md
source content

Crop Data Context

This skill provides essential context for working with the crop planning data model.

CRITICAL: Data Analysis Caveats

The extracted analysis files have known gaps:

FileIssue
column-analysis.json
Misclassifies array formulas as "static" or "mixed"
formula-analysis.json
Missing ~20+ formulas using SWITCH, complex XLOOKUP

Always verify against the actual workbook using:

python scripts/inspect-column.py "STH"           # Inspect specific column
python scripts/inspect-column.py --list          # List all columns
python scripts/inspect-column.py "DTM" --sheet "Bed Plan"

Authoritative reference:

vba/workbook-structure.md
has table schemas extracted directly from Excel.

Key Timing Formulas (FROM WORKBOOK)

STH (Seed To Harvest) - NOT static, despite what analysis files say:

SWITCH(Normal Method,
  "DS": Days to Germination + DTM + IF(Days in Cells > 0, 15, 0)
  "TP": DTM + Days in Cells + IF(Days in Cells <= 0, 20, 0)
  "X":  DTM
)

DTM - Calculated from range:

=FLOOR.MATH(AVERAGE(DTM Lower, DTM Upper))

Days in Cells - Sum of tray stages:

=SUM(Tray 1 Days, Tray 2 Days, Tray 3 Days)

Target dates:

  • Target Sewing Date = LastFrostDate - 5 * Sewing Rel Last Frost
  • Target Field Date = Target Sewing Date + Days in Cells
  • Target Harvest Data = Target Sewing Date + STH
  • Target End of Harvest = Target Harvest Data + Harvest window

Entity Model

GLOBAL CONSTANTS (farm settings: LastFrostDate, BedLength, LaborRate)
       │
       ▼
CROP (~100 unique) ─────────────────────────────────────────────────┐
│ name, category, deprecated                                        │
│ Same for all configurations of a crop                             │
       │                                                            │
       │ one crop → many configurations                             │
       ▼                                                            │
PLANTING CONFIGURATION (340 total)                                  │
│ structure (Field/Hoop/Greenhouse)                                 │
│ method (DS/TP), season (Sp/Su/Fa/Wi/Ow)                          │
│ product type, DTM, spacing, rows                                  │
│ Identifier: "Arugula - Baby Leaf | Field DS Sp"                  │
       │                                    │                       │
       │ one config → many plantings        │ references            │
       ▼                                    ▼                       │
PLANTING (per-plan instance)          PRODUCT (processing info) ◄──┘
│ bed, bedsCount, startDate           │ Unit, Price, Yield
│ per-planting overrides              │ Wash type, labor times
│ actual vs planned dates (future)    │ Holding period

Data Source Files

FileSizeContentsNotes
src/data/crops.json
1.7 MB340 configs × ~155 fieldsFat export, includes calculated
src/data/bed-plan.json
170 KB~138 plantingsCurrent plan assignments
src/data/products.json
213 KBProduct processing dataLabor times, packaging
column-analysis.json
46 KBField classificationHas gaps - verify!
formula-analysis.json
29 KBFormula DAGMissing array formulas!
vba/workbook-structure.md
-Table schemasAuthoritative reference

Planting Override Fields

These bed-plan fields modify catalog values per-planting:

Override FieldModifiesPurpose
additionalDaysInField
STH/DTMWeather, conditions adjustment
additionalDaysOfHarvest
Harvest windowExtended/shortened season
additionalDaysInCells
Days in CellsGreenhouse timing adjustment

Computation pattern:

const effectiveDTM = catalog.STH + planting.additionalDaysInField;
const effectiveHarvestWindow = catalog.harvestWindow + planting.additionalDaysOfHarvest;

Timeline Date Computation

The timeline uses these inputs to compute dates:

From Catalog (crops.json):

  • STH
    - Total days from seeding to first harvest
  • Harvest window
    - Days of harvest period
  • Days in Cells
    - Greenhouse time (0 = direct seed)

From Planting (bed-plan.json):

  • fixedFieldStartDate
    - The target transplant/direct-seed date
  • additionalDays*
    - Per-planting adjustments

Computed:

startDate = fixedFieldStartDate (the TP/DS date)
harvestStartDate = startDate + (STH - daysInCells) = startDate + DTM
endDate = harvestStartDate + harvestWindow

Finding Things

Run from

crop-api/
directory. Use patterns (not file paths) to locate code:

# Entity types (new canonical location)
node scripts/ast-query.js "Plan"           # What does Plan contain?
node scripts/ast-query.js "Planting"       # What does Planting contain?
node scripts/ast-query.js "CropConfig"     # What does CropConfig contain?

# Find type definitions
grep -r "^export interface" src/lib/entities/

# Find calculation functions
grep -r "^export function calculate" src/lib

# Find what uses entities
grep -r "from.*entities" src/lib --include="*.ts"

# Find bed length logic
grep -r "lengthFt\|ROW_LENGTHS" src/lib

# Find plan store actions
grep -r "^  [a-z]*:" src/lib/plan-store.ts | head -30

Data Extraction

Re-extract from Excel when workbook changes (run from

crop-api/
):

python scripts/extract-products.py

Testing & Verification

Run from

crop-api/
:

npx tsx scripts/test-entities.ts        # Entity validation
npx tsx scripts/test-slim-planting.ts   # Date computation parity
npx tsx scripts/test-catalog-parity.ts  # Catalog lookup parity
npx tsx scripts/test-crop-calculations.ts  # Crop calc vs Excel

# Inspect actual Excel formulas
python scripts/inspect-column.py "STH"
python scripts/inspect-column.py --list

Architecture

New canonical types live in

lib/entities/
:

  • Bed
    - bed with
    lengthFt
    (F/J=20, A-E/G-I/U=50, X=80)
  • Planting
    - one per planting, references
    configId
  • CropConfig
    - planting configuration with calculations
  • Plan
    - self-contained: owns
    beds
    ,
    cropCatalog
    ,
    plantings

Key principle: Plans own their data. No external references.

// What we store
interface Plan {
  beds: Record<string, Bed>;           // Plan's bed layout
  cropCatalog: Record<string, CropConfig>;  // Plan's crop configs
  plantings: Planting[];               // One per planting decision
}

// Computed at render time
const timing = calculateCropTiming(planting, config);
const bedSpan = calculateBedSpan(planting.bedFeet, planting.startBed, plan.beds);

See

.claude/plans/state-migration.md
for full migration plan.