# Excel Listener - Clean Setup

## Top Rule: No Placeholders or Mock Data

- Use only actual values in configuration, commands, and examples.
- If a placeholder seems necessary, pause and request approval and the real values before proceeding.

> See project-wide preferences: [project-copilot-instructions.md](../project-copilot-instructions.md). For org standards, see [global-copilot-instructions.md](../global-copilot-instructions.md).

## Structure
```
Excel_Listener/
├── .env                    # Configuration (kept)
├── package.json           # Minimal dependencies
├── tsconfig.json          # TypeScript config
└── src/
    ├── auth.ts            # User + Agent token acquisition
    ├── userAuth.ts        # Graph delegated token (MSAL)
    ├── excel.ts           # Excel table operations (Graph API)
    ├── sync.ts            # PocketBase upsert logic
    └── poller.ts          # Main polling loop (in-memory hash cache)
```

## Quick Start

### Install
```bash
bun install
```

### Run Poller (delegated token)
```bash
# Ensure a valid delegated Graph token is present in GRAPH_ACCESS_TOKEN (no placeholders).
bun run start:poller
```

## How It Works
1. **auth.ts**: Orchestrates PocketBase agent login
2. **userAuth.ts**: Handles delegated Graph token via in-memory cache
3. **excel.ts**: Reads Excel table rows via Graph Workbook API
4. **poller.ts**: Runs continuously, compares row hashes, upserts changed rows to PocketBase
5. **sync.ts**: Normalizes boolean/date fields, enforces Job_Number as primary key

## Key Features
- ✅ Background polling (no webhooks/ngrok needed)
- ✅ Job_Number as immutable primary key
- ✅ Row-hash change detection (skips unchanged rows)
- ✅ Dual auth: user tokens (OAuth2) + agent tokens (.env)
- ✅ No file I/O (in-memory hash cache)
