Security
What Investment Portfolio Manager can read and write, what it stores, and what leaves your instance.
Access model
- Company isolation — global record rules on every investment model (portfolios, accounts, events, charges, policies, runs, snapshots, reconciliation, import batches/rows/issues, proposals, audit). They bind everybody, including holders of Odoo accounting groups.
- Portfolio restriction — a portfolio with restrict access is visible only to its listed users (and investment administrators); the rule applies to its events, runs, positions, cash, policies, reconciliation, import batches and rows, and proposals.
- Attachments (statement files, evidence) belong to their record, so Odoo's attachment access follows the record's rules.
- Reports and exports read through the same rules; a report wizard for a portfolio the user cannot read fails at creation.
- Background jobs run as the user who queued the work.
- Separation of duties — operators record; reviewers decide discrepancies; accountants create draft entries; posting needs Odoo accounting rights; reconciliation adjustments need an administrator.
- Account numbers — the full broker account reference is visible to administrators only; others see ••••••1234.
Tested in tests/test_security.py (core), TestImportSecurity (import) and the bridge's access tests.
Audit trail
invest.audit.entry — append-only (no edit, no delete through the ORM): confirmations (one entry per event; one summary entry for bulk import confirmations), reversals and corrections with reasons, transfers, policy changes, access changes, uploads/commits with file SHA-256 and profile version, reviewer decisions, reconciliation decisions, adjustments, valuation runs and accounting actions. Chatter tracking complements it.
Immutability
Confirmed events are protected twice: the ORM refuses edits and deletes, and a PostgreSQL trigger (invest_event_guard) refuses them even for raw SQL. Corrections are linked reversals. Duplicate identities are unique indexes (broker account + external reference among confirmed events; one event per statement row; one reversal per event; one file per broker account).
Logging and sensitive data
The product does not log statement contents, account numbers or credentials. Statement files are stored as attachments of their batch (needed as evidence); restrict access through portfolio rules. No external service is called.
Retention
Nothing is deleted automatically. Recommended practice:
- keep ledger events, statement files, batches and audit entries for your statutory retention period (commonly several years — confirm yours);
- valuation runs are reproducible from the ledger and can be archived or deleted by an administrator after the period is closed;
- do not delete staged rows of committed batches: they are the link from an event back to its statement line.
Backup and restore
Use Odoo's standard database backup (database + filestore). Statement files live in the filestore; a database-only backup loses them. After restoring to another server, the PostgreSQL immutability trigger is part of the schema and comes back with it. Test a restore: open a portfolio, recalculate a past valuation date and compare with the stored run.
Uninstall
- Uninstalling core removes the investment tables (ledger included). Export the reports you must keep first.
- Uninstalling the accounting bridge is refused while posted journal entries are linked to investment events, unless the system parameter technovision_investment_accounting.allow_uninstall is set to 1. Posted entries always stay in Accounting (their reference and narration name the investment event); only the link back is lost. The bridge never deletes a posted entry.
- Uninstalling the importer removes batches and staged rows; events keep their evidence note naming the file and row.
Resilience
- Every confirmation serializes on a row lock of the portfolio (ordered, deadlock-free), so concurrent confirmations and imports cannot oversell.
- Import commits run in atomic chunks; batches are claimed with FOR UPDATE SKIP LOCKED; an interrupted run resumes without duplicates.
- Backdated events mark valuations stale; nothing is silently recomputed into locked accounting periods.