feat: Add local storage adapter and update CLAUDE.md with permanent rules
- Add local-storage.ts with smart folder structure:
/storage/products/{brand}/{state}/{product_id}/
- Add storage-adapter.ts unified abstraction
- Add docker-compose.local.yml (NO MinIO)
- Add start-local.sh convenience script
- Update CLAUDE.md with:
- PERMANENT RULES section (no data deletion)
- DEPLOYMENT AUTHORIZATION requirements
- LOCAL DEVELOPMENT defaults
- STORAGE BEHAVIOR documentation
- FORBIDDEN ACTIONS list
- UI ANONYMIZATION rules
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
124
CLAUDE.md
124
CLAUDE.md
@@ -1,5 +1,129 @@
|
||||
## Claude Guidelines for this Project
|
||||
|
||||
---
|
||||
|
||||
## PERMANENT RULES (NEVER VIOLATE)
|
||||
|
||||
### 1. NO DELETION OF DATA — EVER
|
||||
|
||||
CannaiQ is a **historical analytics system**. Data retention is **permanent by design**.
|
||||
|
||||
**NEVER delete:**
|
||||
- Product records
|
||||
- Crawled snapshots
|
||||
- Images
|
||||
- Directories
|
||||
- Logs
|
||||
- Orchestrator traces
|
||||
- Profiles
|
||||
- Selector configs
|
||||
- Crawl outcomes
|
||||
- Store data
|
||||
- Brand data
|
||||
|
||||
**NEVER automate cleanup:**
|
||||
- No cron or scheduled job may `rm`, `unlink`, `delete`, `purge`, `prune`, `clean`, or `reset` any storage directory or DB row
|
||||
- No migration may DELETE data — only add/update/alter columns
|
||||
- If cleanup is required, ONLY the user may issue a manual command
|
||||
|
||||
**Code enforcement:**
|
||||
- `local-storage.ts` must only: write files, create directories, read files
|
||||
- No `deleteImage`, `deleteProductImages`, or similar functions
|
||||
|
||||
### 2. DEPLOYMENT AUTHORIZATION REQUIRED
|
||||
|
||||
**NEVER deploy to production unless the user explicitly says:**
|
||||
> "CLAUDE — DEPLOYMENT IS NOW AUTHORIZED."
|
||||
|
||||
Until then:
|
||||
- All work is LOCAL ONLY
|
||||
- No `kubectl apply`, `docker push`, or remote operations
|
||||
- No port-forwarding to production
|
||||
- No connecting to Kubernetes clusters
|
||||
|
||||
### 3. LOCAL DEVELOPMENT BY DEFAULT
|
||||
|
||||
**In local mode:**
|
||||
- Use `docker-compose.local.yml` (NO MinIO)
|
||||
- Use local filesystem storage at `./storage`
|
||||
- Connect to local PostgreSQL at `localhost:54320`
|
||||
- Backend runs at `localhost:3010`
|
||||
- NO remote connections, NO Kubernetes, NO MinIO
|
||||
|
||||
**Environment:**
|
||||
```bash
|
||||
STORAGE_DRIVER=local
|
||||
STORAGE_BASE_PATH=./storage
|
||||
DATABASE_URL=postgresql://dutchie:dutchie_local_pass@localhost:54320/dutchie_menus
|
||||
# MINIO_ENDPOINT is NOT set (forces local storage)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## STORAGE BEHAVIOR
|
||||
|
||||
### Local Storage Structure
|
||||
|
||||
```
|
||||
/storage/products/{brand}/{state}/{product_id}/
|
||||
image-{hash}.webp
|
||||
image-{hash}-medium.webp
|
||||
image-{hash}-thumb.webp
|
||||
|
||||
/storage/brands/{brand}/
|
||||
logo-{hash}.webp
|
||||
```
|
||||
|
||||
### Storage Adapter
|
||||
|
||||
```typescript
|
||||
import { saveImage, getImageUrl } from '../utils/storage-adapter';
|
||||
|
||||
// Automatically uses local storage when STORAGE_DRIVER=local
|
||||
```
|
||||
|
||||
### Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `backend/src/utils/local-storage.ts` | Local filesystem adapter |
|
||||
| `backend/src/utils/storage-adapter.ts` | Unified storage abstraction |
|
||||
| `docker-compose.local.yml` | Local stack without MinIO |
|
||||
| `start-local.sh` | Convenience startup script |
|
||||
|
||||
---
|
||||
|
||||
## FORBIDDEN ACTIONS
|
||||
|
||||
1. **Deleting any data** (products, snapshots, images, logs, traces)
|
||||
2. **Deploying without explicit authorization**
|
||||
3. **Connecting to Kubernetes** without authorization
|
||||
4. **Port-forwarding to production** without authorization
|
||||
5. **Starting MinIO** in local development
|
||||
6. **Using S3/MinIO SDKs** when `STORAGE_DRIVER=local`
|
||||
7. **Automating cleanup** of any kind
|
||||
8. **Dropping database tables or columns**
|
||||
9. **Overwriting historical records** (always append snapshots)
|
||||
|
||||
---
|
||||
|
||||
## UI ANONYMIZATION RULES
|
||||
|
||||
- No vendor names in forward-facing URLs: use `/api/az/...`, `/az`, `/az-schedule`
|
||||
- No "dutchie", "treez", "jane", "weedmaps", "leafly" visible in consumer UIs
|
||||
- Internal admin tools may show provider names for debugging
|
||||
|
||||
---
|
||||
|
||||
## FUTURE TODO / PENDING FEATURES
|
||||
|
||||
- [ ] Orchestrator observability dashboard
|
||||
- [ ] Crawl profile management UI
|
||||
- [ ] State machine sandbox (disabled until authorized)
|
||||
- [ ] Multi-state expansion beyond AZ
|
||||
|
||||
---
|
||||
|
||||
### Multi-Site Architecture (CRITICAL)
|
||||
|
||||
This project has **5 working locations** - always clarify which one before making changes:
|
||||
|
||||
Reference in New Issue
Block a user