@sinoia/loctavia-tools
v1.2.0
Published
CLI Loctavia : gestion locative en ligne de commande (baux, patrimoine, quittancement, banque, pilotage).
Readme
Loctavia CLI
loctavia : la gestion locative Loctavia en ligne de commande, au-dessus de
l'API REST /loctavia/api/v1. Pensée pour les humains et les agents :
sortie JSON sur demande, authentification sans navigateur (device flow),
configuration par variables d'environnement.
Installation
npm install -g @sinoia/loctavia-toolsMise à jour :
npm update -g @sinoia/loctavia-tools # ou re-`npm install -g` pour épingler une versionPrérequis : Node.js ≥ 20. Deux binaires sont installés : loctavia (et son
alias court lt).
Démarrage rapide
# 1. Se connecter à une instance (device flow, sans manipuler de token)
loctavia login --api https://votre-instance.hubdoc.sinoia.cloud
# 2. Choisir le mandataire (tenant) sur lequel travailler
loctavia mandataires list
loctavia mandataires use <mandataire-id>
# 3. Explorer
loctavia leases list --per-page 10
loctavia properties show <id>
loctavia --json owners list # JSON brut pour un script/agentAuthentification (device flow, RFC 8628)
loctavia login demande un code à l'instance, ouvre la page de confirmation
(ou affiche l'URL si aucun navigateur), puis récupère automatiquement un
Personal Access Token de scope read write. Le token est stocké dans
~/.config/loctavia/config.json (permissions 0600).
loctavia logoutsupprime le token.loctavia whoamiaffiche l'identité et le mandataire actif.
Multi-tenant : le mandataire
Tous les endpoints (sauf mandataires list) sont scopés à un mandataire. La
CLI résout l'identifiant dans cet ordre : --mandataire <id> >
LOCTAVIA_MANDATAIRE_ID > mandataire actif persisté (mandataires use). Si tu
n'as qu'un seul mandataire, l'API le sélectionne d'office.
Exploration des commandes
L'aide est imbriquée à chaque niveau :
loctavia --help
loctavia leases --help
loctavia billing-runs --help
loctavia billing-runs create --helpRessources disponibles
| Commande | Actions | Description |
|----------|---------|-------------|
| mandataires | list, use, current | Tenants accessibles, sélection du tenant actif |
| leases | list, show, create | Baux |
| properties | list, show, create | Immeubles |
| units | list, show, create | Lots |
| owners | list, show, create | Propriétaires |
| tenants | list, show | Locataires |
| mandates | list, show, create | Mandats de gestion |
| payments | list, show | Encaissements |
| incidents | list, show | Incidents locataires |
| journal-entries | list, show | Écritures comptables |
| billing-runs | list, show, create, lines, validate, apply, update-line | Quittancements (cycle complet) |
| fec-exports | create, download | Exports comptables FEC |
| pilotage | block | Escalade des agents opérationnels |
| bank statements | list, show, source, preview, confirm, transactions, targets, propose, canonical, findings, reports, report | Relevés bancaires : import, opérations, attendus, compte rendu |
| bank tx | show, triage, accept, reject, reconcile, debit-candidates, reconcile-debit, charge-accounts, reconcile-account, transfer-accounts, reconcile-transfer, suspend, undo-preview, undo | Gestes sur une opération bancaire |
Filtres, tri, pagination (commandes list)
loctavia leases list --filter status_eq=active --sort created_at --direction desc
loctavia owners list --q '{"name_cont":"dupont"}'
loctavia units list --page 2 --per-page 50Les filtres suivent la syntaxe Ransack
(_cont, _eq, _gteq, …).
Créations et mutations (corps JSON)
Les commandes create / update-line acceptent le corps en JSON, ce qui reste
fidèle au schéma de l'API et pratique pour un agent :
# inline
loctavia leases create --data '{"unitId":"…","tenantId":"…","startDate":"2025-01-01"}'
# depuis un fichier
loctavia properties create --file ./immeuble.json
# depuis stdin
echo '{"name":"Résidence X"}' | loctavia properties createCycle de quittancement
loctavia billing-runs create --data '{"lease_ids":["…"]}' # lance le calcul (asynchrone)
loctavia billing-runs show <id> # poller jusqu'à computed/review
loctavia billing-runs lines <id> --type tenant # relire les lignes
loctavia billing-runs update-line <id> <lineId> --excluded true
loctavia billing-runs validate <id>
loctavia billing-runs apply <id>Export FEC
loctavia fec-exports create --fiscal-year 2025 --siren 123456789
loctavia fec-exports download <id> --output ./export.fecUsage par un agent / en CI (sans interaction)
Tout est pilotable par l'environnement, aucun fichier de config requis :
export LOCTAVIA_API_URL=https://votre-instance.hubdoc.sinoia.cloud
export LOCTAVIA_TOKEN=<personal-access-token>
export LOCTAVIA_MANDATAIRE_ID=<mandataire-id>
loctavia --json leases list --per-page 100--json(ou-j) : sortie JSON brute sur stdout ; les messages d'état vont sur stderr, doncloctavia --json … > data.jsonreste propre.- Code de sortie non nul en cas d'erreur, avec un message actionnable sur stderr.
Contrat d'erreur en --json
En mode --json, les erreurs aussi sont du JSON, sur stderr, stdout restant
vide. Un appelant qui pipe stdout dans jq ou json.load ne casse donc jamais
sur une phrase en français ; et une erreur d'usage ne peut pas se déguiser en
résultat vide.
{ "ok": false, "error": { "code": "invalid_filter", "message": "…", "hint": "…", "status": 400 } }| code | Quand |
|--------|-------|
| commander.unknownOption / commander.unknownCommand | Option ou commande inexistante (le hint renvoie vers --filter / --help) |
| invalid_filter | --q / --filter illisible |
| body_required / invalid_body | Corps manquant ou JSON invalide sur une écriture |
| api_url_missing / token_missing | Instance ou token non configurés |
| unauthorized / forbidden / not_found / bad_request / api_error | Réponse HTTP de l'API (avec status) |
| mandataire_required | Portefeuille non résolu — le hint donne la commande |
| network_error | Instance injoignable |
Les filtres acceptent les deux écritures, JSON ou raccourci — parce que les deux s'écrivent en pratique, et qu'un filtre refusé silencieusement se lit comme « aucun résultat », ce qui est bien pire qu'une erreur :
loctavia --json leases list --q '{"status_eq":"active"}'
loctavia --json leases list --q status_eq=active,tenant_name_cont=dupont
loctavia --json leases list --filter status_eq=active --filter start_date_gteq=2026-01-01loctavia --json whoami indique le portefeuille résolu et sa provenance
(mandataireSource : flag / env / config) : inutile de re-poser
LOCTAVIA_MANDATAIRE_ID à chaque commande pour s'en assurer.
Variables d'environnement
| Variable | Rôle |
|----------|------|
| LOCTAVIA_API_URL | URL de l'instance (sinon config, sinon http://localhost:3000) |
| LOCTAVIA_TOKEN | Bearer token (court-circuite login) |
| LOCTAVIA_MANDATAIRE_ID | Mandataire actif |
| XDG_CONFIG_HOME | Emplacement du fichier de config (défaut ~/.config) |
Développement
npm install
npm run typecheck
npm run dev -- leases --help # exécuter depuis les sources
npm run bundle # → dist/publish/ (cli.js autonome + package.json)Le client est typé à partir de openapi/specs/loctavia.yaml (corex) via
npm run gen:types. Le CLI a sa propre ligne de version (cli/package.json),
indépendante du gem : la release est portée par la CI de l'engine loctavia sur
un tag dédié cli-vX.Y.Z.
Banque : import, tri par immeuble, rapprochement
Les gestes de l'écran de rapprochement, un par commande, sous les mêmes
habilitations (rapprocher, et trier pour le tri par immeuble). C'est le chemin
de l'analyste bancaire Synapse : chacun de ses gestes est signé de son nom, avec sa
justification (--rationale), affichée au gestionnaire.
lt --json bank statements show <relevé> # avancement, seuils du cabinet
lt --json bank statements preview <relevé> # brouillon : lignes lues, doublons
lt --json bank statements confirm <relevé> # import (défaut : tout sauf les doublons)
lt --json bank statements tx <relevé> --triage-status to_triage
lt --json bank tx triage <op> --accept-suggestion # ou --property <id> / --out-of-scope
lt --json bank statements propose <relevé> # propositions recalculées, lisibles au retour
lt --json bank statements tx <relevé> --status pending
lt --json bank tx accept <op> --rationale "Montant et référence du bail identiques."
lt --json bank statements targets <relevé> --property <id> --remaining-cents 62000
lt --json bank tx reconcile <op> --allocation billing_line:<id>:62000 --rationale "…"
lt --json bank statements findings <relevé> --file findings.json
lt --json bank statements report <relevé> --outcome completed --body-file report.md