Simpl-Resultat/src-tauri/src/database/consolidated_schema.sql
le king fu bd1085c148
All checks were successful
PR Check — Rust / rust (pull_request) Successful in 9m27s
schema: add migration v17 carrying the full import format on import_sources
`import_sources` carried only the mechanical CSV settings. The two fields that
decide how an amount is READ -- `amount_mode` and `sign_convention` -- lived
only on `import_config_templates`. That asymmetry is the root bug of this
chantier: restoring a saved source re-inferred the mode from the mapping and
hardcoded `signConvention: "negative_expense"` (useImportWizard.ts:321-323), so
a source configured with positive expenses silently flipped back on its second
import. After v17 both tables carry the same eight format fields.

v17 is strictly additive -- v1 to v16 are untouched, and the diff is pure
insertion. The four columns are defaulted or nullable so the ALTERs are safe on
a populated database:

- amount_mode / sign_convention carry a CHECK, same pattern as v15 on
  balance_accounts.kind. amount_mode admits 'absolute_indicator' from the start
  so the third amount mode ships without another migration, while the database
  still refuses a corrupted value today.
- header_signature stores the normalized header labels seen at the last
  successful import, for drift detection.
- template_id is a provenance tag only, never re-read as format: the eight
  source columns are authoritative, so editing a template changes no linked
  source. ON DELETE SET NULL keeps the source and its format when a template
  goes.

The backfill reproduces exactly the rule the wizard applied on the fly, so no
source changes behaviour on migration. It tests `column_mapping LIKE
'%debitAmount%'` rather than json_extract, so the migration depends on no JSON1
extension in the bundled SQLite. sign_convention is deliberately not
backfilled: its DEFAULT restores precisely the value the code hardcoded, the
only past convention that can be inferred.

The four columns are mirrored into consolidated_schema.sql. They are inert
there on the production path -- that script runs after every migration and only
uses CREATE TABLE IF NOT EXISTS, so new profiles receive them from v17 -- but
it stays the tested reference definition, and a parity test now compares it
against the v1->v17 chain column by column, DEFAULT by DEFAULT, CHECK by CHECK
and FK by FK. Both halves of that test were mutation-checked to confirm they
fail on drift.

5 new tests (111 Rust total): v17 on a populated v16 database with a child row,
the backfill against 5 mapping shapes, the CHECKs, the provenance-tag
semantics, and the consolidated parity.

Resolves #323
2026-08-13 12:56:28 -04:00

840 lines
66 KiB
SQL

