@happyvertical/smrt-expenses
Expense records: a cost incurred against a job, work package, or project, with deduplicated receipts, an explicit review, reimbursement, and purchase-order drawdown.
What it gives you
Expense records: a cost incurred against a job, work package, or project, with deduplicated receipts, an explicit review, reimbursement, and purchase-order drawdown.
- 01Review is method-only: review, reject, markDuplicate, and reopen; a reviewed expense’s money, dates, cost object, vendor, and payer are frozen
- 02The same receipt file twice on one expense is refused; the same file on two expenses is reported for a person to look at
- 03Reviewed actuals reduce what remains open on a smrt-commerce purchase commitment, each exactly once
Money and currencies
Amounts are integer minor units with an ISO 4217 currency. Totals are per currency and never summed across currencies. An expense matched to a commitment must share its currency. Optional financial facts reconcile a subtotal and signed tax components to the amount and yield a cost basis. Recoverable tax is stated explicitly, and no tax law is inferred. A refund is a negative expense that names the expense it refunds.
Expenses in the commerce tax summary
The smrt-commerce tax summary reads reviewed expenses as recoverable tax. Each supplier tax component needs a tenant-approved mapping to one of its tax codes. An unmapped component shows as a warning, never as a zero. An expense drawn against a purchase order that already records its tax is flagged rather than counted twice.
What belongs elsewhere
Allowances are budget records, not expenses. Labour belongs to smrt-timesheets. Receipt OCR and accounting-provider posting are out of scope. Vendors and commitments come from smrt-commerce; a commitment is a PurchaseContract, which is a PurchaseOrder or a ProductionOrder; receipt files come from smrt-assets; profiles are referenced by id without a dependency.
Tenancy
Tenancy is optional by default, like smrt-commerce. A consumer makes it required with registerTenantScopedClass for Expense and ExpenseReceipt. A receipt takes its expense’s tenant, and tenants never move once stored.
Package UI
Components in this package
Import these public components directly. When the package also exports playground entries, the next tab renders its real components with package-owned example data.
Package previews
Not rendered here yet
The package ships a playground module for its entry and review components. This site does not install the package, so the previews are not rendered here.
Intentionally not registered
Generated interface
REST
The exact route set comes from each model's @smrt({ api }) policy
and the application manifest—not from a second controller definition.
Models and collections ship with a closed generated surface: no REST, MCP, WebMCP, or CLI operation reaches cost data. Applications expose expenses through their own permission-checked routes.
Generated interface
MCP
AI tools are generated from the methods you explicitly include. Their inputs are validated against the same model metadata used by REST and CLI.
Models and collections ship with a closed generated surface: no REST, MCP, WebMCP, or CLI operation reaches cost data. Applications expose expenses through their own permission-checked routes.
Browser-native agent interface
WebMCP
The generated web definitions carry the same tool names, descriptions, and JSON Schema
inputs as MCP. smrt-web registers them with document.modelContext.
Models and collections ship with a closed generated surface: no REST, MCP, WebMCP, or CLI operation reaches cost data. Applications expose expenses through their own permission-checked routes.
Generated interface
CLI
The app CLI turns manifest resources into predictable operator commands while keeping package-specific actions close to their models.
Models and collections ship with a closed generated surface: no REST, MCP, WebMCP, or CLI operation reaches cost data. Applications expose expenses through their own permission-checked routes.