antares_get_data/.github/copilot-instructions.md

78 lines
4.4 KiB
Markdown

# Copilot Instructions
## Build, test, and lint
- `cargo build`
- `cargo check` - **after every code edit/mod/remove/add, always run this to verify compilation**
- `cargo run` - requires a local `.env` file with `ANTARES_USERCODE` and `ANTARES_PASSWORD`
- `cargo test`
- `cargo test <test_name>` to run one test
- `cargo test -- --list` to discover test names; the repository currently has no defined tests
- `cargo fmt --all -- --check`
- `cargo clippy --all-targets -- -D warnings`
## High-level architecture
This is a modular single-binary Rust utility that fetches Antares B2B product data and exports it to Excel. The codebase is organized into separate concerns:
**Modules:**
- `src/main.rs` - orchestrates the pipeline: credential loading, API calls, JSON deserialization, and delegating to tools
- `src/api/client.rs` - handles URL construction for the Antares B2B API
- `src/tools/excel.rs` - implements Excel export with selective field mapping and business rule validation
- `src/tools/logger.rs` - provides dual output (terminal + file) logging to `log/{YYYY-MM-DD}.log`
- `src/template/antares.rs` - serde models with `#[serde(rename_all = "PascalCase")]`; top-level is `Antares` alias for `Vec<AntaresItem>`; also contains `AntaresLogin` struct holding credentials and base URL
**Pipeline:**
1. Initialize logger (creates `log/` dir if needed)
2. Load credentials from `.env` via `dotenv`
3. Build Antares API URL using `src/api/client::make_url()` (takes an `AntaresLogin` struct)
4. Fetch with 600-second timeout via blocking `reqwest::blocking::Client` (in `src/tools/request.rs`)
5. Deserialize into typed `Antares` structs; if schema mismatch, preserve response as JSON/text
6. Write `antares.json` with pretty formatting
7. Export filtered rows to `out/antares_export.xlsx` via `src/tools/excel::export_to_excel()`
8. Log success/failure at each step
**Logging:**
- All significant events logged to terminal and `log/{YYYY-MM-DD}.log` with format: `[TIMESTAMP] [LEVEL] Message`
- Log levels: `DEBUG`, `INFO` (default), `WARN`, `ERROR`; control via `LOG_LEVEL` env var
- Methods: `.info()`, `.debug()`, `.warn()`, `.error()` for appropriate log levels
- Directory created automatically if missing; logs appended daily by date
## Key conventions
**Credentials:**
- Load via `URL`, `ANTARES_USERCODE`, `ANTARES_PASSWORD`, and `OUT` env vars from `.env`
- `URL` is the Antares B2B base URL; `OUT` is the output file path for the Excel export
- Use `--config /path/to/.env` CLI argument to load config from custom location (defaults to `.env` in current directory)
- `.env.example` documents required variables
- No hardcoded credentials; missing vars cause graceful failure with instructions
- `PASSWORD` is wrapped in `Zeroizing<String>` (from the `zeroize` crate) to securely wipe it from memory after use
**Artifacts:**
- `temp/antares.json` - saved in `temp/` after each successful API fetch; directory created auto if missing
- Excel export path is configured via the `OUT` env var; parent directory created auto if missing
- `log/{YYYY-MM-DD}.log` - daily logs; `log/` directory created auto if missing
- `.gitignore` excludes: `*.json`, `*.xlsx`, `.env`, `/out`, `/log`
**Excel export (`src/tools/excel.rs`):**
- Not a generic dump; maps selected Antares fields to fixed column layout per business rules
- Rows skipped if `cikkszam` empty OR both name fields (`cikk_megnevezes_rovid`, `cikk_megnevezes`) empty
- `BESZCIKKNEV` prefers `cikk_megnevezes_rovid`, falls back to `cikk_megnevezes`
- `EGYSEGAR` prefers `netto_kisker_ar`; if `0.0`, searches `cikk_jellemzok` for entry with `jellemzo_nev == "Alap ár"`
- Headers are bold-formatted
**API integration:**
- When extending the schema, add/modify structs in `src/template/antares.rs` first
- Avoid ad hoc JSON traversal in `main.rs`; keep deserialization flow centered on typed structs
- Preserve response on schema mismatch (save as JSON or text) unless deliberately changing error handling
**Modularity:**
- Extend by adding new files to `src/tools/` (e.g., `csv.rs`, `database.rs`)
- Each tool should be self-contained and exposed via `src/tools/mod.rs`
- HTTP client logic stays in `src/tools/request.rs`; reuse `make_request()` from there for consistency
**Blocking HTTP:**
- Uses `reqwest::blocking::Client` with 600-second timeout (in `src/tools/request.rs`)
- No async runtime; synchronous flow is intentional
- Only change to async if architecture overhaul is deliberate