-- Consolidated schema for new profile databases
-- This file bakes in the base schema + all migrations (v3-v8) and pre-seeds
-- the v1 IPC-aligned category taxonomy so that brand-new profiles immediately
-- use the new standard. Existing profiles keep their v2 seed and are only
-- tagged via the migration (categories_schema_version = 'v2').
-- Used ONLY for initializing new profile databases (not for the default profile).
CREATE TABLE IF NOT EXISTS import_sources (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
description TEXT,
date_format TEXT NOT NULL DEFAULT '%d/%m/%Y',
delimiter TEXT NOT NULL DEFAULT ';',
encoding TEXT NOT NULL DEFAULT 'utf-8',
column_mapping TEXT NOT NULL,
skip_lines INTEGER NOT NULL DEFAULT 0,
has_header INTEGER NOT NULL DEFAULT 1,
-- Full import format (migration v17). These four columns are INERT on the
-- production path: this script runs AFTER tauri-plugin-sql has applied every
-- migration and only uses CREATE TABLE IF NOT EXISTS, so a brand-new profile
-- actually receives them from v17. They are mirrored here to keep this file
-- the tested reference definition -- a parity test compares it against the
-- v1->v17 chain so the DEFAULT and CHECK of the two cannot drift apart.
-- `amount_mode` admits 'absolute_indicator' from the start so the third mode
-- can ship without another migration. `template_id` is a provenance tag
-- only, never re-read as format: the eight format columns above are
-- authoritative, so editing a template changes no linked source.
amount_mode TEXT NOT NULL DEFAULT 'single'
CHECK (amount_mode IN ('single','debit_credit','absolute_indicator')),
sign_convention TEXT NOT NULL DEFAULT 'negative_expense'
CHECK (sign_convention IN ('negative_expense','positive_expense')),
header_signature TEXT,
template_id INTEGER REFERENCES import_config_templates(id) ON DELETE SET NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS imported_files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
source_id INTEGER NOT NULL,
filename TEXT NOT NULL,
file_hash TEXT NOT NULL,
import_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
row_count INTEGER NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT 'completed',
notes TEXT,
FOREIGN KEY (source_id) REFERENCES import_sources(id) ON DELETE CASCADE,
UNIQUE(source_id, filename)
);
CREATE TABLE IF NOT EXISTS categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
parent_id INTEGER,
color TEXT,
icon TEXT,
type TEXT NOT NULL DEFAULT 'expense',
is_active INTEGER NOT NULL DEFAULT 1,
is_inputable INTEGER NOT NULL DEFAULT 1,
sort_order INTEGER NOT NULL DEFAULT 0,
i18n_key TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (parent_id) REFERENCES categories(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS suppliers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
normalized_name TEXT NOT NULL,
category_id INTEGER,
is_active INTEGER NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS keywords (
id INTEGER PRIMARY KEY AUTOINCREMENT,
keyword TEXT NOT NULL,
category_id INTEGER NOT NULL,
supplier_id INTEGER,
priority INTEGER NOT NULL DEFAULT 0,
is_active INTEGER NOT NULL DEFAULT 1,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE,
FOREIGN KEY (supplier_id) REFERENCES suppliers(id) ON DELETE SET NULL,
UNIQUE(keyword, category_id)
);
CREATE TABLE IF NOT EXISTS transactions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date DATE NOT NULL,
description TEXT NOT NULL,
amount REAL NOT NULL,
category_id INTEGER,
supplier_id INTEGER,
source_id INTEGER,
file_id INTEGER,
original_description TEXT,
notes TEXT,
is_manually_categorized INTEGER NOT NULL DEFAULT 0,
is_split INTEGER NOT NULL DEFAULT 0,
parent_transaction_id INTEGER,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL,
FOREIGN KEY (supplier_id) REFERENCES suppliers(id) ON DELETE SET NULL,
FOREIGN KEY (source_id) REFERENCES import_sources(id) ON DELETE SET NULL,
FOREIGN KEY (file_id) REFERENCES imported_files(id) ON DELETE SET NULL,
FOREIGN KEY (parent_transaction_id) REFERENCES transactions(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS adjustments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
date DATE NOT NULL,
is_recurring INTEGER NOT NULL DEFAULT 0,
recurrence_rule TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS adjustment_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
adjustment_id INTEGER NOT NULL,
category_id INTEGER NOT NULL,
amount REAL NOT NULL,
description TEXT,
FOREIGN KEY (adjustment_id) REFERENCES adjustments(id) ON DELETE CASCADE,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS budget_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category_id INTEGER NOT NULL,
year INTEGER NOT NULL,
month INTEGER NOT NULL,
amount REAL NOT NULL,
notes TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE,
UNIQUE(category_id, year, month)
);
CREATE TABLE IF NOT EXISTS budget_templates (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
description TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS budget_template_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
template_id INTEGER NOT NULL,
category_id INTEGER NOT NULL,
amount REAL NOT NULL,
FOREIGN KEY (template_id) REFERENCES budget_templates(id) ON DELETE CASCADE,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE,
UNIQUE(template_id, category_id)
);
CREATE TABLE IF NOT EXISTS import_config_templates (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
delimiter TEXT NOT NULL DEFAULT ';',
encoding TEXT NOT NULL DEFAULT 'utf-8',
date_format TEXT NOT NULL DEFAULT 'DD/MM/YYYY',
skip_lines INTEGER NOT NULL DEFAULT 0,
has_header INTEGER NOT NULL DEFAULT 1,
column_mapping TEXT NOT NULL,
amount_mode TEXT NOT NULL DEFAULT 'single',
sign_convention TEXT NOT NULL DEFAULT 'negative_expense',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS user_preferences (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_transactions_date ON transactions(date);
CREATE INDEX IF NOT EXISTS idx_transactions_category ON transactions(category_id);
CREATE INDEX IF NOT EXISTS idx_transactions_supplier ON transactions(supplier_id);
CREATE INDEX IF NOT EXISTS idx_transactions_source ON transactions(source_id);
CREATE INDEX IF NOT EXISTS idx_transactions_file ON transactions(file_id);
CREATE INDEX IF NOT EXISTS idx_transactions_parent ON transactions(parent_transaction_id);
CREATE INDEX IF NOT EXISTS idx_categories_parent ON categories(parent_id);
CREATE INDEX IF NOT EXISTS idx_categories_type ON categories(type);
CREATE INDEX IF NOT EXISTS idx_suppliers_category ON suppliers(category_id);
CREATE INDEX IF NOT EXISTS idx_suppliers_normalized ON suppliers(normalized_name);
CREATE INDEX IF NOT EXISTS idx_keywords_category ON keywords(category_id);
CREATE INDEX IF NOT EXISTS idx_keywords_keyword ON keywords(keyword);
CREATE INDEX IF NOT EXISTS idx_budget_entries_period ON budget_entries(year, month);
CREATE INDEX IF NOT EXISTS idx_adjustment_entries_adjustment ON adjustment_entries(adjustment_id);
CREATE INDEX IF NOT EXISTS idx_imported_files_source ON imported_files(source_id);
-- ============================================================================
-- Balance sheet (Bilan) — Migration v9 mirror for new profiles
-- ============================================================================
-- 5 tables + 7 indexes + seeded categories. Kept in sync with
-- `balance_schema.sql` (the source of truth applied by Migration v9 in lib.rs).
-- New profiles created from this consolidated schema get the balance feature
-- preinstalled without needing to replay v9 separately.
CREATE TABLE IF NOT EXISTS balance_categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT NOT NULL UNIQUE,
i18n_key TEXT NOT NULL,
kind TEXT NOT NULL CHECK(kind IN ('simple','priced')),
sort_order INTEGER NOT NULL DEFAULT 0,
is_active INTEGER NOT NULL DEFAULT 1,
is_seed INTEGER NOT NULL DEFAULT 0,
asset_type TEXT CHECK(asset_type IS NULL OR asset_type IN ('stock','crypto')),
-- User-facing override for the category label (migration v12). When set,
-- the UI shows this verbatim; otherwise it falls back to t(i18n_key).
custom_label TEXT
);
CREATE TABLE IF NOT EXISTS balance_accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
balance_category_id INTEGER NOT NULL,
name TEXT NOT NULL,
symbol TEXT,
currency TEXT NOT NULL DEFAULT 'CAD' CHECK(currency = 'CAD'),
notes TEXT,
is_active INTEGER NOT NULL DEFAULT 1,
archived_at DATETIME,
-- Fiscal envelope / tax shelter (migration v12). NULL = no envelope (e.g.
-- a chequing account or crypto wallet). NOT an automobile type.
vehicle_type TEXT CHECK(vehicle_type IS NULL OR vehicle_type IN ('unregistered','tfsa','rrsp','rrif','fhsa','resp')),
-- Entry mode (migration v15). 'simple' = one denormalized value per
-- snapshot line; 'detailed' = a basket of per-security holdings (see
-- balance_snapshot_holdings). Accounts under a priced category are backfilled
-- to 'detailed' below. `detailed_since` is the authoritative pivot date from
-- which detailed entry is expected — NULL until the conversion flow sets it.
kind TEXT NOT NULL DEFAULT 'simple' CHECK (kind IN ('simple','detailed')),
detailed_since DATE,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (balance_category_id) REFERENCES balance_categories(id) ON DELETE RESTRICT
);
CREATE TABLE IF NOT EXISTS balance_snapshots (
id INTEGER PRIMARY KEY AUTOINCREMENT,
snapshot_date DATE NOT NULL UNIQUE,
notes TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS balance_snapshot_lines (
id INTEGER PRIMARY KEY AUTOINCREMENT,
snapshot_id INTEGER NOT NULL,
account_id INTEGER NOT NULL,
quantity REAL,
unit_price REAL,
value REAL NOT NULL,
price_source TEXT,
price_fetched_at DATETIME,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (snapshot_id) REFERENCES balance_snapshots(id) ON DELETE CASCADE,
FOREIGN KEY (account_id) REFERENCES balance_accounts(id) ON DELETE RESTRICT,
UNIQUE(snapshot_id, account_id),
CHECK (
(quantity IS NULL AND unit_price IS NULL)
OR (quantity IS NOT NULL AND unit_price IS NOT NULL)
)
);
CREATE TABLE IF NOT EXISTS balance_account_transfers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
account_id INTEGER NOT NULL,
transaction_id INTEGER NOT NULL,
direction TEXT NOT NULL CHECK(direction IN ('in','out')),
notes TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (account_id) REFERENCES balance_accounts(id) ON DELETE CASCADE,
FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE RESTRICT,
UNIQUE(transaction_id, account_id)
);
-- Détail par titre (Bilan Étape 2, migration v14). Kept in sync with
-- `balance_holdings_schema.sql` (the source of truth applied by Migration v14
-- in lib.rs). balance_securities is the instrument catalogue (symbol normalized
-- upper/trim, COLLATE NOCASE UNIQUE); balance_snapshot_holdings is the per-title
-- breakdown of a detailed account's snapshot line.
CREATE TABLE IF NOT EXISTS balance_securities (
id INTEGER PRIMARY KEY AUTOINCREMENT,
symbol TEXT NOT NULL COLLATE NOCASE UNIQUE,
name TEXT,
currency TEXT NOT NULL DEFAULT 'CAD',
asset_type TEXT NOT NULL CHECK (asset_type IN ('stock','crypto')),
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS balance_snapshot_holdings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
snapshot_line_id INTEGER NOT NULL REFERENCES balance_snapshot_lines(id) ON DELETE CASCADE,
security_id INTEGER NOT NULL REFERENCES balance_securities(id) ON DELETE RESTRICT,
quantity REAL NOT NULL,
unit_price REAL NOT NULL,
value REAL NOT NULL,
book_cost REAL,
price_source TEXT,
price_fetched_at DATETIME,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (snapshot_line_id, security_id)
);
CREATE INDEX IF NOT EXISTS idx_balance_accounts_category ON balance_accounts(balance_category_id);
CREATE INDEX IF NOT EXISTS idx_balance_accounts_active ON balance_accounts(is_active) WHERE is_active = 1;
CREATE INDEX IF NOT EXISTS idx_balance_snapshot_lines_snapshot ON balance_snapshot_lines(snapshot_id);
CREATE INDEX IF NOT EXISTS idx_balance_snapshot_lines_account ON balance_snapshot_lines(account_id);
CREATE INDEX IF NOT EXISTS idx_balance_account_transfers_account ON balance_account_transfers(account_id);
CREATE INDEX IF NOT EXISTS idx_balance_account_transfers_transaction ON balance_account_transfers(transaction_id);
CREATE INDEX IF NOT EXISTS idx_balance_snapshots_date ON balance_snapshots(snapshot_date);
CREATE INDEX IF NOT EXISTS idx_balance_snapshot_holdings_line ON balance_snapshot_holdings(snapshot_line_id);
CREATE INDEX IF NOT EXISTS idx_balance_snapshot_holdings_security ON balance_snapshot_holdings(security_id);
-- Asset classes only (Bilan axe véhicule, Étape 1). The former `tfsa` / `rrsp`
-- seeds were fiscal envelopes, not asset classes — they now live on the account
-- as `vehicle_type` (see balance_accounts.vehicle_type). New profiles ship with
-- exactly 5 asset classes: Liquidités, Fonds/FNB, Actions, Crypto, Autres.
INSERT OR IGNORE INTO balance_categories (key, i18n_key, kind, sort_order, is_seed, asset_type) VALUES
('cash', 'balance.category.cash', 'simple', 10, 1, NULL),
('fund', 'balance.category.fund', 'simple', 40, 1, NULL),
('other', 'balance.category.other', 'simple', 50, 1, NULL),
('stock', 'balance.category.stock', 'priced', 60, 1, 'stock'),
('crypto', 'balance.category.crypto', 'priced', 70, 1, 'crypto');
-- Starter accounts (Issue #179): 4 plain accounts seeded for new profiles so
-- /balance lands non-empty. They are NOT marked as seed (no is_seed column on
-- balance_accounts) — once created they are indistinguishable from
-- user-created accounts and can be renamed/archived freely. Existing profiles
-- get the same 4 proposed via StarterAccountsModal on first /balance visit.
--
-- Bilan axe véhicule (Étape 1): the CELI / REER starters are no longer linked
-- to a `tfsa` / `rrsp` category (those seeds are gone). They now attach to the
-- `other` asset class and carry the envelope in `vehicle_type`. Linking them to
-- a deleted key would make the subselect return NULL → NOT NULL violation →
-- broken new-profile init, so the asset class MUST resolve to `other`.
INSERT INTO balance_accounts (balance_category_id, name, currency, is_active, vehicle_type) VALUES
((SELECT id FROM balance_categories WHERE key = 'cash'), 'Compte chèque', 'CAD', 1, NULL),
((SELECT id FROM balance_categories WHERE key = 'other'), 'CELI', 'CAD', 1, 'tfsa'),
((SELECT id FROM balance_categories WHERE key = 'other'), 'REER', 'CAD', 1, 'rrsp'),
((SELECT id FROM balance_categories WHERE key = 'other'), 'Compte non-enregistré', 'CAD', 1, NULL);
-- Détail par titre (migration v15 mirror): accounts under a priced category are
-- detailed-entry by default. The 4 starters above all sit under simple asset
-- classes (cash / other), so this is currently a no-op — kept at parity with the
-- v15 backfill so any future priced starter is stamped correctly.
UPDATE balance_accounts SET kind = 'detailed'
WHERE balance_category_id IN (SELECT id FROM balance_categories WHERE kind = 'priced');
-- Default preferences (new profiles ship with the v1 IPC taxonomy)
INSERT OR IGNORE INTO user_preferences (key, value) VALUES ('language', 'fr');
INSERT OR IGNORE INTO user_preferences (key, value) VALUES ('theme', 'light');
INSERT OR IGNORE INTO user_preferences (key, value) VALUES ('currency', 'EUR');
INSERT OR IGNORE INTO user_preferences (key, value) VALUES ('date_format', 'DD/MM/YYYY');
INSERT OR REPLACE INTO user_preferences (key, value) VALUES ('categories_schema_version', 'v1');
-- Suppress StarterAccountsModal on first /balance visit for new profiles
-- (Issue #179). The 4 starter accounts are already seeded above, so the
-- modal would only show 4 collision rows with no actionable choice. Pre-
-- writing the pref skips that briefly-empty UX entirely. Suggestion S1
-- from PR #185 review (#187).
INSERT OR IGNORE INTO user_preferences (key, value) VALUES ('balance_starter_proposed', '{"shown_at":"seed","accepted":[]}');
-- ============================================================================
-- Seed v1 — IPC Statistique Canada-aligned, 3 levels, Canada/Québec
-- ----------------------------------------------------------------------------
-- Reset any pre-existing category data (possible when tauri-plugin-sql runs
-- the historical v2 seed migration on this fresh DB before this script
-- executes). Keywords/categories are wiped and re-inserted with the v1 IDs
-- (1000+ range) so existing references in migrations v3-v7 stay inert.
-- ============================================================================
DELETE FROM keywords;
UPDATE transactions SET category_id = NULL;
DELETE FROM categories;
-- LEVEL 1 — Roots (9 IPC components + Revenus + Transferts)
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1000, 'Revenus', NULL, 'income', '#16a34a', 0, 1, 'categoriesSeed.revenus.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1100, 'Alimentation', NULL, 'expense', '#ea580c', 0, 2, 'categoriesSeed.alimentation.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1200, 'Logement', NULL, 'expense', '#dc2626', 0, 3, 'categoriesSeed.logement.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1300, 'Ménage & ameublement', NULL, 'expense', '#ca8a04', 0, 4, 'categoriesSeed.menage.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1400, 'Vêtements & chaussures', NULL, 'expense', '#d946ef', 0, 5, 'categoriesSeed.vetements.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1500, 'Transport', NULL, 'expense', '#2563eb', 0, 6, 'categoriesSeed.transport.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1600, 'Santé & soins personnels', NULL, 'expense', '#f43f5e', 0, 7, 'categoriesSeed.sante.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1700, 'Loisirs, formation & lecture', NULL, 'expense', '#8b5cf6', 0, 8, 'categoriesSeed.loisirs.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1800, 'Boissons, tabac & cannabis', NULL, 'expense', '#7c3aed', 0, 9, 'categoriesSeed.consommation.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1900, 'Finances & obligations', NULL, 'expense', '#6b7280', 0, 10, 'categoriesSeed.finances.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1950, 'Transferts & placements', NULL, 'transfer', '#0ea5e9', 0, 11, 'categoriesSeed.transferts.root');
-- 1000 — Revenus
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1010, 'Emploi', 1000, 'income', '#22c55e', 0, 1, 'categoriesSeed.revenus.emploi.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1011, 'Paie régulière', 1010, 'income', '#22c55e', 1, 1, 'categoriesSeed.revenus.emploi.paie');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1012, 'Primes & bonus', 1010, 'income', '#4ade80', 1, 2, 'categoriesSeed.revenus.emploi.primes');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1013, 'Travail autonome', 1010, 'income', '#86efac', 1, 3, 'categoriesSeed.revenus.emploi.autonome');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1020, 'Gouvernemental', 1000, 'income', '#16a34a', 0, 2, 'categoriesSeed.revenus.gouvernemental.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1021, 'Remboursement impôt', 1020, 'income', '#16a34a', 1, 1, 'categoriesSeed.revenus.gouvernemental.remboursementImpot');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1022, 'Allocations familiales', 1020, 'income', '#15803d', 1, 2, 'categoriesSeed.revenus.gouvernemental.allocations');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1023, 'Crédits TPS/TVQ', 1020, 'income', '#166534', 1, 3, 'categoriesSeed.revenus.gouvernemental.credits');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1024, 'Assurance-emploi / RQAP', 1020, 'income', '#14532d', 1, 4, 'categoriesSeed.revenus.gouvernemental.assuranceEmploi');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1030, 'Revenus de placement', 1000, 'income', '#10b981', 0, 3, 'categoriesSeed.revenus.placement.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1031, 'Intérêts & dividendes', 1030, 'income', '#10b981', 1, 1, 'categoriesSeed.revenus.placement.interets');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1032, 'Gains en capital', 1030, 'income', '#059669', 1, 2, 'categoriesSeed.revenus.placement.capital');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1033, 'Revenus locatifs', 1030, 'income', '#047857', 1, 3, 'categoriesSeed.revenus.placement.locatifs');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1090, 'Autres revenus', 1000, 'income', '#84cc16', 1, 9, 'categoriesSeed.revenus.autres');
-- 1100 — Alimentation
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1110, 'Épicerie & marché', 1100, 'expense', '#ea580c', 0, 1, 'categoriesSeed.alimentation.epicerie.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1111, 'Épicerie régulière', 1110, 'expense', '#ea580c', 1, 1, 'categoriesSeed.alimentation.epicerie.reguliere');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1112, 'Boucherie & poissonnerie', 1110, 'expense', '#c2410c', 1, 2, 'categoriesSeed.alimentation.epicerie.boucherie');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1113, 'Boulangerie & pâtisserie', 1110, 'expense', '#9a3412', 1, 3, 'categoriesSeed.alimentation.epicerie.boulangerie');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1114, 'Dépanneur', 1110, 'expense', '#7c2d12', 1, 4, 'categoriesSeed.alimentation.epicerie.depanneur');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1115, 'Marché & produits spécialisés', 1110, 'expense', '#fb923c', 1, 5, 'categoriesSeed.alimentation.epicerie.marche');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1120, 'Restauration', 1100, 'expense', '#f97316', 0, 2, 'categoriesSeed.alimentation.restauration.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1121, 'Restaurant', 1120, 'expense', '#f97316', 1, 1, 'categoriesSeed.alimentation.restauration.restaurant');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1122, 'Café & boulangerie rapide', 1120, 'expense', '#fb923c', 1, 2, 'categoriesSeed.alimentation.restauration.cafe');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1123, 'Restauration rapide', 1120, 'expense', '#fdba74', 1, 3, 'categoriesSeed.alimentation.restauration.fastfood');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1124, 'Livraison à domicile', 1120, 'expense', '#fed7aa', 1, 4, 'categoriesSeed.alimentation.restauration.livraison');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1125, 'Cantine & cafétéria', 1120, 'expense', '#ffedd5', 1, 5, 'categoriesSeed.alimentation.restauration.cantine');
-- 1200 — Logement
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1210, 'Habitation principale', 1200, 'expense', '#dc2626', 0, 1, 'categoriesSeed.logement.habitation.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1211, 'Loyer', 1210, 'expense', '#dc2626', 1, 1, 'categoriesSeed.logement.habitation.loyer');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1212, 'Hypothèque', 1210, 'expense', '#b91c1c', 1, 2, 'categoriesSeed.logement.habitation.hypotheque');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1213, 'Taxes municipales & scolaires', 1210, 'expense', '#991b1b', 1, 3, 'categoriesSeed.logement.habitation.taxes');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1214, 'Charges de copropriété', 1210, 'expense', '#7f1d1d', 1, 4, 'categoriesSeed.logement.habitation.copropriete');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1220, 'Services publics', 1200, 'expense', '#ef4444', 0, 2, 'categoriesSeed.logement.services.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1221, 'Électricité', 1220, 'expense', '#ef4444', 1, 1, 'categoriesSeed.logement.services.electricite');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1222, 'Gaz naturel', 1220, 'expense', '#f87171', 1, 2, 'categoriesSeed.logement.services.gaz');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1223, 'Chauffage (mazout, propane)', 1220, 'expense', '#fca5a5', 1, 3, 'categoriesSeed.logement.services.chauffage');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1224, 'Eau & égouts', 1220, 'expense', '#fecaca', 1, 4, 'categoriesSeed.logement.services.eau');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1230, 'Communications', 1200, 'expense', '#6366f1', 0, 3, 'categoriesSeed.logement.communications.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1231, 'Internet résidentiel', 1230, 'expense', '#6366f1', 1, 1, 'categoriesSeed.logement.communications.internet');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1232, 'Téléphonie mobile', 1230, 'expense', '#818cf8', 1, 2, 'categoriesSeed.logement.communications.mobile');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1233, 'Téléphonie résidentielle', 1230, 'expense', '#a5b4fc', 1, 3, 'categoriesSeed.logement.communications.residentielle');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1234, 'Câblodistribution & streaming TV', 1230, 'expense', '#c7d2fe', 1, 4, 'categoriesSeed.logement.communications.streamingTv');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1240, 'Entretien & réparations', 1200, 'expense', '#e11d48', 0, 4, 'categoriesSeed.logement.entretien.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1241, 'Entretien général', 1240, 'expense', '#e11d48', 1, 1, 'categoriesSeed.logement.entretien.general');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1242, 'Rénovations', 1240, 'expense', '#be123c', 1, 2, 'categoriesSeed.logement.entretien.renovations');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1243, 'Matériaux & outils', 1240, 'expense', '#9f1239', 1, 3, 'categoriesSeed.logement.entretien.materiaux');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1244, 'Aménagement paysager', 1240, 'expense', '#881337', 1, 4, 'categoriesSeed.logement.entretien.paysager');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1250, 'Assurance habitation', 1200, 'expense', '#14b8a6', 1, 5, 'categoriesSeed.logement.assurance');
-- 1300 — Ménage & ameublement
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1310, 'Ameublement', 1300, 'expense', '#ca8a04', 0, 1, 'categoriesSeed.menage.ameublement.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1311, 'Meubles', 1310, 'expense', '#ca8a04', 1, 1, 'categoriesSeed.menage.ameublement.meubles');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1312, 'Électroménagers', 1310, 'expense', '#a16207', 1, 2, 'categoriesSeed.menage.ameublement.electromenagers');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1313, 'Décoration', 1310, 'expense', '#854d0e', 1, 3, 'categoriesSeed.menage.ameublement.decoration');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1320, 'Fournitures ménagères', 1300, 'expense', '#eab308', 0, 2, 'categoriesSeed.menage.fournitures.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1321, 'Produits d''entretien', 1320, 'expense', '#eab308', 1, 1, 'categoriesSeed.menage.fournitures.entretien');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1322, 'Literie & linge de maison', 1320, 'expense', '#facc15', 1, 2, 'categoriesSeed.menage.fournitures.literie');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1323, 'Vaisselle & ustensiles', 1320, 'expense', '#fde047', 1, 3, 'categoriesSeed.menage.fournitures.vaisselle');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1330, 'Services domestiques', 1300, 'expense', '#fbbf24', 0, 3, 'categoriesSeed.menage.services.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1331, 'Ménage & nettoyage', 1330, 'expense', '#fbbf24', 1, 1, 'categoriesSeed.menage.services.nettoyage');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1332, 'Buanderie & pressing', 1330, 'expense', '#fcd34d', 1, 2, 'categoriesSeed.menage.services.buanderie');
-- 1400 — Vêtements & chaussures
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1410, 'Vêtements adultes', 1400, 'expense', '#d946ef', 1, 1, 'categoriesSeed.vetements.adultes');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1420, 'Vêtements enfants', 1400, 'expense', '#c026d3', 1, 2, 'categoriesSeed.vetements.enfants');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1430, 'Chaussures', 1400, 'expense', '#a21caf', 1, 3, 'categoriesSeed.vetements.chaussures');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1440, 'Accessoires & bijoux', 1400, 'expense', '#86198f', 1, 4, 'categoriesSeed.vetements.accessoires');
-- 1500 — Transport
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1510, 'Véhicule personnel', 1500, 'expense', '#2563eb', 0, 1, 'categoriesSeed.transport.vehicule.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1511, 'Achat / location véhicule', 1510, 'expense', '#2563eb', 1, 1, 'categoriesSeed.transport.vehicule.achat');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1512, 'Essence', 1510, 'expense', '#1d4ed8', 1, 2, 'categoriesSeed.transport.vehicule.essence');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1513, 'Entretien & réparations auto', 1510, 'expense', '#1e40af', 1, 3, 'categoriesSeed.transport.vehicule.entretien');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1514, 'Immatriculation & permis', 1510, 'expense', '#1e3a8a', 1, 4, 'categoriesSeed.transport.vehicule.immatriculation');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1515, 'Stationnement & péages', 1510, 'expense', '#3b82f6', 1, 5, 'categoriesSeed.transport.vehicule.stationnement');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1516, 'Assurance auto', 1510, 'expense', '#60a5fa', 1, 6, 'categoriesSeed.transport.vehicule.assurance');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1520, 'Transport public', 1500, 'expense', '#0ea5e9', 0, 2, 'categoriesSeed.transport.public.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1521, 'Autobus & métro', 1520, 'expense', '#0ea5e9', 1, 1, 'categoriesSeed.transport.public.autobus');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1522, 'Train de banlieue', 1520, 'expense', '#0284c7', 1, 2, 'categoriesSeed.transport.public.train');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1523, 'Taxi & covoiturage', 1520, 'expense', '#0369a1', 1, 3, 'categoriesSeed.transport.public.taxi');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1530, 'Voyages longue distance', 1500, 'expense', '#38bdf8', 0, 3, 'categoriesSeed.transport.voyages.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1531, 'Avion', 1530, 'expense', '#38bdf8', 1, 1, 'categoriesSeed.transport.voyages.avion');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1532, 'Train & autocar', 1530, 'expense', '#7dd3fc', 1, 2, 'categoriesSeed.transport.voyages.trainAutocar');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1533, 'Hébergement', 1530, 'expense', '#bae6fd', 1, 3, 'categoriesSeed.transport.voyages.hebergement');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1534, 'Location véhicule voyage', 1530, 'expense', '#e0f2fe', 1, 4, 'categoriesSeed.transport.voyages.location');
-- 1600 — Santé & soins personnels
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1610, 'Soins médicaux', 1600, 'expense', '#f43f5e', 0, 1, 'categoriesSeed.sante.medicaux.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1611, 'Pharmacie', 1610, 'expense', '#f43f5e', 1, 1, 'categoriesSeed.sante.medicaux.pharmacie');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1612, 'Consultations médicales', 1610, 'expense', '#e11d48', 1, 2, 'categoriesSeed.sante.medicaux.consultations');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1613, 'Dentiste & orthodontiste', 1610, 'expense', '#be123c', 1, 3, 'categoriesSeed.sante.medicaux.dentiste');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1614, 'Optométrie & lunettes', 1610, 'expense', '#9f1239', 1, 4, 'categoriesSeed.sante.medicaux.optometrie');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1615, 'Thérapies (physio, psycho, etc.)', 1610, 'expense', '#881337', 1, 5, 'categoriesSeed.sante.medicaux.therapies');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1616, 'Assurance santé complémentaire', 1610, 'expense', '#fb7185', 1, 6, 'categoriesSeed.sante.medicaux.assurance');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1620, 'Soins personnels', 1600, 'expense', '#fb7185', 0, 2, 'categoriesSeed.sante.personnels.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1621, 'Coiffure & esthétique', 1620, 'expense', '#fb7185', 1, 1, 'categoriesSeed.sante.personnels.coiffure');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1622, 'Produits de soins corporels', 1620, 'expense', '#fda4af', 1, 2, 'categoriesSeed.sante.personnels.soins');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1630, 'Assurance vie & invalidité', 1600, 'expense', '#14b8a6', 1, 3, 'categoriesSeed.sante.assuranceVie');
-- 1700 — Loisirs, formation & lecture
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1710, 'Divertissement', 1700, 'expense', '#8b5cf6', 0, 1, 'categoriesSeed.loisirs.divertissement.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1711, 'Cinéma & spectacles', 1710, 'expense', '#8b5cf6', 1, 1, 'categoriesSeed.loisirs.divertissement.cinema');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1712, 'Jeux vidéo & consoles', 1710, 'expense', '#a78bfa', 1, 2, 'categoriesSeed.loisirs.divertissement.jeux');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1713, 'Streaming vidéo', 1710, 'expense', '#c4b5fd', 1, 3, 'categoriesSeed.loisirs.divertissement.streamingVideo');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1714, 'Streaming musique & audio', 1710, 'expense', '#ddd6fe', 1, 4, 'categoriesSeed.loisirs.divertissement.streamingMusique');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1715, 'Jouets & passe-temps', 1710, 'expense', '#ede9fe', 1, 5, 'categoriesSeed.loisirs.divertissement.jouets');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1720, 'Sports & plein air', 1700, 'expense', '#22c55e', 0, 2, 'categoriesSeed.loisirs.sports.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1721, 'Abonnements sportifs', 1720, 'expense', '#22c55e', 1, 1, 'categoriesSeed.loisirs.sports.abonnements');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1722, 'Équipement sportif', 1720, 'expense', '#4ade80', 1, 2, 'categoriesSeed.loisirs.sports.equipement');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1723, 'Parcs & activités plein air', 1720, 'expense', '#86efac', 1, 3, 'categoriesSeed.loisirs.sports.parcs');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1730, 'Formation & éducation', 1700, 'expense', '#6366f1', 0, 3, 'categoriesSeed.loisirs.formation.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1731, 'Scolarité (frais)', 1730, 'expense', '#6366f1', 1, 1, 'categoriesSeed.loisirs.formation.scolarite');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1732, 'Matériel scolaire', 1730, 'expense', '#818cf8', 1, 2, 'categoriesSeed.loisirs.formation.materiel');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1733, 'Cours & certifications', 1730, 'expense', '#a5b4fc', 1, 3, 'categoriesSeed.loisirs.formation.cours');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1734, 'Abonnements professionnels', 1730, 'expense', '#c7d2fe', 1, 4, 'categoriesSeed.loisirs.formation.abonnements');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1740, 'Lecture & médias', 1700, 'expense', '#ec4899', 0, 4, 'categoriesSeed.loisirs.lecture.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1741, 'Livres', 1740, 'expense', '#ec4899', 1, 1, 'categoriesSeed.loisirs.lecture.livres');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1742, 'Journaux & magazines', 1740, 'expense', '#f472b6', 1, 2, 'categoriesSeed.loisirs.lecture.journaux');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1750, 'Animaux de compagnie', 1700, 'expense', '#a855f7', 0, 5, 'categoriesSeed.loisirs.animaux.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1751, 'Nourriture & accessoires animaux', 1750, 'expense', '#a855f7', 1, 1, 'categoriesSeed.loisirs.animaux.nourriture');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1752, 'Vétérinaire', 1750, 'expense', '#c084fc', 1, 2, 'categoriesSeed.loisirs.animaux.veterinaire');
-- 1800 — Boissons, tabac & cannabis
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1810, 'Alcool (SAQ, microbrasseries)', 1800, 'expense', '#7c3aed', 1, 1, 'categoriesSeed.consommation.alcool');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1820, 'Cannabis (SQDC)', 1800, 'expense', '#6d28d9', 1, 2, 'categoriesSeed.consommation.cannabis');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1830, 'Tabac', 1800, 'expense', '#5b21b6', 1, 3, 'categoriesSeed.consommation.tabac');
-- 1900 — Finances & obligations
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1910, 'Frais bancaires', 1900, 'expense', '#6b7280', 0, 1, 'categoriesSeed.finances.fraisBancaires.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1911, 'Frais de compte', 1910, 'expense', '#6b7280', 1, 1, 'categoriesSeed.finances.fraisBancaires.compte');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1912, 'Intérêts & frais de crédit', 1910, 'expense', '#9ca3af', 1, 2, 'categoriesSeed.finances.fraisBancaires.interets');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1913, 'Frais de change', 1910, 'expense', '#d1d5db', 1, 3, 'categoriesSeed.finances.fraisBancaires.change');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1920, 'Impôts & taxes', 1900, 'expense', '#dc2626', 0, 2, 'categoriesSeed.finances.impots.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1921, 'Impôt fédéral', 1920, 'expense', '#dc2626', 1, 1, 'categoriesSeed.finances.impots.federal');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1922, 'Impôt provincial', 1920, 'expense', '#b91c1c', 1, 2, 'categoriesSeed.finances.impots.provincial');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1923, 'Acomptes provisionnels', 1920, 'expense', '#991b1b', 1, 3, 'categoriesSeed.finances.impots.acomptes');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1930, 'Dons & cotisations', 1900, 'expense', '#ec4899', 0, 3, 'categoriesSeed.finances.dons.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1931, 'Dons de charité', 1930, 'expense', '#ec4899', 1, 1, 'categoriesSeed.finances.dons.charite');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1932, 'Cotisations professionnelles', 1930, 'expense', '#f472b6', 1, 2, 'categoriesSeed.finances.dons.professionnelles');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1933, 'Cotisations syndicales', 1930, 'expense', '#f9a8d4', 1, 3, 'categoriesSeed.finances.dons.syndicales');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1940, 'Cadeaux', 1900, 'expense', '#f43f5e', 1, 4, 'categoriesSeed.finances.cadeaux');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1945, 'Retrait cash', 1900, 'expense', '#57534e', 1, 5, 'categoriesSeed.finances.cash');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1946, 'Achats divers non catégorisés', 1900, 'expense', '#78716c', 1, 6, 'categoriesSeed.finances.divers');
-- 1950 — Transferts & placements
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1960, 'Épargne & placements', 1950, 'transfer', '#0ea5e9', 0, 1, 'categoriesSeed.transferts.epargne.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1961, 'REER / RRSP', 1960, 'transfer', '#0ea5e9', 1, 1, 'categoriesSeed.transferts.epargne.reer');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1962, 'CELI / TFSA', 1960, 'transfer', '#0284c7', 1, 2, 'categoriesSeed.transferts.epargne.celi');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1963, 'REEE / RESP', 1960, 'transfer', '#0369a1', 1, 3, 'categoriesSeed.transferts.epargne.reee');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1964, 'Compte non-enregistré', 1960, 'transfer', '#075985', 1, 4, 'categoriesSeed.transferts.epargne.nonEnregistre');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1965, 'Fonds d''urgence', 1960, 'transfer', '#0c4a6e', 1, 5, 'categoriesSeed.transferts.epargne.urgence');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1970, 'Remboursement de dette', 1950, 'transfer', '#7c3aed', 0, 2, 'categoriesSeed.transferts.dette.root');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1971, 'Paiement carte crédit', 1970, 'transfer', '#7c3aed', 1, 1, 'categoriesSeed.transferts.dette.carteCredit');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1972, 'Remboursement prêt étudiant', 1970, 'transfer', '#8b5cf6', 1, 2, 'categoriesSeed.transferts.dette.etudiant');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1973, 'Remboursement prêt perso', 1970, 'transfer', '#a78bfa', 1, 3, 'categoriesSeed.transferts.dette.personnel');
INSERT INTO categories (id, name, parent_id, type, color, is_inputable, sort_order, i18n_key) VALUES (1980, 'Transferts internes', 1950, 'transfer', '#64748b', 1, 3, 'categoriesSeed.transferts.internes');
-- ============================================================================
-- Keywords — Canadian suppliers (150+ entries)
-- ============================================================================
-- Alimentation > Épicerie régulière (1111)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('METRO', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('IGA', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('MAXI', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SUPER C', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('LOBLAWS', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PROVIGO', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ADONIS', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('WHOLE FOODS', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('AVRIL', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('RACHELLE-BERY', 1111, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('COSTCO', 1111, 50);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('WALMART', 1111, 50);
-- Épicerie > Boucherie (1112)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BOUCHERIE', 1112, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('POISSONNERIE', 1112, 0);
-- Épicerie > Boulangerie (1113)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BOULANGERIE', 1113, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PATISSERIE', 1113, 0);
-- Épicerie > Dépanneur (1114)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('COUCHE-TARD', 1114, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DEPANNEUR', 1114, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('7-ELEVEN', 1114, 0);
-- Restauration > Restaurant (1121)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('RESTAURANT', 1121, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BRASSERIE', 1121, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BISTRO', 1121, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SUSHI', 1121, 0);
-- Restauration > Café (1122)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('STARBUCKS', 1122, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TIM HORTONS', 1122, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SECOND CUP', 1122, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('VAN HOUTTE', 1122, 0);
-- Restauration > Fast food (1123)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('MCDONALD', 1123, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SUBWAY', 1123, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('A&W', 1123, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BURGER KING', 1123, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('KFC', 1123, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DOMINOS', 1123, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PIZZA HUT', 1123, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BELLE PROVINCE', 1123, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ST-HUBERT', 1123, 0);
-- Restauration > Livraison (1124)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DOORDASH', 1124, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DD/DOORDASH', 1124, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('UBER EATS', 1124, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SKIPTHEDISHES', 1124, 0);
-- Logement > Hypothèque (1212)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('MTG/HYP', 1212, 0);
-- Logement > Taxes municipales (1213)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('M-ST-HILAIRE TX', 1213, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TAXES MUNICIPALES', 1213, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CSS PATRIOT', 1213, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TAXE SCOLAIRE', 1213, 0);
-- Électricité (1221)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('HYDRO-QUEBEC', 1221, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('HYDRO QUEBEC', 1221, 0);
-- Gaz (1222)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ENERGIR', 1222, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('GAZ METRO', 1222, 0);
-- Internet (1231)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('VIDEOTRON', 1231, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BELL INTERNET', 1231, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ORICOM', 1231, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('COGECO', 1231, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('EBOX', 1231, 0);
-- Mobile (1232)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('FIZZ', 1232, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('KOODO', 1232, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PUBLIC MOBILE', 1232, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('VIRGIN', 1232, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BELL MOBILITE', 1232, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TELUS MOBILE', 1232, 0);
-- Entretien maison (1241)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('IKEA', 1241, 0);
-- Matériaux & outils (1243)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CANADIAN TIRE', 1243, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CANAC', 1243, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('RONA', 1243, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('HOME DEPOT', 1243, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BMR', 1243, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PRINCESS AUTO', 1243, 0);
-- Assurance habitation (1250)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BELAIR', 1250, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PRYSM', 1250, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('INTACT ASSURANCE', 1250, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DESJARDINS ASSURANCE', 1250, 0);
-- Meubles (1311)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TANGUAY', 1311, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('LEON', 1311, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('STRUCTUBE', 1311, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BRICK', 1311, 0);
-- Électroménagers (1312)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BEST BUY', 1312, 0);
-- Décoration (1313)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BOUCLAIR', 1313, 0);
-- Vêtements (1410)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('UNIQLO', 1410, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('WINNERS', 1410, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SIMONS', 1410, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('MARKS', 1410, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('H&M', 1410, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('OLD NAVY', 1410, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('GAP', 1410, 0);
-- Transport — Essence (1512)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SHELL', 1512, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ESSO', 1512, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ULTRAMAR', 1512, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PETRO-CANADA', 1512, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PETRO CANADA', 1512, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CREVIER', 1512, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('HARNOIS', 1512, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('COUCHE-TARD ESSENCE', 1512, 10);
-- Permis / SAAQ (1514)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SAAQ', 1514, 0);
-- Transport public — autobus/métro (1521)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('STM', 1521, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('RTC', 1521, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('STL', 1521, 0);
-- Train de banlieue (1522)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('GARE MONT-SAINT', 1522, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('GARE SAINT-HUBERT', 1522, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('GARE CENTRALE', 1522, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('EXO', 1522, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('REM', 1522, 0);
-- Taxi / Uber (1523)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('UBER', 1523, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('LYFT', 1523, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TAXI', 1523, 0);
-- Avion (1531)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('AIR CANADA', 1531, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('WESTJET', 1531, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('AIR TRANSAT', 1531, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PORTER', 1531, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('AEROPORTS DE MONTREAL', 1531, 0);
-- Hébergement (1533)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('AIRBNB', 1533, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('HILTON', 1533, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('MARRIOTT', 1533, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BOOKING.COM', 1533, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('NORWEGIAN CRUISE', 1533, 0);
-- Pharmacie (1611)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('JEAN COUTU', 1611, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('FAMILIPRIX', 1611, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PHARMAPRIX', 1611, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PROXIM', 1611, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('UNIPRIX', 1611, 0);
-- Thérapies (1615)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PHYSIOACTIF', 1615, 0);
-- Cinéma & spectacles (1711)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CINEPLEX', 1711, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CINEMA DU PARC', 1711, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TICKETMASTER', 1711, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CLUB SODA', 1711, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('LEPOINTDEVENTE', 1711, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('EVENBRITE', 1711, 0);
-- Jeux vidéo (1712)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('STEAMGAMES', 1712, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PLAYSTATION', 1712, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('NINTENDO', 1712, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('XBOX', 1712, 0);
-- Streaming vidéo (1713)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('NETFLIX', 1713, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PRIMEVIDEO', 1713, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DISNEY PLUS', 1713, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CRAVE', 1713, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('APPLE TV', 1713, 0);
-- Streaming musique (1714)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SPOTIFY', 1714, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('APPLE MUSIC', 1714, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('YOUTUBE MUSIC', 1714, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TIDAL', 1714, 0);
-- Jouets & hobbies (1715)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('LEGO', 1715, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('TOYS R US', 1715, 0);
-- Équipement sportif (1722)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('MOUNTAIN EQUIPMENT', 1722, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('LA CORDEE', 1722, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DECATHLON', 1722, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SPORTS EXPERTS', 1722, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ATMOSPHERE', 1722, 0);
-- Parcs & activités (1723)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SEPAQ', 1723, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('BLOC SHOP', 1723, 0);
-- Lecture (1741)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('RENAUD-BRAY', 1741, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('INDIGO', 1741, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ARCHAMBAULT', 1741, 0);
-- Animaux — nourriture (1751)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('MONDOU', 1751, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PET SMART', 1751, 0);
-- Alcool (1810)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SAQ', 1810, 0);
-- Cannabis (1820)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('SQDC', 1820, 0);
-- Frais bancaires (1911)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PROGRAMME PERFORMANCE', 1911, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('FRAIS MENSUELS', 1911, 0);
-- Impôts (1921, 1922)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('GOUV. QUEBEC', 1922, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('REVENU QUEBEC', 1922, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ARC IMPOT', 1921, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CRA TAX', 1921, 0);
-- Dons de charité (1931)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('OXFAM', 1931, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CENTRAIDE', 1931, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('FPA', 1931, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CROIX-ROUGE', 1931, 0);
-- Cotisations professionnelles (1932)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('ORDRE DES COMPTABL', 1932, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('CPA CANADA', 1932, 0);
-- Cadeaux (1940)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DANS UN JARDIN', 1940, 0);
-- Divers (1946) — catch-all marketplace
INSERT INTO keywords (keyword, category_id, priority) VALUES ('AMAZON', 1946, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('AMZN', 1946, 0);
-- Placements (1964)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('WS INVESTMENTS', 1964, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('WEALTHSIMPLE', 1964, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PEAK INVESTMENT', 1964, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DYNAMIC FUND', 1964, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('FIDELITY', 1964, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('AGF', 1964, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('QUESTRADE', 1964, 0);
-- Paie (1011)
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PAY/PAY', 1011, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('DEPOT PAIE', 1011, 0);
INSERT INTO keywords (keyword, category_id, priority) VALUES ('PAYROLL', 1011, 0);