Skip to content

AdametherzLab/egg-tracker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CI TypeScript License: MIT

🥚 egg-tracker

✨ Features

  • Daily tracking — Record counts per coop and breed with strict date validation
  • Smart averages — Calculate weekly, monthly, or custom rolling averages
  • Drop detection — Automatically flag when production falls below expected thresholds
  • Seasonal insights — Analyze patterns across months to optimize flock management
  • Zero dependencies — Pure TypeScript with strict types, runs on Bun or Node.js 20+

📦 Installation

npm install @adametherzlab/egg-tracker
# or
bun add @adametherzlab/egg-tracker

🚀 Quick Start

// REMOVED external import: import { createTracker } from "@adametherzlab/egg-tracker";

const tracker = createTracker();

// Record today's haul
tracker.addEntry({
  date: "2024-01-15",
  coopId: "main-coop",
  breed: "Rhode Island Red",
  count: 5
});

// Get weekly average
const weekly = tracker.calculateAverage({ 
  coopId: "main-coop", 
  days: 7 
});

console.log(`Average: ${weekly.count} eggs/day`);

📚 API Reference

createTracker()

function createTracker(): Tracker

Returns: Tracker — A new tracker instance with empty state.

Example:

const tracker = createTracker();

Tracker Methods

addEntry(entry)

addEntry(entry: EggEntry): void

Parameters:

  • entry — Object containing date (ISO string), coopId (string), breed (string), count (number)

Example:

tracker.addEntry({ 
  date: "2024-03-15", 
  coopId: "north-coop", 
  breed: "Leghorn", 
  count: 4 
});

removeEntry(date, coopId, breed)

removeEntry(date: string, coopId: CoopId, breed: BreedId): boolean

Returns: boolean — True if entry was found and removed.

Example:

const removed = tracker.removeEntry("2024-03-15", "north-coop", "Leghorn");

getEntries(options?)

getEntries(options?: QueryOptions): EggEntry[]

Parameters:

  • options.coopId — Filter by specific coop
  • options.breed — Filter by breed
  • options.startDate — Start of date range (ISO)
  • options.endDate — End of date range (ISO)

Example:

const marchEntries = tracker.getEntries({
  startDate: "2024-03-01",
  endDate: "2024-03-31",
  coopId: "main-coop"
});

getCoops()

getCoops(): CoopId[]

Example:

const coops: string[] = tracker.getCoops(); // ["main-coop", "north-coop"]

getBreeds(coopId?)

Returns all breed IDs, optionally filtered by coop.

getBreeds(coopId?: CoopId): BreedId[]

Example:

const allBreeds = tracker.getBreeds();
const coopBreeds = tracker.getBreeds("main-coop");

clearAll()

Wipes all data. Use with caution.

clearAll(): void

calculateAverage(options)

calculateAverage(options: { 
  coopId?: CoopId; 
  breed?: BreedId; 
  days: number;
  aggregation?: AggregationLevel;
}): AverageResult

Returns: AverageResult with count (number) and period (days).

Example:

const monthly = tracker.calculateAverage({ 
  coopId: "main-coop", 
  days: 30,
  aggregation: "daily"
});

detectProductionDrops(options)

Identifies significant production decreases.

detectProductionDrops(options: DropDetectionOptions): ProductionDrop[]

Parameters:

  • options.threshold — Percentage drop to flag (0-100)
  • options.windowDays — Comparison window size
  • options.minBaseline — Minimum eggs to consider (prevents false positives on empty coops)

Returns: Array of ProductionDrop objects with date, severity, and expected vs actual counts.

Example:

const drops = tracker.detectProductionDrops({
  threshold: 30,
  windowDays: 7,
  minBaseline: 3
});

analyzeSeasonalTrends()

analyzeSeasonalTrends(): SeasonalTrend[]

Returns: Array of trends showing average production per month with variance data.

Example:

const trends = tracker.analyzeSeasonalTrends();
// trends[0] = { month: 1, averageCount: 4.2, variance: 0.8 }

Type Shapes

EggEntry

interface EggEntry {
  readonly date: string;      // ISO 8601 date (YYYY-MM-DD)
  readonly coopId: CoopId;    // Coop identifier
  readonly breed: BreedId;    // Breed name
  readonly count: number;     // Eggs laid (0 or positive)
}

TrackerConfig

interface TrackerConfig {
  readonly dataDir?: string;  // Defaults to ~/.egg-tracker
  readonly maxEntries?: number;
}

DropDetectionOptions

interface DropDetectionOptions {
  readonly threshold: number;    // Percentage (0-100)
  readonly windowDays: number;   // Rolling window for baseline
  readonly minBaseline?: number; // Minimum eggs to trigger
}

DateRange

interface DateRange {
  readonly startDate: string;
  readonly endDate: string;
}

CoopConfig

interface CoopConfig {
  readonly id: CoopId;
  readonly capacity?: number;
  readonly establishedDate?: string;
}

ProductionDrop

interface ProductionDrop {
  readonly date: string;
  readonly coopId: CoopId;
  readonly breed: BreedId;
  readonly expectedCount: number;
  readonly actualCount: number;
  readonly severity: number; // Percentage drop
}

SeasonalTrend

interface SeasonalTrend {
  readonly month: number;        // 1-12
  readonly averageCount: number;
  readonly sampleSize: number;
  readonly variance: number;
}

AverageResult

interface AverageResult {
  readonly count: number;
  readonly period: number; // Days in calculation
}

QueryOptions

interface QueryOptions {
  readonly coopId?: CoopId;
  readonly breed?: BreedId;
  readonly startDate?: string;
  readonly endDate?: string;
}

BatchResult

interface BatchResult {
  readonly added: number;
  readonly errors: Array<{ entry: EggEntry; reason: string }>;
}

Type Aliases

type CoopId = string;
type BreedId = string;
type AggregationLevel = "daily" | "weekly" | "monthly";

🏗️ Advanced Usage

Running a multi-coop operation with automated health monitoring:

// REMOVED external import: import { createTracker, type EggEntry, type ProductionDrop } from "@adametherzlab/egg-tracker";

const tracker = createTracker();

// Batch import historical data
const historical: EggEntry[] = [
  { date: "2024-01-01", coopId: "coop-a", breed: "Orpington", count: 3 },
  { date: "2024-01-01", coopId: "coop-b", breed: "Sussex", count: 5 },
  // ... more entries
];

historical.forEach(entry => tracker.addEntry(entry));

// Detect health issues
const drops: ProductionDrop[] = tracker.detectProductionDrops({
  threshold: 40,      // Flag 40% or greater drops
  windowDays: 14,     // Compare against 2-week baseline
  minBaseline: 2      // Ignore if normally laying less than 2
});

if (drops.length > 0) {
  console.warn("Potential health issues detected:", drops);
}

// Plan for winter
const trends = tracker.analyzeSeasonalTrends();
const winterAvg = trends.find(t => t.month === 12)?.averageCount;
console.log(`December average: ${winterAvg} eggs/day`);

🤝 Contributing

See CONTRIBUTING.md

📄 License

MIT (c) AdametherzLab

About

Egg production tracker — daily counts, averages, trend detection

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors