Taxation Service
@nx/taxationownsTaxGroup/TaxGroupItemtax-rule templates and provisions them onto products asTaxSet+Taxrows, reacting to product changes via Debezium CDC. It also serves read-only Vietnamese administrative units, provinces, and wards. Pricing consumes the provisionedTaxSet; invoice is the downstream tax consumer.
1. Quick Reference
| Property | Value |
|---|---|
| Package | @nx/taxation |
| Code | SVC-00130-TAXATION |
| Type | Microservice |
| Runtime | Bun |
| Base Class | VerifierApplication |
| Location | packages/taxation |
| Base Path | /v1/api/taxation |
| Dev Port | 31130 |
| Container Port | 3000 (external 31130) |
| Snowflake ID | 13 |
| DB Schema | tax (TaxGroup, TaxGroupItem, Vn* refs) + pricing (TaxSet, Tax, TaxType) — all owned by @nx/core |
| Binding Namespace | @nx/taxation |
| Owner | taxation-team |
2. Purpose & Scope
| Included | Excluded |
|---|---|
TaxGroup/TaxGroupItem template CRUD | Tax-rate calculation at sale time (@nx/pricing) |
Provision/deprovision TaxSet + Tax onto products | Seller/buyer tax identity TaxInfo (commerce → invoice) |
| CDC reconcile on product create/update/delete | Variant-level tax overrides (created manually, sourceType unset) |
Merchant taxMethod ↔ group compatibility validation | VN reference-data seeding (loaded externally) |
| Read-only VN provinces / wards / administrative units | Invoice issuance (@nx/invoice) |
3. Tech Stack
External:
| Library | Purpose |
|---|---|
@venizia/ignis | IoC container, DI, BaseService, BaseRestController, ControllerFactory |
hono | HTTP server framework (via IGNIS) |
drizzle-orm | DB access via PostgresCoreDataSource |
@platformatic/kafka | Kafka consumer + key/value (de)serializers |
@venizia/ignis-helpers | KafkaConsumerHelper, env access, getError/HTTP, dayjs |
zod | Request schema validation (provisioning controller) |
Internal:
| Package | Purpose |
|---|---|
@nx/core | ALL Drizzle schemas, repositories, VerifierApplication, CDC topic constants, TProductPgRow/TDebeziumMessage |
Sole internal dependency is
@nx/core. This package declares no schemas of its own.
4. Project Structure
packages/taxation/
├── src/
│ ├── application.ts # Application class (VerifierApplication)
│ ├── index.ts # Entry → bootstrapApplication()
│ ├── migrate.ts # Migration entry → bootstrapMigration()
│ ├── common/ # BindingKeys, RestPaths
│ ├── components/kafka/ # CDC consumer on CDCKafkaTopics.PRODUCT
│ ├── controllers/ # 6 REST controllers + permission defs
│ ├── datasources/ # PostgresCoreDataSource binding
│ ├── migrations/processes/ # Seeds (discrimination types, groups, perms, role-perms)
│ ├── repositories/ # Repository subclasses over @nx/core schemas
│ ├── resources/ # app-info.json, banner
│ └── services/ # TaxGroup, TaxProvisioning, TaxationWorker
├── package.json
└── tsconfig.json5. Architecture
Detail: see Architecture.
6. Domain Snapshot
Full ERD + per-entity tables: see Domain Model.
7. Surface Summary
REST controllers (full reference rendered live from /v1/api/taxation/doc/openapi.json):
| Controller | Base path | Style | Endpoints |
|---|---|---|---|
TaxGroupController | /tax-groups | ControllerFactory CRUD | 8 |
TaxGroupItemController | /tax-group-items | ControllerFactory CRUD | 8 |
TaxProvisioningController | /tax-provisioning | Custom (provision/deprovision) | 2 |
VnProvinceController | /vn-provinces | Read-only | — |
VnWardController | /vn-wards | Read-only | — |
VnAdministrativeUnitController | /vn-administrative-units | Read-only | — |
Async topics (full reference in API Events):
| Direction | Count |
|---|---|
| Inbound (Kafka CDC) | 1 (public.Product) |
| Outbound (Kafka) | 0 |
| WebSocket out | 0 |
| BullMQ jobs in/out | 0 |
8. Components
| Component | File | Purpose |
|---|---|---|
ApplicationKafkaComponent | src/components/kafka/component.ts | Subscribes to CDCKafkaTopics.PRODUCT (Debezium), fallbackMode: latest, routes payload to TaxationWorkerService.handleProductCDC |
9. Services
| Service | File | One-liner |
|---|---|---|
TaxGroupService | src/services/tax-group.service.ts | Validates TaxGroup.taxMethod against merchant taxMethod; finds groups by method |
TaxProvisioningService | src/services/tax-provisioning.service.ts | Idempotent provision/deprovision of TaxSet + Tax from a TaxGroup template |
TaxationWorkerService | src/services/taxation-worker.service.ts | CDC consumer logic: c/u/r → reconcile, d → deprovision |
10. Repositories
Registered in
application.ts. All extend@nx/corerepositories over core-owned schemas.
| Repository | Table | Source | Custom Methods |
|---|---|---|---|
TaxGroupRepository | tax.TaxGroup | @nx/core | — |
TaxGroupItemRepository | tax.TaxGroupItem | @nx/core | — |
TaxTypeRepository | pricing.TaxType | @nx/core | — |
TaxSetRepository | pricing.TaxSet | @nx/core | findActiveTaxSetByPrincipal |
TaxRepository | pricing.Tax | @nx/core | — |
VnProvinceRepository | tax.VnProvince | @nx/core | — |
VnWardRepository | tax.VnWard | @nx/core | — |
VnAdministrativeUnitRepository | tax.VnAdministrativeUnit | @nx/core | — |
DiscriminationTypeRepository | DiscriminationType | @nx/core | — |
MigrationRepository, PermissionRepository, PolicyDefinitionRepository, RoleRepository | infra | @nx/core | — |
11. Entry Points
| File | Purpose |
|---|---|
src/index.ts | Service entry → bootstrapApplication() |
src/migrate.ts | Migration entry → bootstrapMigration() |
src/application.ts | Application class extending VerifierApplication |
12. Configuration
Env vars + feature flags + seeded data: see Configuration.
13. Operations
Deployment + observability + security + runbook: see Operations.
14. Related Pages
- Architecture
- Domain Model
- API Events
- Integration
- Configuration
- Operations
- Decisions
- REST endpoints — live OpenAPI at
/v1/api/taxation/doc/openapi.json - Pricing — consumes provisioned
TaxSet/Tax - Commerce — CDC source of product changes