# Appel De Fonds

> Analyze French syndic quarterly charge-call PDFs (appels de fonds), persist extracted charges as a local KB, and generate one beautiful anomaly-focused HTML report. Don't use for AG convocations, tax notices, bank statements, or non-copropriété PDFs.

- Skill: `luongnv89/appel-de-fonds` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add luongnv89/appel-de-fonds`
- Raw SKILL.md: https://api.skillmd.com/api/skills/luongnv89/appel-de-fonds/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: luongnv89 (https://skillmd.com/u/luongnv89)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/luongnv89/appel-de-fonds

---


# appel-de-fonds — Quarterly copropriété charge analyzer

Analyze one or more French syndic **appels de fonds / avis d'échéance / répartitions de charges** PDFs, persist the extracted data as a reusable local knowledge base, and generate a single polished HTML report that highlights important charges and abnormal items.

## Repo Sync Before Edits (mandatory)

Before writing or modifying files inside a git repository, sync the current branch so generated reports or KB exports do not clobber newer work:

```bash
branch="$(git rev-parse --abbrev-ref HEAD)"
git fetch origin
git pull --rebase origin "$branch"
```

If the working tree is dirty, stash first, sync, then pop. If `origin` is missing or the rebase/pop has conflicts, stop and ask the user before continuing. If writing only to the default user KB under `~/.copro-charges-kb/`, this repo-sync step is not needed.

## When this skill triggers

Use this skill when the user provides French copropriété charge PDFs from a syndic, especially terms like `appel de fonds`, `avis d'échéance`, `charges`, `trimestre`, `répartition`, `fonds travaux`, `syndic`, `copropriété`, or asks to analyze quarterly residence charges.

Do not use it for AG convocations and resolutions (use `ag-copro`), income tax files (use `declaration-impot-fr`), mortgage capacity, generic bank statements, invoices unrelated to copropriété, or non-French residence charges.

## Inputs

Accept any of these:

- A list of PDF paths.
- A directory containing PDFs, for example `appel-de-fonds/`.
- Multiple residence folders; keep residence identities separate unless the user asks to merge.

The document template is variable. Never rely on fixed page coordinates or a single syndic layout. Anchor extraction on semantic labels and table headers.

## Output files

Write one self-contained HTML report to the current working directory:

```text
./charges-<residence-slug>-<period-range>.html
```

Also persist structured extraction data to the local KB:

```text
~/.copro-charges-kb/<residence-slug>/charges.jsonl
~/.copro-charges-kb/<residence-slug>/documents/<document-id>.json
~/.copro-charges-kb/<residence-slug>/latest-report.json
```

The HTML embeds the final dataset as JSON in `<script type="application/json" id="charges-data">…</script>` so future Q&A can use the report even if the KB is unavailable.

## Workflow

### Phase 1 — Intake and environment

1. Resolve all PDF paths to absolute paths.
2. If the user gave a folder, recursively include `*.pdf` files and ignore hidden/system files.
3. Check whether `docling` is available: `python -c "import docling"`.
4. If missing, ask before installing. Prefer the current virtualenv; otherwise suggest `python -m pip install docling`.
5. Create a run workspace under `~/.copro-charges-kb/_runs/<timestamp>/` for extracted markdown, tables, logs, and intermediate JSON.

After this phase, output a Step Completion Report.

### Phase 2 — Extract every PDF with Docling

Use Docling as the primary extractor because syndic PDFs can mix text blocks, tables, scans, and inconsistent layouts.

For each PDF:

1. Run Docling conversion to Markdown/JSON when possible.
2. Preserve page numbers, table boundaries, and raw text snippets for citations.
3. If Docling fails or returns too little text, fall back to OCR-capable PDF tools if available, and clearly mark lower confidence.
4. Extract document metadata:
   - residence / copropriété name and address
   - syndic name
   - copropriétaire name or account reference if present
   - document type (`appel_de_fonds`, `regularisation`, `travaux`, `taxe`, `other_copro_charge`)
   - period start/end, quarter, due date, issue date
   - total due, previous balance, payments/credits, net amount payable
5. Extract all charge lines from tables:
   - label as printed
   - normalized category
   - amount called for the owner
   - building/residence total when present
   - tantièmes / clé / lot reference when present
   - VAT/tax if present
   - page and source snippet

Use `references/extraction.md` for field definitions, landmarks, and normalization rules.

### Phase 3 — Persist the knowledge base

Read `references/knowledge-base.md` before writing KB files.

