---
title: "Hotfolder Daemon — Box Monitoring"
aliases: [hotfolder, daemon, box-monitor, systemd-daemon]
tags: [hotfolder, daemon, systemd, box, ford, automation, python]
sources: [01 Projects/ford_qc, 01 Projects/ford-gechub-sftp]
created: 2026-04-15
updated: 2026-04-15
---

# Hotfolder Daemon — Box Monitoring

Persistent background daemon that watches a Box folder for new files, processes them automatically, and archives the originals.

## Key Takeaways
- Ford QC runs as a **systemd service** on a production server — survives reboots
- Hotfolder pattern: poll Box folder → detect new files → process → upload result → archive original
- Archive processed files immediately to prevent reprocessing
- CLI mode (single file) and daemon mode (continuous) — same core logic, different entry points
- Ford SFTP uses daemon mode (`python main.py --daemon`) without systemd (simpler)

## When to Use
Any automation that must respond to files dropped in a Box folder without human intervention.

## Architecture

### Ford QC Hotfolder
```
Box folder 332861865120 (hotfolder, poll every N seconds)
    ↓ detect new ZIP
ford_qc_box_hotfolder_process.py
    ↓
qc_engine.py → 13 QC check modules (checks/)
    ↓
JSON results → HTML report (html_reporter.py)
    ↓
Upload HTML report → Box 332864939558 (reports)
Archive ZIP → Box 332861653811 (archive)
```

### Ford SFTP Daemon
```
Box folders (PROD / EDU / QA — 3 separate targets)
    ↓ poll for new ZIPs
ford_qc_box_hotfolder_process.py
    ↓
Download ZIP → Upload to GECHUB SFTP (paramiko)
    ↓
Archive in Box
    ↓
Email notification (Mailgun)
```

## Systemd Service (Ford QC)
```bash
# /etc/systemd/system/ford-qc-hotfolder.service
[Unit]
Description=Ford QC Hotfolder Daemon

[Service]
ExecStart=/usr/bin/python3 /path/to/ford_qc_box_hotfolder_process.py
Restart=always

[Install]
WantedBy=multi-user.target

# Commands
sudo systemctl start ford-qc-hotfolder.service
sudo systemctl enable ford-qc-hotfolder.service   # start on boot
sudo systemctl status ford-qc-hotfolder.service
```

## Projects Using This Pattern
- [[01 Projects/ford_qc/Ford QC System|Ford QC System]] — systemd service, 13 QC check modules, Box JWT auth, HTML reports
- [[01 Projects/ford-gechub-sftp/Ford SFTP Transfer|Ford SFTP Transfer]] — `--daemon` flag, 3 environments, SFTP upload, Mailgun notifications

## QC Module Pattern (Ford QC)
```python
# qc_module.py
class QCModule:
    def check(self, zip_path: str, profile: dict) -> dict:
        """Returns {"passed": bool, "issues": [...]}"""

# 13 modules in checks/:
# image resolution, format, file size, layer depth, colour existence,
# linking validation, MEC/BAU compliance, powertrain validation, lifestyle inventory
```

## Gotchas & Lessons
- Always archive processed files — the daemon will reprocess on next poll if not archived
- Box JWT config (`ford_box_config.json`) must not be committed to git
- Ranger ptvl pattern is configurable via profile JSON — don't hardcode (fix: 2026-03-16)
- Three environments (PROD/EDU/QA) have completely separate Box folder IDs and SFTP targets
- Mailgun integration: keep email templates simple — Mailgun rejects complex HTML occasionally

## Related
- [[wiki/tech-patterns/box-api-integration|box-api-integration]] — Box auth and folder IDs
- [[wiki/client-knowledge/ford|ford]] — Ford-specific context and environment details
