docs: add METRC integration specification
Some checks are pending
Deploy to Production / deploy (push) Waiting to run
Test / backend-test (push) Waiting to run
Test / frontend-test (push) Waiting to run

- 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
This commit is contained in:
fullsizemalt 2025-12-12 20:52:44 -08:00
parent e02fdb0c45
commit 9897e73de1

451
specs/metrc-integration.md Normal file
View file

@ -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
<BatchCard>
<div className="flex items-center gap-2">
<span className="badge">B007</span>
<h3>Zkittlez</h3>
{batch.metrcPlantBatchId && (
<Badge variant="success" className="text-[10px]">
<CloudCheck size={10} />
METRC
</Badge>
)}
</div>
{batch.metrcSyncStatus === 'SYNC_ERROR' && (
<Alert variant="warning">
METRC sync error - verify data in METRC portal
</Alert>
)}
</BatchCard>
```
### Weight Log Entry
```tsx
<WeightLogForm>
<Input label="Weight (g)" value={weight} />
<Select label="Type" options={['WET', 'FINAL_DRY', 'TRIM', 'WASTE']} />
<Divider />
<div className="metrc-section bg-yellow-50 p-3 rounded">
<h4 className="font-medium text-yellow-800">
⚠️ METRC Reporting Required
</h4>
<p className="text-sm text-yellow-700">
This weight must be reported to METRC within 24 hours.
</p>
<Checkbox
label="I will report this in METRC"
required
/>
</div>
</WeightLogForm>
```
### Room Assignment
```tsx
<RoomSelector>
<Select
label="Room"
options={rooms.map(r => ({
value: r.id,
label: r.name,
metrc: r.metrcLocationName
}))}
/>
{selectedRoom?.metrcLocationId && (
<p className="text-xs text-tertiary">
METRC Location: {selectedRoom.metrcLocationName}
</p>
)}
</RoomSelector>
```
---
## 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 |