From 9897e73de19b88f57beab8349c94d4ea54cdae7e Mon Sep 17 00:00:00 2001 From: fullsizemalt <106900403+fullsizemalt@users.noreply.github.com> Date: Fri, 12 Dec 2025 20:52:44 -0800 Subject: [PATCH] docs: add METRC integration specification - Clarifies METRC as source of truth - Defines data model with metrc fields - Feature overlap matrix (supplement vs add value) - UI integration points - Compliance alerts workflow - Implementation phases --- specs/metrc-integration.md | 451 +++++++++++++++++++++++++++++++++++++ 1 file changed, 451 insertions(+) create mode 100644 specs/metrc-integration.md diff --git a/specs/metrc-integration.md b/specs/metrc-integration.md new file mode 100644 index 0000000..6e3f3ed --- /dev/null +++ b/specs/metrc-integration.md @@ -0,0 +1,451 @@ +# METRC Integration Specification + +## Overview + +This document defines how CA Grow Ops Manager integrates with California's METRC (Metrc LLC) track-and-trace system. METRC compliance is **mandatory** for all licensed cannabis operations in California. + +> **Critical Note**: Our application is a **supplementary management tool** that works alongside METRC, NOT a replacement. All legally required data MUST be entered into METRC according to DCC regulations. + +--- + +## Integration Approach + +### Philosophy: METRC as Source of Truth + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ METRC (State System) │ +│ ═══ SOURCE OF TRUTH ═══ │ +│ • Official plant/package tracking │ +│ • State compliance reporting │ +│ • Manifests & transfers │ +│ • Required weight logs │ +└─────────────────────────────────────────────────────────────────────┘ + ▲ ▲ + SYNC ────┘ └──── SYNC + │ +┌─────────────────────────────────────────────────────────────────────┐ +│ CA Grow Ops Manager │ +│ ═══ OPERATIONAL LAYER ═══ │ +│ • Enhanced day-to-day management │ +│ • Photo documentation │ +│ • Staff scheduling & timekeeping │ +│ • IPM tracking & analytics │ +│ • SOPs & training │ +│ • Real-time environment monitoring │ +│ • Facility 3D visualization │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### Integration Levels + +| Level | Description | Implementation | +|-------|-------------|----------------| +| **L1: Reference** | Store METRC IDs for cross-reference | ✅ Implemented | +| **L2: Sync (Read)** | Pull data from METRC API | 🔄 Planned | +| **L3: Sync (Write)** | Push data to METRC API | 🔄 Planned | +| **L4: Real-time** | Live bi-directional sync | 🔮 Future | + +--- + +## Data Model: METRC Fields + +### Batch Model + +```prisma +model Batch { + // ... existing fields ... + + // METRC Integration + metrcPlantBatchId String? // METRC Plant Batch ID + metrcGroupId String? // METRC Group ID + metrcLicenseNumber String? // Source license + metrcSyncedAt DateTime? // Last sync timestamp + metrcSyncStatus METRCSyncStatus @default(NOT_SYNCED) +} + +enum METRCSyncStatus { + NOT_SYNCED + SYNCING + SYNCED + SYNC_ERROR + MANUAL_OVERRIDE +} +``` + +### Weight Log Model + +```prisma +model WeightLog { + // ... existing fields ... + + metrcHarvestId String? // METRC Harvest ID + metrcPackageId String? // METRC Package ID + metrcWasteId String? // METRC Waste event ID + metrcReported Boolean @default(false) + metrcReportedAt DateTime? +} +``` + +### Room Model + +```prisma +model Room { + // ... existing fields ... + + metrcLocationId String? // METRC Location ID + metrcLocationName String? // METRC Location Name +} +``` + +--- + +## Feature Overlap Matrix + +### Where We SUPPLEMENT METRC + +| Feature | METRC Does | We Do | Integration | +|---------|------------|-------|-------------| +| **Plant Tracking** | Official counts, tags | Daily observations, photos | Link via `metrcPlantBatchId` | +| **Weight Logging** | Legal wet/dry weights | Operational weights, notes | Push to METRC, store locally | +| **Transfers** | Manifests, chain of custody | Prep checklists, photos | Reference `metrcManifestId` | +| **Waste** | Waste disposal logging | Waste tracking triggers | Push to METRC on disposal | +| **Room Location** | Official location names | Visual layout, sensors | Link via `metrcLocationId` | + +### Where We ADD VALUE (Not in METRC) + +| Feature | What We Provide | +|---------|-----------------| +| **Daily Walkthroughs** | Structured inspections with photos | +| **IPM Schedules** | Preventive pest management tracking | +| **Touch Points** | Granular activity logging (feed, water, prune) | +| **Environment Data** | VPD, temperature, humidity trends | +| **Staff Management** | Time clock, task assignment | +| **SOPs & Training** | Document management, acknowledgments | +| **Visitor Management** | Check-in, NDA tracking | +| **3D Visualization** | Facility layout, sensor placement | +| **Financial Tracking** | Labor costs, supply expenses | +| **Analytics** | Yield predictions, efficiency reports | + +--- + +## METRC Data Mapping + +### Plant Batch → Our Batch + +```typescript +interface METRCPlantBatch { + Id: number; // → metrcPlantBatchId + Name: string; // → strain + batch code comparison + PlantCount: number; // → plantCount (validate) + RoomName: string; // → room.metrcLocationName + StrainName: string; // → strain + PlantedDate: string; // → startDate + TrackedDate: string; // Reference + GrowthPhase: string; // → stage mapping +} + +// Stage Mapping +const METRC_TO_STAGE = { + 'Immature': 'CLONE_IN', + 'Vegetative': 'VEGETATIVE', + 'Flowering': 'FLOWERING', + 'InactiveImmature': 'FINISHED', + 'InactiveVegetative': 'FINISHED', + 'InactiveFlowering': 'FINISHED', +}; +``` + +### Location → Our Room + +```typescript +interface METRCLocation { + Id: number; // → metrcLocationId + Name: string; // → metrcLocationName + LocationTypeName: string; // → type inference +} +``` + +### Harvest → Our Weight Log + +```typescript +interface METRCHarvest { + Id: number; // → metrcHarvestId + HarvestName: string; // Reference + WetWeight: number; // → weight (WET type) + DryWeight: number; // → weight (FINAL_DRY type) + UnitOfWeight: string; // → unit conversion + LabResultStatus: string; // → compliance status +} +``` + +--- + +## UI Integration Points + +### Batch Card + +```tsx + + + B007 + Zkittlez + {batch.metrcPlantBatchId && ( + + + METRC + + )} + + {batch.metrcSyncStatus === 'SYNC_ERROR' && ( + + METRC sync error - verify data in METRC portal + + )} + +``` + +### Weight Log Entry + +```tsx + + + + + + + + + ⚠️ METRC Reporting Required + + + This weight must be reported to METRC within 24 hours. + + + + +``` + +### Room Assignment + +```tsx + + ({ + value: r.id, + label: r.name, + metrc: r.metrcLocationName + }))} + /> + {selectedRoom?.metrcLocationId && ( + + METRC Location: {selectedRoom.metrcLocationName} + + )} + +``` + +--- + +## Sync Workflows + +### Daily Sync Routine (Planned) + +``` +06:00 AM - Pull overnight data from METRC + - Compare plant counts + - Flag discrepancies + +During Day - Local operations logged + - Touch points, weights, etc. + +11:00 PM - Generate METRC report summary + - Show items needing METRC entry + - Export CSV if supported +``` + +### Manual Sync Trigger + +```typescript +// API Endpoint +POST /api/metrc/sync +{ + type: 'PULL' | 'PUSH' | 'VALIDATE', + scope: 'ALL' | 'BATCHES' | 'ROOMS' | 'HARVESTS', + batchIds?: string[] // Optional specific batches +} + +// Response +{ + status: 'SUCCESS' | 'PARTIAL' | 'FAILED', + synced: 47, + errors: 2, + discrepancies: [ + { batchId: 'xxx', field: 'plantCount', ours: 280, metrc: 278 } + ] +} +``` + +--- + +## Compliance Alerts & Reminders + +### Weight Reporting Alerts + +```typescript +// Trigger: Weight log created without METRC ID +{ + type: 'METRC_WEIGHT_PENDING', + message: 'Wet weight (42,000g) for Batch B004 needs METRC entry', + deadline: '24 hours from harvest', + action: 'Open METRC to report harvest weight' +} +``` + +### Plant Movement Alerts + +```typescript +// Trigger: Room assignment changed +{ + type: 'METRC_LOCATION_CHANGE', + message: 'Batch B002 moved to Flower Room A - update METRC location', + action: 'Record location change in METRC' +} +``` + +### Stage Transition Alerts + +```typescript +// Trigger: Batch stage changed to FLOWERING +{ + type: 'METRC_PHASE_CHANGE', + message: 'Batch B005 transitioned to Flowering - update METRC growth phase', + action: 'Change growth phase in METRC' +} +``` + +--- + +## API Configuration + +### Environment Variables + +```bash +# METRC API (when implemented) +METRC_ENABLED=false +METRC_API_URL=https://api-ca.metrc.com +METRC_VENDOR_KEY=your_vendor_api_key +METRC_USER_KEY=your_user_api_key +METRC_LICENSE_NUMBER=CCL21-0001234 + +# Sync Settings +METRC_AUTO_SYNC=false +METRC_SYNC_INTERVAL=6h +METRC_ALERT_PENDING_ITEMS=true +``` + +### Required METRC API Permissions + +- `plants` - Read/Write plant batches +- `plantbatches` - Read/Write batch operations +- `harvests` - Read/Write harvest data +- `packages` - Read package information +- `locations` - Read location data +- `labresults` - Read lab test results + +--- + +## Reporting & Audits + +### METRC Compliance Report + +``` +Weekly METRC Sync Report - 2025-12-09 to 2025-12-15 +═══════════════════════════════════════════════════ + +✓ Batches in METRC: 7 +✓ Batches in App: 7 (100% linked) + +✓ Weight entries pending METRC: 0 +✓ Location changes pending: 0 +✓ Phase changes pending: 0 + +⚠️ Discrepancies Found: 1 + - Batch B001: Plant count (280 local vs 278 METRC) + Action: Verify physical count, correct appropriate system + +Last Full Sync: Dec 15, 2025 at 06:00 AM +``` + +### Audit Trail + +All METRC-related fields are immutable once synced: + +- Before sync: Editable locally +- After sync: Read-only, requires override permission +- Override: Creates audit log entry with reason + +--- + +## Implementation Phases + +### Phase 1: Reference IDs (Current) + +- [x] Add METRC ID fields to schema +- [x] Display METRC sync status indicators +- [ ] Manual ID entry UI + +### Phase 2: Compliance Alerts + +- [ ] Pending entry reminders +- [ ] Discrepancy flagging +- [ ] Deadline tracking + +### Phase 3: Read Sync + +- [ ] Pull batches from METRC +- [ ] Pull locations from METRC +- [ ] Discrepancy detection + +### Phase 4: Write Sync + +- [ ] Push weight logs to METRC +- [ ] Push waste events to METRC +- [ ] Location change sync + +### Phase 5: Real-time Integration + +- [ ] Webhook support +- [ ] Live sync status +- [ ] Auto-correction suggestions + +--- + +## References + +- [METRC API Documentation](https://api-ca.metrc.com/Documentation) +- [DCC Regulations](https://cannabis.ca.gov/cannabis-laws/laws-and-regulations/) +- [METRC Training](https://www.metrc.com/california) + +--- + +## Internal vs METRC: Quick Reference + +| Need to do | METRC | Our App | +|------------|-------|---------| +| Report plant counts | ✅ Required | 📝 Reference | +| Log wet weight at harvest | ✅ Required | 📝 Mirror weight | +| Record waste disposal | ✅ Required | 📝 Track trigger | +| Create manifests | ✅ Required | ❌ Not applicable | +| Log package creation | ✅ Required | 📝 Reference | +| Log lab results | ✅ Required | 📝 Reference | +| Daily plant observations | ❌ Not tracked | ✅ Primary function | +| IPM treatments | ❌ Not tracked | ✅ Primary function | +| Staff time tracking | ❌ Not tracked | ✅ Primary function | +| Environment data | ❌ Not tracked | ✅ Primary function | +| Photo documentation | ❌ Not tracked | ✅ Primary function | +| SOPs & Training | ❌ Not tracked | ✅ Primary function |
+ This weight must be reported to METRC within 24 hours. +
+ METRC Location: {selectedRoom.metrcLocationName} +