feat: AZ dispensary harmonization with Dutchie source of truth

Major changes:
- Add harmonize-az-dispensaries.ts script to sync dispensaries with Dutchie API
- Add migration 057 for crawl_enabled and dutchie_verified fields
- Remove legacy dutchie-az module (replaced by platforms/dutchie)
- Clean up deprecated crawlers, scrapers, and orchestrator code
- Update location-discovery to not fallback to slug when ID is missing
- Add crawl-rotator service for proxy rotation
- Add types/index.ts for shared type definitions
- Add woodpecker-agent k8s manifest

Harmonization script:
- Queries ConsumerDispensaries API for all 32 AZ cities
- Matches dispensaries by platform_dispensary_id (not slug)
- Updates existing records with full Dutchie data
- Creates new records for unmatched Dutchie dispensaries
- Disables dispensaries not found in Dutchie

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Kelly
2025-12-08 10:19:49 -07:00
parent 948a732dd5
commit b7cfec0770
112 changed files with 3163 additions and 34694 deletions

92
k8s/woodpecker-agent.yaml Normal file
View File

@@ -0,0 +1,92 @@
# Woodpecker CI Agent Deployment
# Runs in the K8s cluster to pick up CI jobs from ci.cannabrands.app
---
apiVersion: v1
kind: Namespace
metadata:
name: woodpecker
---
apiVersion: v1
kind: Secret
metadata:
name: woodpecker-agent-secret
namespace: woodpecker
type: Opaque
stringData:
WOODPECKER_AGENT_SECRET: "" # Get from CI server admin panel
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: woodpecker-agent
namespace: woodpecker
labels:
app: woodpecker-agent
spec:
replicas: 2
selector:
matchLabels:
app: woodpecker-agent
template:
metadata:
labels:
app: woodpecker-agent
spec:
serviceAccountName: woodpecker-agent
containers:
- name: agent
image: woodpeckerci/woodpecker-agent:latest
env:
- name: WOODPECKER_SERVER
value: "ci.cannabrands.app:443"
- name: WOODPECKER_AGENT_SECRET
valueFrom:
secretKeyRef:
name: woodpecker-agent-secret
key: WOODPECKER_AGENT_SECRET
- name: WOODPECKER_GRPC_SECURE
value: "true"
- name: WOODPECKER_BACKEND
value: "kubernetes"
- name: WOODPECKER_BACKEND_K8S_NAMESPACE
value: "woodpecker"
- name: WOODPECKER_BACKEND_K8S_VOLUME_SIZE
value: "10G"
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "100m"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: woodpecker-agent
namespace: woodpecker
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: woodpecker-agent
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "secrets", "configmaps", "persistentvolumeclaims"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: woodpecker-agent
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: woodpecker-agent
subjects:
- kind: ServiceAccount
name: woodpecker-agent
namespace: woodpecker