Requirements
Documentation for Modules
Fiscal Library - Requirements Specification
Library:
@libs-core/fiscalLocation:libs/core/fiscal/Type: Core infrastructure library (not a business module) Permission Namespace:fiscal:*
1. Overview
Minimal tax configuration system that provides tax class definitions and tax rate resolution to any module in the platform. Products, services, invoicing, POS, and any entity or process that needs tax calculation can consume this library.
This is a minimal MVP — it provides the tax class registry and basic rate resolution. Advanced features (tax rules by region, tax exemptions, compound taxes) are deferred to future iterations.
1.1 Design Principles
- Domain-agnostic: Tax classes are not tied to products — any module can reference them.
- Multi-tenant: Tax configuration is per-tenant (different tenants may have different tax regimes).
- Configurable: Tax rates are configurable per tenant, not hardcoded.
- Minimal: Only what's needed now — tax class + rate resolution. No invoice generation, no tax reports.
- Buildable: ng-packagr library for module boundary compliance.
2. Functional Requirements
2.1 Tax Class Entity
A tax class represents a category of taxation (e.g., "Standard", "Reduced", "Exempt"):
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Unique identifier (UUID) |
tenantId |
string |
Yes | Multi-tenant isolation |
name |
string |
Yes | Display name (e.g., "Standard Rate", "Reduced Rate") |
code |
string |
Yes | Machine-readable code (e.g., 'standard', 'reduced', 'exempt', 'zero_rated') |
description |
string |
No | Explanation of when this class applies |
rate |
number |
Yes | Tax rate as percentage (e.g., 16 for 16%, 0 for exempt) |
isDefault |
boolean |
Yes | Whether this is the default tax class for new entities |
isActive |
boolean |
Yes | Whether this tax class is available (default: true) |
sortOrder |
number |
No | Display order |
createdAt |
Date |
Yes | Creation timestamp |
updatedAt |
Date |
Yes | Last update timestamp |
Tax Class Rules:
- Code uniqueness enforced per tenant
- Exactly one tax class must be marked as
isDefaultper tenant - Predefined seed data per tenant: Standard (16%), Reduced (8%), Exempt (0%), Zero-Rated (0%)
- Rates are configurable per tenant (e.g., one tenant may have 16% standard, another 21%)
- Deactivating a tax class does not affect entities referencing it
2.2 Tax Calculation
The library provides a simple calculation utility:
calculateTax(amount, taxClassId): Observable<TaxCalculationResult>- Returns:
{ amount, taxRate, taxAmount, totalWithTax, taxClassName }
- Returns:
resolveTaxRate(taxClassId): Observable<number>— Get rate for a tax classgetDefaultTaxClass(tenantId): Observable<TaxClass>— Get default tax class
3. Services
3.1 FiscalService
Injectable service for programmatic access:
getAll(tenantId): Observable<TaxClass[]>— All tax classes for tenantgetById(id): Observable<TaxClass>— Single tax classgetByCode(code, tenantId): Observable<TaxClass>— Lookup by codegetDefault(tenantId): Observable<TaxClass>— Default tax classcreate(taxClass): Observable<TaxClass>— Create tax classupdate(id, changes): Observable<TaxClass>— Update tax class (including rate)delete(id): Observable<void>— Delete tax class (fails if is default)calculateTax(amount, taxClassId): Observable<TaxCalculationResult>— Calculate tax
3.2 TaxCalculationResult
interface TaxCalculationResult {
subtotal: number; // Original amount
taxRate: number; // Applied rate (e.g., 16)
taxAmount: number; // Calculated tax (subtotal * rate / 100)
total: number; // subtotal + taxAmount
taxClassName: string; // Name of applied tax class
taxClassCode: string; // Code of applied tax class
}
4. Integration Points
4.1 Domain Events
| Event | Payload | Trigger |
|---|---|---|
fiscal.tax-class.created |
{ taxClass, tenantId } |
Tax class created |
fiscal.tax-class.updated |
{ taxClass, changes, tenantId } |
Tax class updated (including rate change) |
fiscal.tax-class.deleted |
{ taxClassId, tenantId } |
Tax class deleted |
fiscal.tax-rate.changed |
{ taxClassId, oldRate, newRate, tenantId } |
Tax rate changed (important for consumers) |
4.2 Embeddable Components
| Component ID | Description | Inputs |
|---|---|---|
fiscal:tax-class-selector |
Dropdown tax class picker | placeholder, showRate, includeInactive |
4.3 Public Actions
| Action ID | Description | Parameters | Permission |
|---|---|---|---|
fiscal:get-tax-classes |
List tax classes | { tenantId } |
fiscal:read |
fiscal:calculate-tax |
Calculate tax for amount | { amount, taxClassId } |
fiscal:read |
5. Permissions
| Permission | Description |
|---|---|
fiscal:read |
View tax classes and calculate taxes |
fiscal:manage |
Create/edit/delete tax classes and rates |
6. User Stories
- US-01: As an admin, I can view and configure tax classes and their rates for my tenant.
- US-02: As an admin, I can set a default tax class that applies to new entities automatically.
- US-03: As a module developer, I can embed a tax class selector in my module's forms.
- US-04: As a module developer, I can calculate tax amounts programmatically given an amount and tax class.
- US-05: As a module developer, I can listen to tax rate change events to update cached calculations.
7. Non-Functional Requirements
- NF-01: Buildable library (ng-packagr) for module boundary compliance.
- NF-02: All components standalone with OnPush change detection.
- NF-03: Multi-tenant isolation — each tenant has its own tax configuration.
- NF-04: Full mock API with seed data for development.
- NF-05: Minimum 90% test coverage.
- NF-06: Tax calculations must be deterministic and use proper decimal handling (avoid floating point issues).
8. Dependencies
@libs-core/fiscal
├── @libs-core/event-system (domain events)
├── @libs-core/security (permissions, tenant context)
├── @libs-core/log-system (logging)
├── @libs-core/utilities (number/currency utilities)
├── @libs-core/shared-models (BaseEntity, API types)
├── @libs-core/ui-framework (UI components for embeddables)
├── @libs-core/action-registry (public actions)
└── @libs-core/mock-api (development mock data)
9. Future Iterations (Out of Scope)
These features are explicitly deferred:
- Tax rules by geographic region
- Tax exemption certificates
- Compound/cascading taxes
- Tax reporting and summaries
- Tax-inclusive vs tax-exclusive pricing modes
- Tax holidays and temporal rules