rubis/apps/api/app/models/client.ts
ordinarthur e0b47ddfdc feat(invoices): éditeur de factures natif — data model + API (Phase 1)
Pose les fondations pour permettre aux utilisateurs de créer leurs
factures directement dans Rubis (en complément de l'upload OCR existant),
avec snapshots immuables, numérotation strict séquentielle (art. 242
nonies A CGI) et 4 thèmes pré-faits paramétrables.

Data model
- organizations.invoice_settings (JSONB) : thème par défaut, accent color,
  préfixe et compteur de numérotation, mentions légales (pénalités,
  escompte), identité émetteur (SIREN/SIRET/TVA intra/RCS/capital), RIB.
- clients enrichi : SIREN, TVA intra, adresse structurée (lines/zip/city
  /country). Le champ address legacy reste pour les clients pré-feature.
- invoices enrichi : lines (JSONB), client_snapshot + issuer_snapshot
  figés à l'émission, amount_ht/tva, tva_breakdown, payment_terms_days,
  theme_slug + theme_accent_color, is_native, sequence_number (unique
  per org), pdf_generated_at.

API
- GET/PATCH /organizations/me/invoice-settings (resolveInvoiceSettings)
- GET /invoice-themes (4 thèmes : classique, moderne, minimal, élégant)
- POST /invoices/native (séquence strict allouée en transaction,
  totaux recalculés serveur, snapshots immuables)
- POST /invoices/preview-pdf (stream PDF sans persister, stub Phase 1)

Le rendu PDF lui-même (@react-pdf/renderer + templates) arrive en
Phase 2 ; le storeNative crée bien la facture mais pdf_storage_key
reste null jusqu'à Phase 2. Conformité Factur-X visée pour V1.5
(Q3-Q4 2026, avant l'échéance d'émission TPE-PME au 1er sept 2027).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 02:07:45 +02:00

45 lines
1.3 KiB
TypeScript

import { ClientSchema } from '#database/schema'
import { belongsTo, column, hasMany } from '@adonisjs/lucid/orm'
import type { BelongsTo, HasMany } from '@adonisjs/lucid/types/relations'
import Organization from '#models/organization'
import Invoice from '#models/invoice'
export default class Client extends ClientSchema {
/**
* Champs ajoutés par la migration `1778800000100_enrich_clients_for_invoicing`
* (SIREN/TVA intra/adresse structurée). Déclarations manuelles en attendant
* que `schema.ts` soit régénéré par `node ace migration:run`.
*
* Le champ `address` (existant, string libre) est conservé pour les clients
* importés avant la feature ; le nouveau code lit en priorité ces champs
* structurés et retombe sur `address` s'ils sont vides.
*/
@column()
declare siren: string | null
@column()
declare tvaIntra: string | null
@column()
declare addressLine1: string | null
@column()
declare addressLine2: string | null
@column()
declare addressZip: string | null
@column()
declare addressCity: string | null
/** ISO 3166-1 alpha-2 (ex. "FR"). */
@column()
declare addressCountry: string | null
@belongsTo(() => Organization)
declare organization: BelongsTo<typeof Organization>
@hasMany(() => Invoice)
declare invoices: HasMany<typeof Invoice>
}