# Changelog of French Accountants · Expert-Comptable Directory (`corent1robert/experts-comptables-annuaire-scraper`) Actor

- **URL**: https://apify.com/corent1robert/experts-comptables-annuaire-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/corent1robert/experts-comptables-annuaire-scraper.md

## Changelog

### \[2.12.1] — 2026-09-07

#### Changed

- **SIREN matching off by default** — phone lists stay on the cheaper row event; turn the checkbox on for SIREN / SIRET.
- **Free plan:** 20 firms per run on Apify (local `apify run` uncapped).
- Default run memory **1024 MB** (HTTP-only; was 2048).

### \[2.12] — 2026-08-20

#### Changed

- Store title and description state **phones, no email** — the Ordre register does not publish email.

### \[2.11] — 2026-08-20

#### Changed

- Store PPE is now the **3-tier** events (`firm-contact-row` $2 / 1k, `firm-enriched-row` $4 / 1k, `firm-basic-row` $1 / 1k). Code bills those events instead of the old flat $3.99 line.

### \[2.10] — 2026-08-20

#### Fixed

- Dataset rows bill the **live Store event** (`apify-default-dataset-item`). Named 3-tier events in `actor.json` were never published on Console, so runs were not charging.

### \[2.9] — 2026-06-22

#### Added

- **Pay-per-event pricing** in `actor.json` — `firm-contact-row`, `firm-enriched-row`, `firm-basic-row`; free `apify-actor-start`.

#### Changed

- `chargeActorStart()` uses platform event `apify-actor-start`.

### \[2.8] — 2026-06-22

#### Added

- **`published-tasks/` kit** — 4 task specs, inputs, `bootstrap-tasks.mjs`, `publication-console.md`.
- **Input validation** — `src/lib/validate.js` with clear English errors for empty URL/city lists.
- **`docs/PPE-CONSOLE.md`** — Console pay-per-event setup with tier table.

#### Changed

- README — **Quick start** ordering, **Ready-made examples**, full PPE tier pricing table.
- Console form — field order: profile URLs before row limit (per mode flow).
- npm scripts — `start:paris`, `start:lyon-siren`, `test:smoke`.
- `.apifyignore` — excludes `published-tasks/` and `docs/`.

#### Fixed

- README and **PPE-CONSOLE** — `actor-start` documented as **$0** (always free); scenario totals exclude run-start fee.
- README polish — removed duplicate pricing copy; dataset **View** names in Quick start; clearer published-task 404 note; demo video script.

### \[2.7] — 2026-06-22

#### Added

- **Pay-per-event billing** — `actor-start`, `firm-contact-row`, `firm-enriched-row`, `firm-basic-row` via `src/lib/billing.js`.
- **Dataset views** — `outreachCrm` and `crmEnriched` for published tasks and CRM exports.
- **Unit tests** — `input`, `billing`, `mapMarkers` (+36 tests total).

#### Changed

- **Store metadata** — title leads with leads/outcome; categories `BUSINESS` + `LEAD_GENERATION`; `defaultRunOptions.timeoutSecs` 4 h.
- **Input normalization** — extracted to `src/lib/input.js`; shared `runPool` in `src/lib/pool.js`.

#### Fixed

- **SIREN API resilience** — `gouvHttp` reads gouv responses as text, detects HTML proxy/WAF pages, rotates proxy on 429/HTML, and backs off on rate-limit storms.

### \[2.6] — 2026-06-17

#### Console UX

- **English-only form** (Store standard) — benefit-first copy, three clear modes, city dropdown + optional custom slug.
- **No prefill on profile URLs** — avoids confusion when mode is **By city**.
- **Cloud proxy default** — Apify runs use datacenter proxy automatically (`useApifyProxy: true`).

### \[2.5] — 2026-06-17

#### Console UX

- **Simpler French form** — three clear modes (*Une ville*, *Toute la France*, *Mes liens*), no step numbering, `citySlugs` hidden from Console (API only).
- **Optional slug field** — `customCitySlug` text input for communes not in the dropdown.

### \[2.4] — 2026-06-17

#### Console UX

- **Commune dropdown** — pick Paris, Lyon, Marseille, etc. without guessing URL slugs; optional **Custom** + additional slugs for multi-city runs.
- **Clearer form flow** — mode-specific hints, Try-safe defaults (`rodez` + 50 firms).

### \[2.3] — 2026-06-17

#### Performance

- **Instant commune list on full directory** — ships a bundled index of **4 679 communes** (`src/data/city-slugs.json`). Skips ~120 HTTP requests (~20 s) on every France-wide run.
- **Faster live index refresh** — when `refreshCommuneIndex: true`, regional crawl uses retries and default concurrency **25** (was 15).

### \[2.2] — 2026-06-17

#### Added

- **Accountant names** — `accountants` array on each profile (full names from the Ordre listing).
- **Optional SIREN / SIRET matching** — Console checkbox **Match SIREN & SIRET** (`enrichSiren`) adds `siren`, `siret`, legal name, NAF, match score, and confidence per firm via the public business register.
- **Unit tests** — `gouvEnrich` scoring and dataset field wiring.
- **Offline CSV enricher** — `scripts/enrich-experts-comptables-siren.mjs` for batch files outside the Actor.

#### Changed

- **Console input** — simpler step flow (mode → slugs/URLs → optional SIREN → max firms); benefit-first copy; **By city** listed first in the mode dropdown.
- **README** — accountants + SIREN sections, updated output sample, fill-rate benchmarks, pricing with enrichment.
- **Store metadata** — `actor.json` v2.2 description and SEO mention accountant names and optional SIREN/SIRET.
- **Dataset overview view** — SIREN, SIRET, and match confidence columns.
- **Run logs** — SIREN enrichment startup line uses outcome wording (no API paths in default logs).