1. Generate a stable `document_id` from residence, period, source filename, and total amount.
2. Append one JSONL record per charge line to `charges.jsonl` unless an identical `source_hash + line_hash` already exists.
3. Save one full document JSON under `documents/<document-id>.json`.
4. Update `latest-report.json` with the report dataset and anomaly summary.
5. Keep original source paths and hashes; do not copy PDFs into the KB unless the user asks.

### Phase 4 — Detect abnormal items

Compare within the current batch and against historical KB records for the same residence:

- Quarter-over-quarter and year-over-year changes by normalized category.
- New labels/categories never seen before.
- Large one-off works or tax/insurance lines.
- Duplicate calls for the same period/category.
- Negative credits, unexplained balances, or payment deadlines already passed.
- Owner share that appears inconsistent with tantièmes or previous periods.

Flag anomalies by severity: `info`, `watch`, `warning`, `critical`. Never accuse the syndic of an error; phrase as "à vérifier" unless the document itself proves the issue.

### Phase 5 — Generate the HTML report

Use the `frontend-design` skill's production-grade UI principles if available: distinctive but readable design, responsive layout, clear hierarchy, accessible contrast, no generic dashboard slop.

Read `references/html-report.md` for the required sections and visual style. The report must include:

- Executive summary cards: amount due, period, due date, biggest category, anomaly count.
- Timeline of quarters/documents.
- Category breakdown chart and per-quarter comparison chart (Chart.js via CDN is acceptable).
- Table of all charge lines with filters and severity badges.
- "Abnormal / à vérifier" section explaining each flagged item with evidence.
- Knowledge-base status: records added, duplicates skipped, KB path.
- Embedded JSON source data for follow-up questions.

Write a single `.html` file. If the target exists, ask before overwriting.

### Phase 6 — Review and answer

Before presenting the result, do a quick consistency review:

- Sum of extracted line amounts vs document totals.
- Period labels are plausible quarters.
- Every anomaly has a source page/snippet.
- HTML contains the embedded `charges-data` JSON.
- KB files were written or a clear reason is reported.

Then summarize the important points in 3–6 bullets and provide the report path.

## Subagent architecture

If the Agent tool is available, keep the main agent as orchestrator:

- For 3+ PDFs, spawn parallel worker subagents using `agents/pdf-worker.md`, one worker per PDF or small batch.
- Spawn one synthesis/report subagent using `agents/report-builder.md` to merge worker JSON, update the KB, and write the HTML.
- Spawn a fresh reviewer subagent using `agents/reviewer.md` for independent quality checks.

If Agent is not available, execute the same phases inline.

## Query mode

If the user asks a follow-up question after a report exists:

1. Prefer the HTML's embedded `charges-data` JSON if a report path is provided.
2. Otherwise load the residence KB from `~/.copro-charges-kb/`.
3. Answer from stored data only. If the answer requires re-reading PDFs, say so and ask whether to re-extract.
4. Keep French copropriété terms in French (`appel de fonds`, `tantièmes`, `fonds travaux`, `régularisation`).

## Step Completion Reports

After each major phase, output this compact report, adapting check names to the phase:

```text
◆ [Phase Name] ([step N of 6] — appel-de-fonds)
··································································
  PDFs resolved:       √ [count]
  Docling extraction:  √ [count ok] / [count total]
  KB persistence:      √ [records added], [duplicates skipped]
  Anomaly scan:        √ [count] flagged
  HTML report:         √ ./charges-[slug]-[range].html
  Criteria:            √ [N/M] met
  ____________________________
  Result:              PASS | PARTIAL | FAIL
```

## Constraints

- Do not invent missing amounts. Store `null` and lower confidence when a field cannot be extracted.
- Keep page/source snippets for every important number and anomaly.
- Do not provide legal advice or accuse fraud. Explain what the document says and what the user may want to verify with the syndic/conseil syndical.
- Treat personal data as sensitive. Do not upload PDFs or KB contents to external services unless the user explicitly asks.
- Prefer local persistent storage under `~/.copro-charges-kb/` so knowledge survives across projects without polluting repos.

## Reference files

- `references/extraction.md` — Docling extraction strategy, landmarks, schema, and category normalization.
- `references/knowledge-base.md` — persistent KB layout, deduplication, and query rules.
- `references/html-report.md` — required report sections, visual design, embedded JSON contract.
- `agents/pdf-worker.md` — prompt for parallel per-PDF extraction workers.
- `agents/report-builder.md` — prompt for synthesis, KB update, and HTML generation.
- `agents/reviewer.md` — prompt for independent quality review.

