rubis/apps/api/app/models/organization.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

42 lines
1.7 KiB
TypeScript

import { OrganizationSchema } from '#database/schema'
import { column, hasMany } from '@adonisjs/lucid/orm'
import type { HasMany } from '@adonisjs/lucid/types/relations'
import User from '#models/user'
import BankConnection from '#models/bank_connection'
import type { BrandSettings } from '#services/brand'
import type { InvoiceSettings } from '#services/invoice_settings'
export default class Organization extends OrganizationSchema {
/**
* Settings de marque blanche (plan Business) — JSONB, null = palette
* Rubis par défaut. Cf. `#services/brand` pour la résolution et la
* validation. Cette déclaration manuelle existe en attendant que
* `schema.ts` soit régénéré par `node ace migration:run` (cf. migration
* `1778400000000_add_brand_settings_to_organizations_table.ts`).
*/
@column()
declare brandSettings: BrandSettings | null
/**
* Settings de facturation native — JSONB, null = defaults applicatifs.
* Cf. `#services/invoice_settings` pour la résolution et la validation.
* Cette déclaration manuelle existe en attendant que `schema.ts` soit
* régénéré par `node ace migration:run` (cf. migration
* `1778800000000_add_invoice_settings_to_organizations_table.ts`).
*/
@column()
declare invoiceSettings: InvoiceSettings | null
@hasMany(() => User)
declare users: HasMany<typeof User>
/**
* V1 = une seule connection active par org, mais on garde hasMany pour
* l'historique (connections révoquées passent en state='revoked'). Les
* services filtrent sur state='active' quand ils ont besoin de "la"
* connection courante.
*/
@hasMany(() => BankConnection)
declare bankConnections: HasMany<typeof BankConnection>
}