Audience: admins, support engineers, sales engineering Difficulty: intermediate
What this covers
Every Solabooks feature flag, the plan tier(s) on which it is enabled by
default, where it shows up in the UI, the backend gate (route
middleware, policy, or controller authorize()), and any audit-flagged
mismatch.
Sources of truth:
database/seeders/PlanFeatureSeeder.php— writes feature definitions toplan_features.config/features.catalog.php(parent) — 108 entries, the central catalog.database/seeders/ProjectPlanSeeder.php— per-tierfeature_overrides.config/finance_features.php(finance) — 88featureskeys + 103permission_mapentries.
Solabooks plan tiers
Defined in database/seeders/ProjectPlanSeeder.php.
| Tier slug | Display | Price | Max users | Max orgs |
|---|---|---|---|---|
standard |
Free | $0.00 | 2 / 2 | 1 |
professional |
Professional | $25.00 | 5 / 5 | unlimited |
premium |
Premium | $35.00 | 8 / 8 | unlimited |
enterprise |
Enterprise | $100.00 | unlimited | unlimited |
Bundles (BundleSeeder.php) sum finance + inventory at the same tier
slug to produce: Starter (standard), Business (premium), Enterprise
(enterprise).
Feature flags by area
Each row gives the UI surface, the gate, and which plan turns it on.
"Default" means the value declared in config/finance_features.php —
plan tiers can override.
Core accounting & sales (always on at standard+)
| Feature | App | Plans | UI Location | Backend gate | Notes |
|---|---|---|---|---|---|
tracker.chart_of_accounts |
Solabooks | all | Solabooks > Accounting > Chart of Accounts | route accounts/*, perm:accounts.* |
default true |
tracker.manual_journals |
Solabooks | all | Solabooks > Accounting > Journal Entries | route entries/*, perm:journals.* |
default true |
tracker.dashboard |
Solabooks | all | Solabooks > Dashboard | feature:tracker.dashboard on /dashboard |
default true |
tracker.invoices |
Solabooks | all | Solabooks > Sales > Invoices | feature:tracker.invoices on ar/invoices/* |
default true |
tracker.quotes_estimates |
Solabooks | all | Solabooks > Sales > Quotes | feature:tracker.quotes_estimates on ar/quotes/* |
default true |
tracker.credit_notes |
Solabooks | all | Solabooks > Sales > Credit Notes | feature:tracker.credit_notes |
default true |
tracker.sales_receipts |
Solabooks | all | Solabooks > Sales > Receipts | feature:tracker.sales_receipts |
default true |
tracker.record_offline_payments |
Solabooks | all | Solabooks > Sales > Customer Payments | feature:tracker.record_offline_payments |
default true |
tracker.bills |
Solabooks | all | Solabooks > Purchases > Bills | feature:tracker.bills on ap/bills/* |
default true |
tracker.expenses_direct_pay |
Solabooks | all | Solabooks > Purchases > Expenses | feature:tracker.expenses_direct_pay |
default true |
tracker.record_payments_made |
Solabooks | all | Solabooks > Purchases > Bill Payments | feature:tracker.record_payments_made |
default true |
tracker.vendor_credits_debit_notes |
Solabooks | all | Solabooks > Purchases > Debit Notes | feature:tracker.vendor_credits_debit_notes |
default true |
tracker.purchase_orders |
Solabooks | all | Solabooks > Purchases > Purchase Orders | feature:tracker.purchase_orders (+ enable_purchase_orders) |
default true |
tracker.manage_items |
Solabooks | all | Solabooks > Inventory > Items | feature:tracker.manage_items |
default true |
tracker.multiple_bank_credit_card_accounts |
Solabooks | all | Solabooks > Banking > Accounts | feature:tracker.multiple_bank_credit_card_accounts |
default true |
tracker.import_bank_statements |
Solabooks | all | Solabooks > Banking > Imports | feature:tracker.import_bank_statements |
default true |
tracker.bank_reconciliation |
Solabooks | all | Solabooks > Banking > Reconciliation | feature:tracker.bank_reconciliation (+ bank_reconciliation_enabled) |
default true |
Reports (default on)
| Feature | App | Plans | UI | Gate |
|---|---|---|---|---|
tracker.profit_loss_report |
Solabooks | all | Reports > Financial > P&L | feature:tracker.profit_loss_report |
tracker.balance_sheet_report |
Solabooks | all | Reports > Financial > Balance Sheet | feature:tracker.balance_sheet_report |
tracker.trial_balance_report |
Solabooks | all | Reports > Financial > Trial Balance | feature:tracker.trial_balance_report |
tracker.cash_flow_report |
Solabooks | all | Reports > Financial > Cash Flow | feature:tracker.cash_flow_report |
tracker.tax_reports |
Solabooks | all | Reports > Tax | feature:tracker.tax_reports |
tracker.vat_returns |
Solabooks | all | Reports > VAT > Returns | feature:tracker.vat_returns (+ vat_enabled) |
tracker.sales_reports_by_customer_item |
Solabooks | all | Reports > Sales | feature:tracker.sales_reports_by_customer_item |
tracker.purchase_reports_by_supplier_item |
Solabooks | all | Reports > Purchases | feature:tracker.purchase_reports_by_supplier_item |
Premium / paid-only (default false, enabled per plan)
| Feature | App | Plans (default) | UI | Gate |
|---|---|---|---|---|
tracker.sales_orders |
Solabooks | premium+ | AR > Sales Orders | feature:tracker.sales_orders + sales.use_sales_orders |
tracker.landed_costs |
Solabooks | premium+ | AP > Landed Costs | feature:tracker.landed_costs |
tracker.track_mileage_expenses |
Solabooks | premium+ | AP > Mileage | feature:tracker.track_mileage_expenses |
tracker.budgeting |
Solabooks | premium+ | Reports > Budgets | feature:tracker.budgeting |
tracker.manage_projects |
Solabooks | premium+ | Projects | feature:tracker.manage_projects |
tracker.project_tasks |
Solabooks | premium+ | Projects > Tasks | feature:tracker.project_tasks |
tracker.project_revenue |
Solabooks | enterprise | Projects > Revenue | – |
tracker.project_profitability |
Solabooks | enterprise | Projects > Profitability | – |
tracker.timesheets |
Solabooks | premium+ | Projects > Time | feature:tracker.timesheets |
tracker.time_approval |
Solabooks | premium+ | Projects > Time Approval | feature:tracker.time_approval |
tracker.time_billing |
Solabooks | enterprise | Projects > Time Billing | – |
tracker.reporting_tags_dimensions |
Solabooks | premium+ | Settings > Dimensions | feature:tracker.reporting_tags_dimensions |
tracker.custom_fields |
Solabooks | premium+ | Settings > Custom Fields | feature:tracker.custom_fields |
tracker.custom_views |
Solabooks | premium+ | (per-list) | – |
tracker.api_integration |
Solabooks | enterprise | Settings > API Access | feature:tracker.api_integration (+ finance_api_enabled) |
tracker.transaction_rules_auto_categorization |
Solabooks | premium+ | Banking > Rules | – |
tracker.schedule_reports |
Solabooks | premium+ | Reports > Scheduled | feature:tracker.schedule_reports |
tracker.recurring_invoices, tracker.recurring_bills, tracker.recurring_expenses, tracker.recurring_journals |
Solabooks | premium+ | Recurring | – |
tracker.sales_approval_workflow, tracker.purchase_approval_workflow |
Solabooks | enterprise | Settings > Workflow | (+ workflow_enabled) |
tracker.workflow_rules |
Solabooks | enterprise | Admin > Workflow Rules | feature:tracker.workflow_rules |
tracker.base_currency_adjustments |
Solabooks | enterprise | Accounting > Base FX | (+ multi_currency_enabled) |
Fixed Assets (premium tier-up)
tracker.fixed_assets, tracker.asset_depreciation,
tracker.asset_disposals, tracker.asset_transfers,
tracker.asset_reports, tracker.asset_approvals,
tracker.asset_disposal_approval, tracker.asset_transfer_approval,
tracker.asset_maintenance, tracker.asset_budgeting. Default false.
Premium turns on the register; Enterprise turns on the approval and
budgeting layers.
Org-level switches (independent of tier)
| Feature | Default | Effect when off |
|---|---|---|
vat_enabled |
true |
Hides all tax.*, vat_returns.*, reports.vat.* |
reverse_charge_enabled |
false |
Hides tax.reverse_charge |
multi_currency_enabled |
false |
Hides FX rates, base-currency adjustment |
period_locking_enabled |
true |
Period lock/unlock unavailable |
bank_reconciliation_enabled |
true |
Hides reconciliation, bank import, rules, templates |
inventory_enabled |
true |
Hides inventory views |
inventory.reorder_point |
false |
Hides reorder-point alerts |
pdf_templates_enabled |
true |
Hides settings/PDF templates |
workflow_enabled |
false |
Hides settings/workflow |
enable_purchase_orders |
true |
Hides AP > Purchase Orders |
enable_po_approvals, enable_po_receiving, enable_3_way_match |
false |
Inline PO workflow stages |
sales.use_sales_orders |
false |
Hides AR > Sales Orders |
finance_api_enabled |
false |
Hides Settings > API Access |
receipt_scan_enabled |
true |
Hides OCR scan |
price_lists, multiple_price_lists, price_list_per_customer, price_list_on_transactions, advanced_pricing_rules, pricing_rules, quantity_pricing, customer_group_pricing, budgets_enabled |
false |
Premium pricing/budget UI |
Audit-flagged mismatches (Phase 1)
The Phase 1 audit ran a diff between the feature: middleware tokens
in finance routes and the keys declared in config/finance_features.php.
Seven feature keys are referenced as middleware but not declared in
the features map:
| Undeclared key | Where used | Impact |
|---|---|---|
finance.retainers |
ar/retainers/* route group |
The EnsureFinanceFeatureEnabled middleware soft-fails on missing config. The route is effectively un-gated (or always-disabled). Behaviour needs confirmation in the middleware class. |
projects.ai_assistant |
projects AI helper page | Same |
projects.core |
project base routes | Same |
projects.members |
project member management | Same |
projects.tasks |
project task screens | Same |
projects.time_approval |
project time approvals | Same |
projects.time_tracking |
project time entries | Same |
These keys do appear in the central catalog
(config/features.catalog.php) but are missing from finance's local
features map. The finance app reads its local map first, so unless the
plan-feature snapshot explicitly carries the value, the gate behaviour
is undefined. Fix: add the keys (with sensible defaults) to
config/finance_features.php, or have the middleware fall back to the
central catalog.
The audit also notes:
- 116 keys in finance's
featuresmap are not in the central catalog (mostly tracker entitlements that should live as plan overrides, not feature flags). - 33 keys in the central catalog are not in finance's map (e.g.
api_integration.enabled,max_price_lists,receipt_ocr_scans, thetracker.activity_log_audit_trailfamily). Some of these are limit-type (numeric) entitlements and may not need a finance-side flag. - 130 of the 261 finance permission keys are not enforced by any
perm:middleware token at the route layer. They may be checked in policies or@candirectives, or they may be unreached.