*Apify actor version: 2.2*

### \[2.1] — 2026-06-05

#### Changed

- **README — getting started** — step-by-step Console walkthrough, API curl examples, Schedules hint, and a typical multi-Actor workflow (SIREN / SIRET / BODACC).
- **README — Also available** — links to sibling Actors on [apify.com/corent1robert](https://apify.com/corent1robert) (notaires, recherche-entreprises, establishments, BODACC, Houzz, Ameli, syndics).
- **README — Who is this for?** — persona table plus default fill rates and mode-selection guidance.
- **README — progress docs** — aligned with v2.0 log format (scan vs export phases).
- **Store SEO** — `seoDescription` tuned for snippet length (~155 chars).
- **Cross-links** — reciprocal **Also available** sections on sibling French register Actors (notaires, recherche-entreprises, establishments, BODACC, Houzz, Ameli, syndics).

*Apify actor version: 2.1*

### \[2.0] — 2026-06-05

#### Changed

- **Clearer run progress** — one `Progress:` line every ~8s with phase-specific wording (commune list → scan → export). Console status is short and distinct from the log.
- **No misleading export % during scan** — while communes are still scanning, logs show firms found and saved counts without a false “exported X%” against a partial total.
- **Phase milestones** — `Phase` / `Phase complete` lines at index, scan, and export boundaries instead of overlapping Discovery/Export banners.
- **Configuration line** — worker counts moved behind `verboseLogs`; default startup copy stays outcome-focused.

*Apify actor version: 2.0*

### \[1.9] — 2026-06-05

#### Improved

- **Two-stage export pipeline** — 50 marker workers resolve profile URLs while 80 profile workers fetch pages in parallel (cloud defaults).
- **Unified run progress** — one log line every ~8s instead of overlapping scan + export messages; Console status shows a single ETA.
- **Non-blocking dataset writes** — profile workers no longer wait on each `pushData` round-trip.

### \[1.8] — 2026-06-05

#### Improved

- **Much faster profile export** — replaced CheerioCrawler queue with a direct HTTP worker pool (marker + profile in one worker, proxy reuse per slot).
- **Cloud export parallelism 60** (was effectively 10 from schema default) — full France ~31k firms targets ~20–35 min export instead of many hours.
- Progress logs every **50** exported rows; resume checkpoints every **100**.

### \[1.7] — 2026-06-05

#### Fixed

- **Full directory no longer capped at 50 firms by default** — `maxProfiles` schema default is **0** (unlimited); Console **Try** still uses **50** via `.actor/INPUT.json` for **By city** only.
- **Mode-specific input cleanup** — prefilled `citySlugs` / `profileUrls` from other modes are ignored so a **Full directory** run is not confused with Rodez or sample URLs.
- **Startup log** — prints effective mode and limits (`max firms: unlimited`, etc.).

### \[1.6] — 2026-06-05

#### Fixed

- **Dataset push no longer crashes the run** — rows are sanitized (no nulls, string coercion), dataset schema validation relaxed, and failed pushes are logged instead of aborting the Actor.

### \[1.5] — 2026-06-05

#### Fixed

- **Dataset schema validation crash** — optional fields are omitted from rows instead of pushed as `null` (Apify dataset schema rejects null strings/numbers). Coerces latitude/longitude to numbers.

### \[1.4] — 2026-06-05

#### Improved

- **Pipelined export** — profile export starts while commune map scan is still running (no wait for all 4 675 communes).
- **Cloud concurrency 30** — map and profile export default to 30 parallel requests on Apify.
- **Proxy reuse** — map workers reuse the same proxy URL for ~80 requests (less SDK overhead).

### \[1.3] — 2026-06-05

#### Improved

- **Faster full directory** — parallel regional index crawl (15–20 concurrent pages vs sequential), higher default map/export concurrency on Apify cloud (22 / 20), batched checkpoint writes (every 150 communes instead of every commune).

### \[1.2] — 2026-06-05

#### Fixed

- **Silent discovery phase** — progress logs and status messages during regional index crawl (regions + departments) and commune map scan (every 50 communes or 5 s), with ETA.

### \[1.1] — 2026-06-05

#### Fixed

- **Cloud crash on full directory** — `proxyConfiguration.newUrl()` is async in Apify SDK v3; discovery and map fetches now `await` the proxy URL instead of passing a Promise to got-scraping.

### \[1.0] — 2026-06-05

#### Added

- **Store-ready Actor** for [annuaire.experts-comptables.org](https://annuaire.experts-comptables.org/) — HTTP-only, no browser.
- **Three input modes:** full directory (~4 600 communes), by city (commune slugs), and bulk profile URL refresh.
- **Dataset fields:** firm name, address, phone, geo, profile URL, languages, competences (when present), website / LinkedIn / Facebook (separate columns), discovery metadata, scrape errors.
- **CheerioCrawler** profile export with retries, progressive `pushData`, and optional proxy (API).
- **Checkpoint / resume** via key-value store for long full-directory runs.
- **RUN\_LOG** live progress artifact and Console **Quick view (table)** dataset schema.
- **Unit tests** for discovery parsing, URL helpers, social link classification, and profile HTML/JSON-LD fixtures (Paris, Rodez).
- **Default Try input:** `cities` + `rodez` + 50 firms.

#### Notes

- Email is **not** exported (not available in public JSON-LD; contact flow is UI-only).
- Register lists **firm records** by commune — deduplication uses `searchId`.
